From ea4d20dacfd599b4469735ece561e806c709883d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 6 Nov 2022 01:10:22 +0100 Subject: [PATCH] go.mod: github.com/cloudflare/cfssl v1.5.0 not using latest version, as that brings many indirect dependencies (through cobra) - removes github.com/gogo/protobuf dependency - unfortunately, brings back golang.org/x/crypto/ed25519 (will open a PR for that) Signed-off-by: Sebastiaan van Stijn --- go.mod | 9 +- go.sum | 52 +- trustpinning/certs_test.go | 2 +- .../github.com/cloudflare/cfssl/auth/auth.go | 2 +- .../cloudflare/cfssl/certdb/README.md | 12 +- .../cloudflare/cfssl/certdb/certdb.go | 44 + .../cloudflare/cfssl/config/config.go | 112 +- vendor/github.com/cloudflare/cfssl/csr/csr.go | 98 +- .../cloudflare/cfssl/errors/error.go | 13 +- .../helpers/derhelpers/derhelpers-legacy.go | 50 + .../cfssl/helpers/derhelpers/derhelpers.go | 24 +- .../cfssl/helpers/derhelpers/ed25519.go | 133 + .../cloudflare/cfssl/helpers/helpers.go | 109 +- .../cloudflare/cfssl/initca/initca.go | 8 +- .../cloudflare/cfssl/signer/local/local.go | 249 +- .../cloudflare/cfssl/signer/signer.go | 20 +- vendor/github.com/gogo/protobuf/AUTHORS | 15 - vendor/github.com/gogo/protobuf/CONTRIBUTORS | 23 - vendor/github.com/gogo/protobuf/LICENSE | 35 - .../github.com/gogo/protobuf/proto/Makefile | 43 - .../github.com/gogo/protobuf/proto/clone.go | 258 - .../gogo/protobuf/proto/custom_gogo.go | 39 - .../github.com/gogo/protobuf/proto/decode.go | 427 - .../gogo/protobuf/proto/deprecated.go | 63 - .../github.com/gogo/protobuf/proto/discard.go | 350 - .../gogo/protobuf/proto/duration.go | 100 - .../gogo/protobuf/proto/duration_gogo.go | 49 - .../github.com/gogo/protobuf/proto/encode.go | 205 - .../gogo/protobuf/proto/encode_gogo.go | 33 - .../github.com/gogo/protobuf/proto/equal.go | 300 - .../gogo/protobuf/proto/extensions.go | 605 -- .../gogo/protobuf/proto/extensions_gogo.go | 389 - vendor/github.com/gogo/protobuf/proto/lib.go | 973 -- .../gogo/protobuf/proto/lib_gogo.go | 50 - .../gogo/protobuf/proto/message_set.go | 181 - .../gogo/protobuf/proto/pointer_reflect.go | 357 - .../protobuf/proto/pointer_reflect_gogo.go | 59 - .../gogo/protobuf/proto/pointer_unsafe.go | 308 - .../protobuf/proto/pointer_unsafe_gogo.go | 56 - .../gogo/protobuf/proto/properties.go | 610 -- .../gogo/protobuf/proto/properties_gogo.go | 36 - .../gogo/protobuf/proto/skip_gogo.go | 119 - .../gogo/protobuf/proto/table_marshal.go | 3009 ------ .../gogo/protobuf/proto/table_marshal_gogo.go | 388 - .../gogo/protobuf/proto/table_merge.go | 676 -- .../gogo/protobuf/proto/table_unmarshal.go | 2249 ----- .../protobuf/proto/table_unmarshal_gogo.go | 385 - vendor/github.com/gogo/protobuf/proto/text.go | 930 -- .../gogo/protobuf/proto/text_gogo.go | 57 - .../gogo/protobuf/proto/text_parser.go | 1018 -- .../gogo/protobuf/proto/timestamp.go | 113 - .../gogo/protobuf/proto/timestamp_gogo.go | 49 - .../gogo/protobuf/proto/wrappers.go | 1888 ---- .../gogo/protobuf/proto/wrappers_gogo.go | 113 - .../certificate-transparency-go/.gitignore | 5 + .../certificate-transparency-go/.travis.yml | 47 +- .../certificate-transparency-go/CHANGELOG.md | 208 + .../client/configpb/multilog.pb.go | 88 +- .../client/getentries.go | 2 +- .../client/logclient.go | 60 +- .../client/multilog.go | 2 +- .../cloudbuild_tag.yaml | 10 + .../gometalinter.json | 5 +- .../jsonclient/client.go | 7 +- .../serialization.go | 156 +- .../certificate-transparency-go/signatures.go | 21 +- .../certificate-transparency-go/tls/types.go | 23 +- .../certificate-transparency-go/types.go | 68 + .../x509/cert_pool.go | 2 +- .../x509/curves.go | 37 + .../x509/ptr_sysptr_windows.go | 20 + .../x509/ptr_uint_windows.go | 17 + .../x509/revoked.go | 9 +- .../x509/root_windows.go | 2 +- .../certificate-transparency-go/x509/rpki.go | 242 + .../certificate-transparency-go/x509/sec1.go | 5 +- .../x509/verify.go | 119 +- .../certificate-transparency-go/x509/x509.go | 345 +- vendor/github.com/jmoiron/sqlx/LICENSE | 23 + .../github.com/jmoiron/sqlx/types/README.md | 5 + vendor/github.com/jmoiron/sqlx/types/types.go | 172 + .../weppos/publicsuffix-go/LICENSE.txt | 21 + .../publicsuffix/publicsuffix.go | 544 + .../publicsuffix-go/publicsuffix/rules.go | 8847 +++++++++++++++++ vendor/github.com/zmap/zcrypto/LICENSE | 257 + vendor/github.com/zmap/zcrypto/json/dhe.go | 130 + vendor/github.com/zmap/zcrypto/json/ecdhe.go | 107 + vendor/github.com/zmap/zcrypto/json/names.go | 113 + vendor/github.com/zmap/zcrypto/json/rsa.go | 67 + vendor/github.com/zmap/zcrypto/util/isURL.go | 77 + vendor/github.com/zmap/zcrypto/x509/README.md | 8 + .../github.com/zmap/zcrypto/x509/cert_pool.go | 171 + .../zmap/zcrypto/x509/certificate_type.go | 64 + vendor/github.com/zmap/zcrypto/x509/chain.go | 70 + .../zmap/zcrypto/x509/ct/serialization.go | 168 + .../github.com/zmap/zcrypto/x509/ct/types.go | 229 + .../github.com/zmap/zcrypto/x509/example.json | 65 + .../zmap/zcrypto/x509/extended_key_usage.go | 679 ++ .../zcrypto/x509/extended_key_usage_schema.sh | 21 + .../zmap/zcrypto/x509/extensions.go | 800 ++ .../zmap/zcrypto/x509/fingerprint.go | 61 + .../generated_certvalidationlevel_string.go | 16 + vendor/github.com/zmap/zcrypto/x509/json.go | 651 ++ vendor/github.com/zmap/zcrypto/x509/names.go | 30 + .../zmap/zcrypto/x509/pem_decrypt.go | 240 + vendor/github.com/zmap/zcrypto/x509/pkcs1.go | 121 + vendor/github.com/zmap/zcrypto/x509/pkcs8.go | 54 + .../github.com/zmap/zcrypto/x509/pkix/json.go | 279 + .../github.com/zmap/zcrypto/x509/pkix/oid.go | 74 + .../zmap/zcrypto/x509/pkix/oid_names.go | 1014 ++ .../github.com/zmap/zcrypto/x509/pkix/pkix.go | 299 + .../zmap/zcrypto/x509/qc_statements.go | 173 + vendor/github.com/zmap/zcrypto/x509/sec1.go | 105 + .../zcrypto/x509/tor_service_descriptor.go | 158 + .../zmap/zcrypto/x509/validation.go | 60 + vendor/github.com/zmap/zcrypto/x509/verify.go | 635 ++ vendor/github.com/zmap/zcrypto/x509/x509.go | 2957 ++++++ .../github.com/zmap/zlint/v2/.goreleaser.yml | 30 + vendor/github.com/zmap/zlint/v2/LICENSE | 202 + vendor/github.com/zmap/zlint/v2/lint/base.go | 96 + .../zmap/zlint/v2/lint/registration.go | 351 + .../github.com/zmap/zlint/v2/lint/result.go | 106 + .../github.com/zmap/zlint/v2/lint/source.go | 132 + .../lint_ct_sct_policy_count_unsatisfied.go | 157 + ...er_cert_valid_time_longer_than_398_days.go | 79 + .../cabf_br/lint_ca_common_name_missing.go | 50 + .../cabf_br/lint_ca_country_name_invalid.go | 63 + .../cabf_br/lint_ca_country_name_missing.go | 58 + .../lints/cabf_br/lint_ca_crl_sign_not_set.go | 57 + .../lint_ca_digital_signature_not_set.go | 60 + .../zlint/v2/lints/cabf_br/lint_ca_is_ca.go | 63 + .../cabf_br/lint_ca_key_cert_sign_not_set.go | 56 + .../cabf_br/lint_ca_key_usage_missing.go | 58 + .../cabf_br/lint_ca_key_usage_not_critical.go | 56 + .../lint_ca_organization_name_missing.go | 55 + .../lint_cab_dv_conflicts_with_locality.go | 52 + .../cabf_br/lint_cab_dv_conflicts_with_org.go | 55 + .../lint_cab_dv_conflicts_with_postal.go | 55 + .../lint_cab_dv_conflicts_with_province.go | 55 + .../lint_cab_dv_conflicts_with_street.go | 55 + .../lint_cab_iv_requires_personal_name.go | 54 + .../lints/cabf_br/lint_cab_ov_requires_org.go | 54 + .../lint_cert_policy_iv_requires_country.go | 54 + ...policy_iv_requires_province_or_locality.go | 55 + .../lint_cert_policy_ov_requires_country.go | 54 + ...policy_ov_requires_province_or_locality.go | 55 + .../lints/cabf_br/lint_dh_params_missing.go | 56 + .../lint_dnsname_bad_character_in_label.go | 64 + .../lint_dnsname_check_left_label_wildcard.go | 67 + .../lint_dnsname_contains_bare_iana_suffix.go | 56 + .../lint_dnsname_contains_empty_label.go | 68 + .../cabf_br/lint_dnsname_hyphen_in_sld.go | 67 + .../cabf_br/lint_dnsname_label_too_long.go | 70 + .../lint_dnsname_right_label_valid_tld.go | 56 + .../cabf_br/lint_dnsname_underscore_in_sld.go | 67 + .../cabf_br/lint_dnsname_underscore_in_trd.go | 68 + ..._dnsname_wildcard_left_of_public_suffix.go | 67 + ...int_dnsname_wildcard_only_in_left_label.go | 69 + .../lint_dsa_correct_order_in_subgroup.go | 66 + ...nt_dsa_improper_modulus_or_divisor_size.go | 57 + .../lint_dsa_shorter_than_2048_bits.go | 59 + .../lint_dsa_unique_correct_representation.go | 60 + .../lints/cabf_br/lint_ec_improper_curves.go | 71 + .../lint_ext_nc_intersects_reserved_ip.go | 63 + .../lint_ext_san_contains_reserved_ip.go | 61 + .../lint_ext_san_critical_with_subject_dn.go | 61 + .../lint_ext_san_directory_name_present.go | 60 + .../lint_ext_san_edi_party_name_present.go | 60 + .../v2/lints/cabf_br/lint_ext_san_missing.go | 57 + .../lint_ext_san_other_name_present.go | 60 + .../lint_ext_san_registered_id_present.go | 60 + .../lint_ext_san_rfc822_name_present.go | 60 + ...san_uniform_resource_identifier_present.go | 60 + ...ext_tor_service_descriptor_hash_invalid.go | 220 + .../lint_extra_subject_common_names.go | 52 + .../lint_invalid_certificate_version.go | 53 + ...old_root_ca_rsa_mod_less_than_2048_bits.go | 55 + ..._old_sub_ca_rsa_mod_less_than_1024_bits.go | 59 + ...ld_sub_cert_rsa_mod_less_than_1024_bits.go | 56 + .../lint_public_key_type_not_allowed.go | 51 + ...aints_path_len_constraint_field_present.go | 71 + .../lint_root_ca_contains_cert_policy.go | 55 + ...lint_root_ca_extended_key_usage_present.go | 55 + ...lint_root_ca_key_usage_must_be_critical.go | 51 + .../cabf_br/lint_root_ca_key_usage_present.go | 50 + ...t_rsa_mod_factors_smaller_than_752_bits.go | 59 + .../lint_rsa_mod_less_than_2048_bits.go | 54 + .../v2/lints/cabf_br/lint_rsa_mod_not_odd.go | 61 + .../lint_rsa_public_exponent_not_in_range.go | 65 + .../lint_rsa_public_exponent_not_odd.go | 59 + .../lint_rsa_public_exponent_too_small.go | 59 + .../lint_san_dns_name_onion_invalid.go | 151 + .../lint_san_dns_name_onion_not_ev_cert.go | 69 + .../lint_signature_algorithm_not_supported.go | 87 + ..._ca_aia_does_not_contain_issuing_ca_url.go | 61 + .../lint_sub_ca_aia_marked_critical.go | 51 + .../lints/cabf_br/lint_sub_ca_aia_missing.go | 58 + ...ca_certificate_policies_marked_critical.go | 56 + ...int_sub_ca_certificate_policies_missing.go | 55 + ...istribution_points_does_not_contain_url.go | 59 + ...crl_distribution_points_marked_critical.go | 56 + ..._sub_ca_crl_distribution_points_missing.go | 56 + .../lints/cabf_br/lint_sub_ca_eku_critical.go | 58 + .../lints/cabf_br/lint_sub_ca_eku_missing.go | 50 + .../cabf_br/lint_sub_ca_eku_valid_fields.go | 57 + ...nt_sub_ca_name_constraints_not_critical.go | 61 + ...ert_aia_does_not_contain_issuing_ca_url.go | 60 + ..._sub_cert_aia_does_not_contain_ocsp_url.go | 62 + .../lint_sub_cert_aia_marked_critical.go | 51 + .../cabf_br/lint_sub_cert_aia_missing.go | 59 + .../lint_sub_cert_cert_policy_empty.go | 58 + ...rt_certificate_policies_marked_critical.go | 57 + ...t_sub_cert_certificate_policies_missing.go | 56 + .../lint_sub_cert_country_name_must_appear.go | 51 + ...istribution_points_does_not_contain_url.go | 60 + ...crl_distribution_points_marked_critical.go | 58 + .../cabf_br/lint_sub_cert_eku_extra_values.go | 64 + .../cabf_br/lint_sub_cert_eku_missing.go | 56 + ...ert_eku_server_auth_client_auth_missing.go | 59 + .../lint_sub_cert_gn_sn_contains_policy.go | 52 + .../v2/lints/cabf_br/lint_sub_cert_is_ca.go | 57 + ...nt_sub_cert_key_usage_cert_sign_bit_set.go | 56 + ...int_sub_cert_key_usage_crl_sign_bit_set.go | 56 + ...lint_sub_cert_locality_name_must_appear.go | 53 + ..._sub_cert_locality_name_must_not_appear.go | 51 + .../lint_sub_cert_or_sub_ca_using_sha1.go | 54 + .../lint_sub_cert_postal_code_prohibited.go | 52 + .../lint_sub_cert_province_must_appear.go | 53 + .../lint_sub_cert_province_must_not_appear.go | 51 + .../lint_sub_cert_sha1_expiration_too_long.go | 61 + ...ub_cert_street_address_should_not_exist.go | 52 + ...b_cert_valid_time_longer_than_39_months.go | 49 + ...ub_cert_valid_time_longer_than_825_days.go | 49 + .../lint_subject_common_name_included.go | 55 + .../lint_subject_common_name_not_from_san.go | 69 + ...lint_subject_contains_malformed_arpa_ip.go | 150 + ...subject_contains_noninformational_value.go | 80 + .../lint_subject_contains_reserved_arpa_ip.go | 233 + .../lint_subject_contains_reserved_ip.go | 60 + .../cabf_br/lint_subject_country_not_iso.go | 61 + .../lint_ev_business_category_missing.go | 50 + .../cabf_ev/lint_ev_country_name_missing.go | 50 + .../lint_ev_organization_name_missing.go | 50 + .../cabf_ev/lint_ev_serial_number_missing.go | 49 + .../cabf_ev/lint_ev_valid_time_too_long.go | 54 + ...t_onion_subject_validity_time_too_large.go | 69 + .../lints/community/lint_ian_bare_wildcard.go | 53 + .../lint_ian_dns_name_includes_null_char.go | 53 + .../lint_ian_dns_name_starts_with_period.go | 53 + .../lint_ian_iana_pub_suffix_empty.go | 53 + .../community/lint_ian_wildcard_not_first.go | 53 + .../lints/community/lint_is_redacted_cert.go | 63 + .../lint_issuer_dn_leading_whitespace.go | 53 + .../lint_issuer_dn_trailing_whitespace.go | 53 + .../community/lint_issuer_multiple_rdn.go | 59 + .../lints/community/lint_rsa_exp_negative.go | 53 + .../lints/community/lint_rsa_no_public_key.go | 53 + .../lints/community/lint_san_bare_wildcard.go | 53 + .../community/lint_san_dns_name_duplicate.go | 58 + .../lint_san_dns_name_includes_null_char.go | 53 + .../lint_san_dns_name_starts_with_period.go | 53 + .../lint_san_iana_pub_suffix_empty.go | 58 + .../community/lint_san_wildcard_not_first.go | 53 + .../lint_subject_dn_leading_whitespace.go | 53 + .../lint_subject_dn_trailing_whitespace.go | 53 + .../community/lint_subject_multiple_rdn.go | 58 + .../lint_validity_time_not_positive.go | 49 + ...lint_qcstatem_etsi_present_qcs_critical.go | 62 + .../etsi/lint_qcstatem_etsi_type_as_statem.go | 69 + .../lint_qcstatem_mandatory_etsi_statems.go | 72 + .../etsi/lint_qcstatem_qccompliance_valid.go | 67 + .../etsi/lint_qcstatem_qclimitvalue_valid.go | 100 + .../etsi/lint_qcstatem_qcpds_lang_case.go | 91 + .../lints/etsi/lint_qcstatem_qcpds_valid.go | 101 + .../lint_qcstatem_qcretentionperiod_valid.go | 74 + .../lints/etsi/lint_qcstatem_qcsscd_valid.go | 68 + .../lints/etsi/lint_qcstatem_qctype_valid.go | 84 + .../v2/lints/etsi/lint_qcstatem_qctype_web.go | 90 + .../v2/lints/mozilla/lint_mp_allowed_eku.go | 76 + ...int_mp_authority_key_identifier_correct.go | 78 + .../lint_mp_ecdsa_pub_key_encoding_correct.go | 88 + ...int_mp_ecdsa_signature_encoding_correct.go | 121 + .../mozilla/lint_mp_exponent_cannot_be_one.go | 66 + ...nt_mp_modulus_must_be_2048_bits_or_more.go | 65 + .../lint_mp_modulus_must_be_divisible_by_8.go | 65 + ...lint_mp_pss_parameters_encoding_correct.go | 101 + .../mozilla/lint_mp_rsassa-pss_in_spki.go | 66 + .../lint_basic_constraints_not_critical.go | 66 + .../lints/rfc/lint_ca_subject_field_empty.go | 62 + .../lint_cert_contains_unique_identifier.go | 62 + .../rfc/lint_cert_extensions_version_not_3.go | 68 + ...rt_unique_identifier_version_not_2_or_3.go | 64 + .../rfc/lint_distribution_point_incomplete.go | 85 + ..._distribution_point_missing_ldap_or_uri.go | 58 + .../v2/lints/rfc/lint_ecdsa_ee_invalid_ku.go | 99 + .../lints/rfc/lint_eku_critical_improperly.go | 67 + .../lint_ext_aia_access_location_missing.go | 64 + .../lints/rfc/lint_ext_aia_marked_critical.go | 56 + ...t_ext_authority_key_identifier_critical.go | 56 + ...nt_ext_authority_key_identifier_missing.go | 65 + ...hority_key_identifier_no_key_identifier.go | 65 + ...lint_ext_cert_policy_contains_noticeref.go | 67 + ..._policy_disallowed_any_policy_qualifier.go | 64 + .../rfc/lint_ext_cert_policy_duplicate.go | 63 + ...xt_cert_policy_explicit_text_ia5_string.go | 72 + ...t_policy_explicit_text_includes_control.go | 90 + ...t_ext_cert_policy_explicit_text_not_nfc.go | 66 + ..._ext_cert_policy_explicit_text_not_utf8.go | 73 + ..._ext_cert_policy_explicit_text_too_long.go | 82 + ...nt_ext_crl_distribution_marked_critical.go | 57 + .../lints/rfc/lint_ext_duplicate_extension.go | 59 + .../lint_ext_freshest_crl_marked_critical.go | 57 + .../v2/lints/rfc/lint_ext_ian_critical.go | 56 + .../rfc/lint_ext_ian_dns_not_ia5_string.go | 74 + .../v2/lints/rfc/lint_ext_ian_empty_name.go | 81 + .../v2/lints/rfc/lint_ext_ian_no_entries.go | 63 + .../rfc/lint_ext_ian_rfc822_format_invalid.go | 70 + .../lints/rfc/lint_ext_ian_space_dns_name.go | 67 + .../rfc/lint_ext_ian_uri_format_invalid.go | 70 + .../lint_ext_ian_uri_host_not_fqdn_or_ip.go | 72 + .../v2/lints/rfc/lint_ext_ian_uri_not_ia5.go | 60 + .../v2/lints/rfc/lint_ext_ian_uri_relative.go | 71 + ...lint_ext_key_usage_cert_sign_without_ca.go | 65 + .../rfc/lint_ext_key_usage_not_critical.go | 56 + .../rfc/lint_ext_key_usage_without_bits.go | 59 + .../lint_ext_name_constraints_not_critical.go | 63 + .../lint_ext_name_constraints_not_in_ca.go | 61 + .../rfc/lint_ext_policy_constraints_empty.go | 76 + ...int_ext_policy_constraints_not_critical.go | 56 + .../rfc/lint_ext_policy_map_any_policy.go | 65 + .../rfc/lint_ext_policy_map_not_critical.go | 57 + .../lint_ext_policy_map_not_in_cert_policy.go | 64 + .../rfc/lint_ext_san_dns_name_too_long.go | 51 + .../rfc/lint_ext_san_dns_not_ia5_string.go | 73 + .../v2/lints/rfc/lint_ext_san_empty_name.go | 81 + .../v2/lints/rfc/lint_ext_san_no_entries.go | 63 + ...nt_ext_san_not_critical_without_subject.go | 63 + .../rfc/lint_ext_san_rfc822_format_invalid.go | 70 + .../lints/rfc/lint_ext_san_space_dns_name.go | 67 + .../rfc/lint_ext_san_uri_format_invalid.go | 70 + .../lint_ext_san_uri_host_not_fqdn_or_ip.go | 78 + .../v2/lints/rfc/lint_ext_san_uri_not_ia5.go | 60 + .../v2/lints/rfc/lint_ext_san_uri_relative.go | 71 + ...int_ext_subject_directory_attr_critical.go | 58 + ...int_ext_subject_key_identifier_critical.go | 56 + ...t_ext_subject_key_identifier_missing_ca.go | 70 + ...subject_key_identifier_missing_sub_cert.go | 70 + ...neralized_time_does_not_include_seconds.go | 97 + ...eralized_time_includes_fraction_seconds.go | 97 + .../rfc/lint_generalized_time_not_in_zulu.go | 78 + .../rfc/lint_idn_dnsname_malformed_unicode.go | 60 + .../lints/rfc/lint_idn_dnsname_must_be_nfc.go | 64 + .../lint_inhibit_any_policy_not_critical.go | 64 + ..._issuer_dn_country_not_printable_string.go | 65 + .../v2/lints/rfc/lint_issuer_field_empty.go | 58 + .../lints/rfc/lint_name_constraint_empty.go | 79 + ...lint_name_constraint_maximum_not_absent.go | 128 + .../lint_name_constraint_minimum_non_zero.go | 128 + .../lint_name_constraint_on_edi_party_name.go | 62 + .../lint_name_constraint_on_registered_id.go | 62 + .../lints/rfc/lint_name_constraint_on_x400.go | 62 + ...path_len_constraint_improperly_included.go | 73 + .../lint_path_len_constraint_zero_or_less.go | 79 + ...int_serial_number_longer_than_20_octets.go | 67 + .../rfc/lint_serial_number_not_positive.go | 67 + ..._spki_rsa_encryption_parameter_not_null.go | 66 + .../lint_subject_common_name_max_length.go | 59 + ...subject_dn_country_not_printable_string.go | 65 + ...int_subject_dn_not_printable_characters.go | 74 + ...int_subject_dn_serial_number_max_length.go | 51 + ...t_dn_serial_number_not_printable_string.go | 65 + .../rfc/lint_subject_email_max_length.go | 68 + .../rfc/lint_subject_empty_without_san.go | 67 + .../rfc/lint_subject_given_name_max_length.go | 62 + ...int_subject_info_access_marked_critical.go | 54 + .../lint_subject_locality_name_max_length.go | 61 + .../zlint/v2/lints/rfc/lint_subject_not_dn.go | 61 + ...nt_subject_organization_name_max_length.go | 61 + ...ect_organizational_unit_name_max_length.go | 61 + .../lint_subject_postal_code_max_length.go | 62 + .../lint_subject_printable_string_badalpha.go | 109 + .../rfc/lint_subject_state_name_max_length.go | 61 + .../lint_subject_street_address_max_length.go | 60 + .../rfc/lint_subject_surname_max_length.go | 62 + ...ignature_alg_matches_cert_signature_alg.go | 88 + ...ature_rsa_encryption_parameter_not_null.go | 82 + .../lint_utc_time_does_not_include_seconds.go | 83 + .../v2/lints/rfc/lint_utc_time_not_in_zulu.go | 98 + .../rfc/lint_wrong_time_format_pre2050.go | 86 + vendor/github.com/zmap/zlint/v2/makefile | 42 + vendor/github.com/zmap/zlint/v2/newLint.sh | 50 + vendor/github.com/zmap/zlint/v2/resultset.go | 58 + vendor/github.com/zmap/zlint/v2/template | 45 + .../zlint/v2/util/algorithm_identifier.go | 190 + vendor/github.com/zmap/zlint/v2/util/ca.go | 57 + .../zmap/zlint/v2/util/countries.go | 51 + vendor/github.com/zmap/zlint/v2/util/eku.go | 14 + .../zmap/zlint/v2/util/encodings.go | 136 + vendor/github.com/zmap/zlint/v2/util/ev.go | 73 + vendor/github.com/zmap/zlint/v2/util/fqdn.go | 124 + vendor/github.com/zmap/zlint/v2/util/gtld.go | 120 + .../github.com/zmap/zlint/v2/util/gtld_map.go | 7875 +++++++++++++++ vendor/github.com/zmap/zlint/v2/util/ip.go | 127 + vendor/github.com/zmap/zlint/v2/util/ku.go | 18 + vendor/github.com/zmap/zlint/v2/util/names.go | 64 + vendor/github.com/zmap/zlint/v2/util/oid.go | 183 + .../github.com/zmap/zlint/v2/util/primes.go | 57 + .../github.com/zmap/zlint/v2/util/qc_stmt.go | 253 + vendor/github.com/zmap/zlint/v2/util/rdn.go | 26 + vendor/github.com/zmap/zlint/v2/util/time.go | 112 + vendor/github.com/zmap/zlint/v2/zlint.go | 62 + vendor/golang.org/x/crypto/ed25519/ed25519.go | 71 + vendor/modules.txt | 35 +- 413 files changed, 49973 insertions(+), 16938 deletions(-) create mode 100644 vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers-legacy.go create mode 100644 vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go delete mode 100644 vendor/github.com/gogo/protobuf/AUTHORS delete mode 100644 vendor/github.com/gogo/protobuf/CONTRIBUTORS delete mode 100644 vendor/github.com/gogo/protobuf/LICENSE delete mode 100644 vendor/github.com/gogo/protobuf/proto/Makefile delete mode 100644 vendor/github.com/gogo/protobuf/proto/clone.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/custom_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/decode.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/deprecated.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/discard.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/duration.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/duration_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/encode.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/encode_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/equal.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/extensions.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/extensions_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/lib.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/lib_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/message_set.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_reflect.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/properties.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/properties_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/skip_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/table_marshal.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/table_merge.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/table_unmarshal.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/text_parser.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/wrappers.go delete mode 100644 vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go create mode 100644 vendor/github.com/google/certificate-transparency-go/CHANGELOG.md create mode 100644 vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/curves.go create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go create mode 100644 vendor/github.com/google/certificate-transparency-go/x509/rpki.go create mode 100644 vendor/github.com/jmoiron/sqlx/LICENSE create mode 100644 vendor/github.com/jmoiron/sqlx/types/README.md create mode 100644 vendor/github.com/jmoiron/sqlx/types/types.go create mode 100644 vendor/github.com/weppos/publicsuffix-go/LICENSE.txt create mode 100644 vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go create mode 100644 vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go create mode 100644 vendor/github.com/zmap/zcrypto/LICENSE create mode 100644 vendor/github.com/zmap/zcrypto/json/dhe.go create mode 100644 vendor/github.com/zmap/zcrypto/json/ecdhe.go create mode 100644 vendor/github.com/zmap/zcrypto/json/names.go create mode 100644 vendor/github.com/zmap/zcrypto/json/rsa.go create mode 100644 vendor/github.com/zmap/zcrypto/util/isURL.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/README.md create mode 100644 vendor/github.com/zmap/zcrypto/x509/cert_pool.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/certificate_type.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/chain.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/ct/serialization.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/ct/types.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/example.json create mode 100644 vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh create mode 100644 vendor/github.com/zmap/zcrypto/x509/extensions.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/fingerprint.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/json.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/names.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkcs1.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkcs8.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkix/json.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkix/oid.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/qc_statements.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/sec1.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/validation.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/verify.go create mode 100644 vendor/github.com/zmap/zcrypto/x509/x509.go create mode 100644 vendor/github.com/zmap/zlint/v2/.goreleaser.yml create mode 100644 vendor/github.com/zmap/zlint/v2/LICENSE create mode 100644 vendor/github.com/zmap/zlint/v2/lint/base.go create mode 100644 vendor/github.com/zmap/zlint/v2/lint/registration.go create mode 100644 vendor/github.com/zmap/zlint/v2/lint/result.go create mode 100644 vendor/github.com/zmap/zlint/v2/lint/source.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/apple/lint_ct_sct_policy_count_unsatisfied.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_common_name_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_crl_sign_not_set.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_digital_signature_not_set.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_is_ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_cert_sign_not_set.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_organization_name_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_locality.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_org.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_postal.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_province.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_street.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_iv_requires_personal_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_ov_requires_org.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_country.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_province_or_locality.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_country.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_province_or_locality.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dh_params_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_bad_character_in_label.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_check_left_label_wildcard.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_bare_iana_suffix.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_empty_label.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_hyphen_in_sld.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_label_too_long.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_right_label_valid_tld.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_sld.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_trd.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_left_of_public_suffix.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_only_in_left_label.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_improper_modulus_or_divisor_size.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_unique_correct_representation.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ec_improper_curves.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_contains_reserved_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_critical_with_subject_dn.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_directory_name_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_edi_party_name_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_other_name_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_registered_id_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_rfc822_name_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_uniform_resource_identifier_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_tor_service_descriptor_hash_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_extra_subject_common_names.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_invalid_certificate_version.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_root_ca_rsa_mod_less_than_2048_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_ca_rsa_mod_less_than_1024_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_cert_rsa_mod_less_than_1024_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_public_key_type_not_allowed.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_basic_constraints_path_len_constraint_field_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_contains_cert_policy.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_extended_key_usage_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_must_be_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_present.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_factors_smaller_than_752_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_less_than_2048_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_not_odd.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_in_range.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_odd.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_too_small.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_not_ev_cert.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_signature_algorithm_not_supported.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_does_not_contain_issuing_ca_url.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_does_not_contain_url.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_valid_fields.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_name_constraints_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_cert_policy_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_country_name_must_appear.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_does_not_contain_url.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_extra_values.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_gn_sn_contains_policy.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_is_ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_cert_sign_bit_set.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_crl_sign_bit_set.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_appear.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_not_appear.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_or_sub_ca_using_sha1.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_postal_code_prohibited.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_appear.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_not_appear.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_sha1_expiration_too_long.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_street_address_should_not_exist.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_39_months.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_825_days.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_included.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_not_from_san.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_malformed_arpa_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_noninformational_value.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_arpa_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_country_not_iso.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_business_category_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_country_name_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_organization_name_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_serial_number_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_valid_time_too_long.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_onion_subject_validity_time_too_large.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_bare_wildcard.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_includes_null_char.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_starts_with_period.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_iana_pub_suffix_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_wildcard_not_first.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_is_redacted_cert.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_leading_whitespace.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_trailing_whitespace.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_multiple_rdn.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_exp_negative.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_no_public_key.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_bare_wildcard.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_duplicate.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_includes_null_char.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_starts_with_period.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_iana_pub_suffix_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_san_wildcard_not_first.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_leading_whitespace.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_trailing_whitespace.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_multiple_rdn.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/community/lint_validity_time_not_positive.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_present_qcs_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_type_as_statem.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_mandatory_etsi_statems.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qccompliance_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qclimitvalue_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_lang_case.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcretentionperiod_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcsscd_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_valid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_web.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_allowed_eku.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_authority_key_identifier_correct.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_pub_key_encoding_correct.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_signature_encoding_correct.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_exponent_cannot_be_one.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_2048_bits_or_more.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_divisible_by_8.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_pss_parameters_encoding_correct.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_rsassa-pss_in_spki.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_basic_constraints_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ca_subject_field_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_contains_unique_identifier.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_extensions_version_not_3.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_unique_identifier_version_not_2_or_3.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_incomplete.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_missing_ldap_or_uri.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ecdsa_ee_invalid_ku.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_eku_critical_improperly.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_access_location_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_missing.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_no_key_identifier.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_contains_noticeref.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_disallowed_any_policy_qualifier.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_duplicate.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_ia5_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_includes_control.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_nfc.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_utf8.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_too_long.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_crl_distribution_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_duplicate_extension.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_freshest_crl_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_dns_not_ia5_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_empty_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_no_entries.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_rfc822_format_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_space_dns_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_format_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_host_not_fqdn_or_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_not_ia5.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_relative.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_cert_sign_without_ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_without_bits.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_in_ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_any_policy.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_in_cert_policy.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_name_too_long.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_not_ia5_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_empty_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_no_entries.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_not_critical_without_subject.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_rfc822_format_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_space_dns_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_format_invalid.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_host_not_fqdn_or_ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_not_ia5.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_relative.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_directory_attr_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_sub_cert.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_does_not_include_seconds.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_includes_fraction_seconds.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_not_in_zulu.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_malformed_unicode.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_must_be_nfc.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_inhibit_any_policy_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_dn_country_not_printable_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_field_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_empty.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_maximum_not_absent.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_minimum_non_zero.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_edi_party_name.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_registered_id.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_x400.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_improperly_included.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_zero_or_less.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_longer_than_20_octets.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_not_positive.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_spki_rsa_encryption_parameter_not_null.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_common_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_country_not_printable_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_not_printable_characters.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_not_printable_string.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_email_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_empty_without_san.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_given_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_info_access_marked_critical.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_locality_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_not_dn.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organization_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organizational_unit_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_postal_code_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_printable_string_badalpha.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_state_name_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_street_address_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_surname_max_length.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_alg_matches_cert_signature_alg.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_rsa_encryption_parameter_not_null.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_does_not_include_seconds.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_not_in_zulu.go create mode 100644 vendor/github.com/zmap/zlint/v2/lints/rfc/lint_wrong_time_format_pre2050.go create mode 100644 vendor/github.com/zmap/zlint/v2/makefile create mode 100644 vendor/github.com/zmap/zlint/v2/newLint.sh create mode 100644 vendor/github.com/zmap/zlint/v2/resultset.go create mode 100644 vendor/github.com/zmap/zlint/v2/template create mode 100644 vendor/github.com/zmap/zlint/v2/util/algorithm_identifier.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/ca.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/countries.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/eku.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/encodings.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/ev.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/fqdn.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/gtld.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/gtld_map.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/ip.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/ku.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/names.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/oid.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/primes.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/qc_stmt.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/rdn.go create mode 100644 vendor/github.com/zmap/zlint/v2/util/time.go create mode 100644 vendor/github.com/zmap/zlint/v2/zlint.go create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go diff --git a/go.mod b/go.mod index 864476f781..b4b9166344 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.17 require ( github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d github.com/bugsnag/bugsnag-go v1.0.5 - github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 // 1.3.1 + github.com/cloudflare/cfssl v1.5.0 github.com/docker/distribution v2.8.1+incompatible github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c github.com/docker/go-connections v0.4.0 @@ -42,13 +42,13 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 // indirect + github.com/google/certificate-transparency-go v1.0.21 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.4 // indirect + github.com/jmoiron/sqlx v1.2.0 // indirect github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -68,6 +68,9 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.1 // indirect + github.com/weppos/publicsuffix-go v0.13.0 // indirect + github.com/zmap/zcrypto v0.0.0-20200911161511-43ff0ea04f21 // indirect + github.com/zmap/zlint/v2 v2.2.1 // indirect golang.org/x/text v0.4.0 // indirect google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect gopkg.in/cenkalti/backoff.v2 v2.2.1 // indirect diff --git a/go.sum b/go.sum index 0636750b3c..b6fe5f367d 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -57,10 +58,13 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= +github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -91,6 +95,7 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -102,8 +107,11 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= +github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY= +github.com/cloudflare/cfssl v1.5.0 h1:vFJDAvQgFSRbCn9zg8KpSrrEZrBAQ4KO5oNK7SXEyb0= +github.com/cloudflare/cfssl v1.5.0/go.mod h1:sPPkBS5L8l8sRc/IOO1jG51Xb34u+TYhL6P//JdODMQ= +github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4= +github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -117,6 +125,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -156,6 +165,7 @@ github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUork github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -166,12 +176,12 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -210,8 +220,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE= +github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -297,6 +307,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -304,6 +315,9 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo= +github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -319,6 +333,8 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= +github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -331,7 +347,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -347,6 +366,8 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA= github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -368,14 +389,17 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= @@ -436,6 +460,7 @@ github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5A github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= @@ -473,12 +498,25 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= +github.com/weppos/publicsuffix-go v0.13.0 h1:0Tu1uzLBd1jPn4k6OnMmOPZH/l/9bj9kUOMMkoRs6Gg= +github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= +github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= +github.com/zmap/zcrypto v0.0.0-20200513165325-16679db567ff/go.mod h1:TxpejqcVKQjQaVVmMGfzx5HnmFMdIU+vLtaCyPBfGI4= +github.com/zmap/zcrypto v0.0.0-20200911161511-43ff0ea04f21 h1:PIpcdSOg3pMdFJUBg5yR9xxcj5rm/SGAyaWT/wK6Kco= +github.com/zmap/zcrypto v0.0.0-20200911161511-43ff0ea04f21/go.mod h1:TxpejqcVKQjQaVVmMGfzx5HnmFMdIU+vLtaCyPBfGI4= +github.com/zmap/zlint/v2 v2.2.1 h1:b2kI/ToXX16h2wjV2c6Da65eT6aTMtkLHKetXuM9EtI= +github.com/zmap/zlint/v2 v2.2.1/go.mod h1:ixPWsdq8qLxYRpNUTbcKig3R7WgmspsHGLhCCs6rFAM= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= @@ -499,11 +537,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200124225646-8b5121be2f68/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -577,6 +618,7 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= diff --git a/trustpinning/certs_test.go b/trustpinning/certs_test.go index 4f5dc96ff8..606ee68e92 100644 --- a/trustpinning/certs_test.go +++ b/trustpinning/certs_test.go @@ -74,7 +74,7 @@ func sampleCertChain(t *testing.T) *certChain { // Create a simple CSR for the CA using the default CA validator and policy req := &csr.CertificateRequest{ CN: "docker.io/notary/root", - KeyRequest: csr.NewBasicKeyRequest(), + KeyRequest: csr.NewKeyRequest(), CA: &csr.CAConfig{}, } diff --git a/vendor/github.com/cloudflare/cfssl/auth/auth.go b/vendor/github.com/cloudflare/cfssl/auth/auth.go index ecd5e5fefd..db2197bb10 100644 --- a/vendor/github.com/cloudflare/cfssl/auth/auth.go +++ b/vendor/github.com/cloudflare/cfssl/auth/auth.go @@ -56,7 +56,7 @@ func New(key string, ad []byte) (*Standard, error) { if err != nil { return nil, err } - key = string(data) + key = strings.TrimSpace(string(data)) default: return nil, fmt.Errorf("unknown key prefix: %s", splitKey[0]) } diff --git a/vendor/github.com/cloudflare/cfssl/certdb/README.md b/vendor/github.com/cloudflare/cfssl/certdb/README.md index fbd941e39c..9aead39f84 100644 --- a/vendor/github.com/cloudflare/cfssl/certdb/README.md +++ b/vendor/github.com/cloudflare/cfssl/certdb/README.md @@ -27,11 +27,11 @@ Currently supported: ### Use goose to start and terminate a MySQL DB To start a MySQL using goose: - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql up + goose -path certdb/mysql up To tear down a MySQL DB using goose - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql down + goose -path certdb/mysql down Note: the administration of MySQL DB is not included. We assume the databases being connected to are already created and access control @@ -40,11 +40,11 @@ is properly handled. ### Use goose to start and terminate a PostgreSQL DB To start a PostgreSQL using goose: - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg up + goose -path certdb/pg up To tear down a PostgreSQL DB using goose - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg down + goose -path certdb/pg down Note: the administration of PostgreSQL DB is not included. We assume the databases being connected to are already created and access control @@ -53,11 +53,11 @@ is properly handled. ### Use goose to start and terminate a SQLite DB To start a SQLite DB using goose: - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite up + goose -path certdb/sqlite up To tear down a SQLite DB using goose - goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite down + goose -path certdb/sqlite down ## CFSSL Configuration diff --git a/vendor/github.com/cloudflare/cfssl/certdb/certdb.go b/vendor/github.com/cloudflare/cfssl/certdb/certdb.go index dc8c856c3b..9c3afb2b31 100644 --- a/vendor/github.com/cloudflare/cfssl/certdb/certdb.go +++ b/vendor/github.com/cloudflare/cfssl/certdb/certdb.go @@ -1,7 +1,11 @@ package certdb import ( + "database/sql" + "encoding/json" "time" + + "github.com/jmoiron/sqlx/types" ) // CertificateRecord encodes a certificate and its metadata @@ -15,6 +19,46 @@ type CertificateRecord struct { Expiry time.Time `db:"expiry"` RevokedAt time.Time `db:"revoked_at"` PEM string `db:"pem"` + // the following fields will be empty for data inserted before migrate 002 has been run. + IssuedAt *time.Time `db:"issued_at"` + NotBefore *time.Time `db:"not_before"` + MetadataJSON types.JSONText `db:"metadata"` + SANsJSON types.JSONText `db:"sans"` + CommonName sql.NullString `db:"common_name"` +} + +// SetMetadata sets the metadata json +func (c *CertificateRecord) SetMetadata(meta map[string]interface{}) error { + marshaled, err := json.Marshal(meta) + if err != nil { + return err + } + c.MetadataJSON = types.JSONText(marshaled) + return nil +} + +// GetMetadata returns the json metadata +func (c *CertificateRecord) GetMetadata() (map[string]interface{}, error) { + var meta map[string]interface{} + err := c.MetadataJSON.Unmarshal(&meta) + return meta, err +} + +// SetSANs sets the list of sans +func (c *CertificateRecord) SetSANs(meta []string) error { + marshaled, err := json.Marshal(meta) + if err != nil { + return err + } + c.SANsJSON = types.JSONText(marshaled) + return nil +} + +// GetSANs returns the json SANs +func (c *CertificateRecord) GetSANs() ([]string, error) { + var sans []string + err := c.SANsJSON.Unmarshal(&sans) + return sans, err } // OCSPRecord encodes a OCSP response body and its metadata diff --git a/vendor/github.com/cloudflare/cfssl/config/config.go b/vendor/github.com/cloudflare/cfssl/config/config.go index d5eb7c3760..56eeb43679 100644 --- a/vendor/github.com/cloudflare/cfssl/config/config.go +++ b/vendor/github.com/cloudflare/cfssl/config/config.go @@ -19,6 +19,9 @@ import ( "github.com/cloudflare/cfssl/helpers" "github.com/cloudflare/cfssl/log" ocspConfig "github.com/cloudflare/cfssl/ocsp/config" + // empty import of zlint/v2 required to have lints registered. + _ "github.com/zmap/zlint/v2" + "github.com/zmap/zlint/v2/lint" ) // A CSRWhitelist stores booleans for fields in the CSR. If a CSRWhitelist is @@ -32,7 +35,7 @@ import ( // mechanism. type CSRWhitelist struct { Subject, PublicKeyAlgorithm, PublicKey, SignatureAlgorithm bool - DNSNames, IPAddresses, EmailAddresses bool + DNSNames, IPAddresses, EmailAddresses, URIs bool } // OID is our own version of asn1's ObjectIdentifier, so we can define a custom @@ -81,6 +84,8 @@ type SigningProfile struct { ExpiryString string `json:"expiry"` BackdateString string `json:"backdate"` AuthKeyName string `json:"auth_key"` + CopyExtensions bool `json:"copy_extensions"` + PrevAuthKeyName string `json:"prev_auth_key"` // to suppport key rotation RemoteName string `json:"remote"` NotBefore time.Time `json:"not_before"` NotAfter time.Time `json:"not_after"` @@ -89,11 +94,26 @@ type SigningProfile struct { CTLogServers []string `json:"ct_log_servers"` AllowedExtensions []OID `json:"allowed_extensions"` CertStore string `json:"cert_store"` + // LintErrLevel controls preissuance linting for the signing profile. + // 0 = no linting is performed [default] + // 2..3 = reserved + // 3 = all lint results except pass are considered errors + // 4 = all lint results except pass and notice are considered errors + // 5 = all lint results except pass, notice and warn are considered errors + // 6 = all lint results except pass, notice, warn and error are considered errors. + // 7 = lint is performed, no lint results are treated as errors. + LintErrLevel lint.LintStatus `json:"lint_error_level"` + // ExcludeLints lists ZLint lint names to exclude from preissuance linting. + ExcludeLints []string `json:"ignored_lints"` + // ExcludeLintSources lists ZLint lint sources to exclude from preissuance + // linting. + ExcludeLintSources []string `json:"ignored_lint_sources"` Policies []CertificatePolicy Expiry time.Duration Backdate time.Duration Provider auth.Provider + PrevProvider auth.Provider // to suppport key rotation RemoteProvider auth.Provider RemoteServer string RemoteCAs *x509.CertPool @@ -102,6 +122,11 @@ type SigningProfile struct { NameWhitelist *regexp.Regexp ExtensionWhitelist map[string]bool ClientProvidesSerialNumbers bool + // LintRegistry is the collection of lints that should be used if + // LintErrLevel is configured. By default all ZLint lints are used. If + // ExcludeLints or ExcludeLintSources are set then this registry will be + // filtered in populate() to exclude the named lints and lint sources. + LintRegistry lint.Registry } // UnmarshalJSON unmarshals a JSON string into an OID. @@ -229,7 +254,7 @@ func (p *SigningProfile) populate(cfg *Config) error { if p.AuthKeyName != "" { log.Debug("match auth key in profile to auth_keys section") - if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true { + if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok { if key.Type == "standard" { p.Provider, err = auth.New(key.Key, nil) if err != nil { @@ -248,6 +273,27 @@ func (p *SigningProfile) populate(cfg *Config) error { } } + if p.PrevAuthKeyName != "" { + log.Debug("match previous auth key in profile to auth_keys section") + if key, ok := cfg.AuthKeys[p.PrevAuthKeyName]; ok { + if key.Type == "standard" { + p.PrevProvider, err = auth.New(key.Key, nil) + if err != nil { + log.Debugf("failed to create new standard auth provider: %v", err) + return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, + errors.New("failed to create new standard auth provider")) + } + } else { + log.Debugf("unknown authentication type %v", key.Type) + return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, + errors.New("unknown authentication type")) + } + } else { + return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, + errors.New("failed to find prev_auth_key in auth_keys section")) + } + } + if p.AuthRemote.AuthKeyName != "" { log.Debug("match auth remote key in profile to auth_keys section") if key, ok := cfg.AuthKeys[p.AuthRemote.AuthKeyName]; ok == true { @@ -284,6 +330,40 @@ func (p *SigningProfile) populate(cfg *Config) error { p.ExtensionWhitelist[asn1.ObjectIdentifier(oid).String()] = true } + // By default perform any required preissuance linting with all ZLint lints. + p.LintRegistry = lint.GlobalRegistry() + + // If ExcludeLintSources are present in config build a lint.SourceList while + // validating that no unknown sources were specified. + var excludedSources lint.SourceList + if len(p.ExcludeLintSources) > 0 { + for _, sourceName := range p.ExcludeLintSources { + var lintSource lint.LintSource + lintSource.FromString(sourceName) + if lintSource == lint.UnknownLintSource { + return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, + fmt.Errorf("failed to build excluded lint source list: unknown source %q", + sourceName)) + } + excludedSources = append(excludedSources, lintSource) + } + } + + opts := lint.FilterOptions{ + ExcludeNames: p.ExcludeLints, + ExcludeSources: excludedSources, + } + if !opts.Empty() { + // If ExcludeLints or ExcludeLintSources were not empty then filter out the + // lints we don't want to use for preissuance linting with this profile. + filteredRegistry, err := p.LintRegistry.Filter(opts) + if err != nil { + return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, + fmt.Errorf("failed to build filtered lint registry: %v", err)) + } + p.LintRegistry = filteredRegistry + } + return nil } @@ -404,7 +484,8 @@ func (p *SigningProfile) Usages() (ku x509.KeyUsage, eku []x509.ExtKeyUsage, unk // valid local default profile has defined at least a default expiration. // A valid remote profile (default or not) has remote signer initialized. // In addition, a remote profile must has a valid auth provider if auth -// key defined. +// key defined. A valid profile must not include a lint_error_level outside of +// [0,8). func (p *SigningProfile) validProfile(isDefault bool) bool { if p == nil { return false @@ -461,6 +542,11 @@ func (p *SigningProfile) validProfile(isDefault bool) bool { } } + if p.LintErrLevel < 0 || p.LintErrLevel >= 8 { + log.Debugf("invalid profile: lint_error_level outside of range [0,8)") + return false + } + log.Debugf("profile is valid") return true } @@ -551,16 +637,16 @@ func (p *Signing) Valid() bool { // KeyUsage contains a mapping of string names to key usages. var KeyUsage = map[string]x509.KeyUsage{ - "signing": x509.KeyUsageDigitalSignature, - "digital signature": x509.KeyUsageDigitalSignature, - "content committment": x509.KeyUsageContentCommitment, - "key encipherment": x509.KeyUsageKeyEncipherment, - "key agreement": x509.KeyUsageKeyAgreement, - "data encipherment": x509.KeyUsageDataEncipherment, - "cert sign": x509.KeyUsageCertSign, - "crl sign": x509.KeyUsageCRLSign, - "encipher only": x509.KeyUsageEncipherOnly, - "decipher only": x509.KeyUsageDecipherOnly, + "signing": x509.KeyUsageDigitalSignature, + "digital signature": x509.KeyUsageDigitalSignature, + "content commitment": x509.KeyUsageContentCommitment, + "key encipherment": x509.KeyUsageKeyEncipherment, + "key agreement": x509.KeyUsageKeyAgreement, + "data encipherment": x509.KeyUsageDataEncipherment, + "cert sign": x509.KeyUsageCertSign, + "crl sign": x509.KeyUsageCRLSign, + "encipher only": x509.KeyUsageEncipherOnly, + "decipher only": x509.KeyUsageDecipherOnly, } // ExtKeyUsage contains a mapping of string names to extended key diff --git a/vendor/github.com/cloudflare/cfssl/csr/csr.go b/vendor/github.com/cloudflare/cfssl/csr/csr.go index c4ccea60b0..844bc282d9 100644 --- a/vendor/github.com/cloudflare/cfssl/csr/csr.go +++ b/vendor/github.com/cloudflare/cfssl/csr/csr.go @@ -14,6 +14,7 @@ import ( "errors" "net" "net/mail" + "net/url" "strings" cferr "github.com/cloudflare/cfssl/errors" @@ -29,46 +30,38 @@ const ( // A Name contains the SubjectInfo fields. type Name struct { - C string // Country - ST string // State - L string // Locality - O string // OrganisationName - OU string // OrganisationalUnitName - SerialNumber string + C string `json:"C,omitempty" yaml:"C,omitempty"` // Country + ST string `json:"ST,omitempty" yaml:"ST,omitempty"` // State + L string `json:"L,omitempty" yaml:"L,omitempty"` // Locality + O string `json:"O,omitempty" yaml:"O,omitempty"` // OrganisationName + OU string `json:"OU,omitempty" yaml:"OU,omitempty"` // OrganisationalUnitName + SerialNumber string `json:"SerialNumber,omitempty" yaml:"SerialNumber,omitempty"` } -// A KeyRequest is a generic request for a new key. -type KeyRequest interface { - Algo() string - Size() int - Generate() (crypto.PrivateKey, error) - SigAlgo() x509.SignatureAlgorithm -} - -// A BasicKeyRequest contains the algorithm and key size for a new private key. -type BasicKeyRequest struct { +// A KeyRequest contains the algorithm and key size for a new private key. +type KeyRequest struct { A string `json:"algo" yaml:"algo"` S int `json:"size" yaml:"size"` } -// NewBasicKeyRequest returns a default BasicKeyRequest. -func NewBasicKeyRequest() *BasicKeyRequest { - return &BasicKeyRequest{"ecdsa", curveP256} +// NewKeyRequest returns a default KeyRequest. +func NewKeyRequest() *KeyRequest { + return &KeyRequest{"ecdsa", curveP256} } // Algo returns the requested key algorithm represented as a string. -func (kr *BasicKeyRequest) Algo() string { +func (kr *KeyRequest) Algo() string { return kr.A } // Size returns the requested key size. -func (kr *BasicKeyRequest) Size() int { +func (kr *KeyRequest) Size() int { return kr.S } // Generate generates a key as specified in the request. Currently, // only ECDSA and RSA are supported. -func (kr *BasicKeyRequest) Generate() (crypto.PrivateKey, error) { +func (kr *KeyRequest) Generate() (crypto.PrivateKey, error) { log.Debugf("generate key from request: algo=%s, size=%d", kr.Algo(), kr.Size()) switch kr.Algo() { case "rsa": @@ -99,7 +92,7 @@ func (kr *BasicKeyRequest) Generate() (crypto.PrivateKey, error) { // SigAlgo returns an appropriate X.509 signature algorithm given the // key request's type and size. -func (kr *BasicKeyRequest) SigAlgo() x509.SignatureAlgorithm { +func (kr *KeyRequest) SigAlgo() x509.SignatureAlgorithm { switch kr.Algo() { case "rsa": switch { @@ -139,19 +132,21 @@ type CAConfig struct { // A CertificateRequest encapsulates the API interface to the // certificate request functionality. type CertificateRequest struct { - CN string - Names []Name `json:"names" yaml:"names"` - Hosts []string `json:"hosts" yaml:"hosts"` - KeyRequest KeyRequest `json:"key,omitempty" yaml:"key,omitempty"` - CA *CAConfig `json:"ca,omitempty" yaml:"ca,omitempty"` - SerialNumber string `json:"serialnumber,omitempty" yaml:"serialnumber,omitempty"` + CN string `json:"CN" yaml:"CN"` + Names []Name `json:"names" yaml:"names"` + Hosts []string `json:"hosts" yaml:"hosts"` + KeyRequest *KeyRequest `json:"key,omitempty" yaml:"key,omitempty"` + CA *CAConfig `json:"ca,omitempty" yaml:"ca,omitempty"` + SerialNumber string `json:"serialnumber,omitempty" yaml:"serialnumber,omitempty"` + Extensions []pkix.Extension `json:"extensions,omitempty" yaml:"extensions,omitempty"` + CRL string `json:"crl_url,omitempty" yaml:"crl_url,omitempty"` } // New returns a new, empty CertificateRequest with a -// BasicKeyRequest. +// KeyRequest. func New() *CertificateRequest { return &CertificateRequest{ - KeyRequest: NewBasicKeyRequest(), + KeyRequest: NewKeyRequest(), } } @@ -193,7 +188,7 @@ type BasicConstraints struct { func ParseRequest(req *CertificateRequest) (csr, key []byte, err error) { log.Info("received CSR") if req.KeyRequest == nil { - req.KeyRequest = NewBasicKeyRequest() + req.KeyRequest = NewKeyRequest() } log.Infof("generating key: %s-%d", req.KeyRequest.Algo(), req.KeyRequest.Size()) @@ -268,14 +263,17 @@ func getHosts(cert *x509.Certificate) []string { for _, email := range cert.EmailAddresses { hosts = append(hosts, email) } + for _, uri := range cert.URIs { + hosts = append(hosts, uri.String()) + } return hosts } // getNames returns an array of Names from the certificate -// It onnly cares about Country, Organization, OrganizationalUnit, Locality, Province +// It only cares about Country, Organization, OrganizationalUnit, Locality, Province func getNames(sub pkix.Name) []Name { - // anonymous func for finding the max of a list of interger + // anonymous func for finding the max of a list of integer max := func(v1 int, vn ...int) (max int) { max = v1 for i := 0; i < len(vn); i++ { @@ -379,11 +377,15 @@ func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err erro tpl.IPAddresses = append(tpl.IPAddresses, ip) } else if email, err := mail.ParseAddress(req.Hosts[i]); err == nil && email != nil { tpl.EmailAddresses = append(tpl.EmailAddresses, email.Address) + } else if uri, err := url.ParseRequestURI(req.Hosts[i]); err == nil && uri != nil { + tpl.URIs = append(tpl.URIs, uri) } else { tpl.DNSNames = append(tpl.DNSNames, req.Hosts[i]) } } + tpl.ExtraExtensions = []pkix.Extension{} + if req.CA != nil { err = appendCAInfoToCSR(req.CA, &tpl) if err != nil { @@ -392,6 +394,14 @@ func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err erro } } + if req.Extensions != nil { + err = appendExtensionsToCSR(req.Extensions, &tpl) + if err != nil { + err = cferr.Wrap(cferr.CSRError, cferr.GenerationFailed, err) + return + } + } + csr, err = x509.CreateCertificateRequest(rand.Reader, &tpl, priv) if err != nil { log.Errorf("failed to generate a CSR: %v", err) @@ -420,13 +430,19 @@ func appendCAInfoToCSR(reqConf *CAConfig, csr *x509.CertificateRequest) error { return err } - csr.ExtraExtensions = []pkix.Extension{ - { - Id: asn1.ObjectIdentifier{2, 5, 29, 19}, - Value: val, - Critical: true, - }, - } + csr.ExtraExtensions = append(csr.ExtraExtensions, pkix.Extension{ + Id: asn1.ObjectIdentifier{2, 5, 29, 19}, + Value: val, + Critical: true, + }) return nil } + +// appendCAInfoToCSR appends user-defined extension to a CSR +func appendExtensionsToCSR(extensions []pkix.Extension, csr *x509.CertificateRequest) error { + for _, extension := range extensions { + csr.ExtraExtensions = append(csr.ExtraExtensions, extension) + } + return nil +} diff --git a/vendor/github.com/cloudflare/cfssl/errors/error.go b/vendor/github.com/cloudflare/cfssl/errors/error.go index 607223765e..9715a7cfbd 100644 --- a/vendor/github.com/cloudflare/cfssl/errors/error.go +++ b/vendor/github.com/cloudflare/cfssl/errors/error.go @@ -194,6 +194,13 @@ const ( // CTClientConstructionFailed occurs when the construction of a new // github.com/google/certificate-transparency client fails. CTClientConstructionFailed + // PrecertMissingPoison occurs when a precert is passed to SignFromPrecert + // and is missing the CT poison extension. + PrecertMissingPoison + // PrecertInvalidPoison occurs when a precert is passed to SignFromPrecert + // and has a invalid CT poison extension value or the extension is not + // critical. + PrecertInvalidPoison ) // Certificate persistence related errors specified with CertStoreError @@ -369,6 +376,10 @@ func New(category Category, reason Reason) *Error { msg = "Certificate transparency parsing failed due to unknown error" case PrecertSubmissionFailed: msg = "Certificate transparency precertificate submission failed" + case PrecertMissingPoison: + msg = "Precertificate is missing CT poison extension" + case PrecertInvalidPoison: + msg = "Precertificate contains an invalid CT poison extension" default: panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CTError.", reason)) } @@ -415,7 +426,7 @@ func Wrap(category Category, reason Reason, err error) *Error { } } case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError, - APIClientError, CSRError, CTError, CertStoreError: + APIClientError, CSRError, CTError, CertStoreError, OCSPError: // no-op, just use the error default: panic(fmt.Sprintf("Unsupported CFSSL error type: %d.", diff --git a/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers-legacy.go b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers-legacy.go new file mode 100644 index 0000000000..a634a46eb2 --- /dev/null +++ b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers-legacy.go @@ -0,0 +1,50 @@ +// +build !go1.13 + +// Package derhelpers implements common functionality +// on DER encoded data +package derhelpers + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + + cferr "github.com/cloudflare/cfssl/errors" + "golang.org/x/crypto/ed25519" +) + +// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA, or Ed25519 DER-encoded +// private key. The key must not be in PEM format. +func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { + generalKey, err := x509.ParsePKCS8PrivateKey(keyDER) + if err != nil { + generalKey, err = x509.ParsePKCS1PrivateKey(keyDER) + if err != nil { + generalKey, err = x509.ParseECPrivateKey(keyDER) + if err != nil { + generalKey, err = ParseEd25519PrivateKey(keyDER) + if err != nil { + // We don't include the actual error into + // the final error. The reason might be + // we don't want to leak any info about + // the private key. + return nil, cferr.New(cferr.PrivateKeyError, + cferr.ParseFailed) + } + } + } + } + + switch generalKey.(type) { + case *rsa.PrivateKey: + return generalKey.(*rsa.PrivateKey), nil + case *ecdsa.PrivateKey: + return generalKey.(*ecdsa.PrivateKey), nil + case ed25519.PrivateKey: + return generalKey.(ed25519.PrivateKey), nil + } + + // should never reach here + return nil, cferr.New(cferr.PrivateKeyError, cferr.ParseFailed) +} diff --git a/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go index bcc7418508..25bda27a50 100644 --- a/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go +++ b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go @@ -1,3 +1,5 @@ +// +build go1.13 + // Package derhelpers implements common functionality // on DER encoded data package derhelpers @@ -5,14 +7,15 @@ package derhelpers import ( "crypto" "crypto/ecdsa" + "crypto/ed25519" "crypto/rsa" "crypto/x509" cferr "github.com/cloudflare/cfssl/errors" ) -// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, or elliptic curve -// DER-encoded private key. The key must not be in PEM format. +// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA, or Ed25519 DER-encoded +// private key. The key must not be in PEM format. func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { generalKey, err := x509.ParsePKCS8PrivateKey(keyDER) if err != nil { @@ -20,12 +23,15 @@ func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { if err != nil { generalKey, err = x509.ParseECPrivateKey(keyDER) if err != nil { - // We don't include the actual error into - // the final error. The reason might be - // we don't want to leak any info about - // the private key. - return nil, cferr.New(cferr.PrivateKeyError, - cferr.ParseFailed) + generalKey, err = ParseEd25519PrivateKey(keyDER) + if err != nil { + // We don't include the actual error into + // the final error. The reason might be + // we don't want to leak any info about + // the private key. + return nil, cferr.New(cferr.PrivateKeyError, + cferr.ParseFailed) + } } } } @@ -35,6 +41,8 @@ func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { return generalKey.(*rsa.PrivateKey), nil case *ecdsa.PrivateKey: return generalKey.(*ecdsa.PrivateKey), nil + case ed25519.PrivateKey: + return generalKey.(ed25519.PrivateKey), nil } // should never reach here diff --git a/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go new file mode 100644 index 0000000000..9220f3e5fa --- /dev/null +++ b/vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go @@ -0,0 +1,133 @@ +package derhelpers + +import ( + "crypto" + "crypto/x509/pkix" + "encoding/asn1" + "errors" + + "golang.org/x/crypto/ed25519" +) + +var errEd25519WrongID = errors.New("incorrect object identifier") +var errEd25519WrongKeyType = errors.New("incorrect key type") + +// ed25519OID is the OID for the Ed25519 signature scheme: see +// https://datatracker.ietf.org/doc/draft-ietf-curdle-pkix-04. +var ed25519OID = asn1.ObjectIdentifier{1, 3, 101, 112} + +// subjectPublicKeyInfo reflects the ASN.1 object defined in the X.509 standard. +// +// This is defined in crypto/x509 as "publicKeyInfo". +type subjectPublicKeyInfo struct { + Algorithm pkix.AlgorithmIdentifier + PublicKey asn1.BitString +} + +// MarshalEd25519PublicKey creates a DER-encoded SubjectPublicKeyInfo for an +// ed25519 public key, as defined in +// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04. This is analagous to +// MarshalPKIXPublicKey in crypto/x509, which doesn't currently support Ed25519. +func MarshalEd25519PublicKey(pk crypto.PublicKey) ([]byte, error) { + pub, ok := pk.(ed25519.PublicKey) + if !ok { + return nil, errEd25519WrongKeyType + } + + spki := subjectPublicKeyInfo{ + Algorithm: pkix.AlgorithmIdentifier{ + Algorithm: ed25519OID, + }, + PublicKey: asn1.BitString{ + BitLength: len(pub) * 8, + Bytes: pub, + }, + } + + return asn1.Marshal(spki) +} + +// ParseEd25519PublicKey returns the Ed25519 public key encoded by the input. +func ParseEd25519PublicKey(der []byte) (crypto.PublicKey, error) { + var spki subjectPublicKeyInfo + if rest, err := asn1.Unmarshal(der, &spki); err != nil { + return nil, err + } else if len(rest) > 0 { + return nil, errors.New("SubjectPublicKeyInfo too long") + } + + if !spki.Algorithm.Algorithm.Equal(ed25519OID) { + return nil, errEd25519WrongID + } + + if spki.PublicKey.BitLength != ed25519.PublicKeySize*8 { + return nil, errors.New("SubjectPublicKeyInfo PublicKey length mismatch") + } + + return ed25519.PublicKey(spki.PublicKey.Bytes), nil +} + +// oneAsymmetricKey reflects the ASN.1 structure for storing private keys in +// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04, excluding the optional +// fields, which we don't use here. +// +// This is identical to pkcs8 in crypto/x509. +type oneAsymmetricKey struct { + Version int + Algorithm pkix.AlgorithmIdentifier + PrivateKey []byte +} + +// curvePrivateKey is the innter type of the PrivateKey field of +// oneAsymmetricKey. +type curvePrivateKey []byte + +// MarshalEd25519PrivateKey returns a DER encdoing of the input private key as +// specified in https://tools.ietf.org/html/draft-ietf-curdle-pkix-04. +func MarshalEd25519PrivateKey(sk crypto.PrivateKey) ([]byte, error) { + priv, ok := sk.(ed25519.PrivateKey) + if !ok { + return nil, errEd25519WrongKeyType + } + + // Marshal the innter CurvePrivateKey. + curvePrivateKey, err := asn1.Marshal(priv.Seed()) + if err != nil { + return nil, err + } + + // Marshal the OneAsymmetricKey. + asym := oneAsymmetricKey{ + Version: 0, + Algorithm: pkix.AlgorithmIdentifier{ + Algorithm: ed25519OID, + }, + PrivateKey: curvePrivateKey, + } + return asn1.Marshal(asym) +} + +// ParseEd25519PrivateKey returns the Ed25519 private key encoded by the input. +func ParseEd25519PrivateKey(der []byte) (crypto.PrivateKey, error) { + asym := new(oneAsymmetricKey) + if rest, err := asn1.Unmarshal(der, asym); err != nil { + return nil, err + } else if len(rest) > 0 { + return nil, errors.New("OneAsymmetricKey too long") + } + + // Check that the key type is correct. + if !asym.Algorithm.Algorithm.Equal(ed25519OID) { + return nil, errEd25519WrongID + } + + // Unmarshal the inner CurvePrivateKey. + seed := new(curvePrivateKey) + if rest, err := asn1.Unmarshal(asym.PrivateKey, seed); err != nil { + return nil, err + } else if len(rest) > 0 { + return nil, errors.New("CurvePrivateKey too long") + } + + return ed25519.NewKeyFromSeed(*seed), nil +} diff --git a/vendor/github.com/cloudflare/cfssl/helpers/helpers.go b/vendor/github.com/cloudflare/cfssl/helpers/helpers.go index c9506077a4..8b957582d7 100644 --- a/vendor/github.com/cloudflare/cfssl/helpers/helpers.go +++ b/vendor/github.com/cloudflare/cfssl/helpers/helpers.go @@ -12,16 +12,15 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" - "encoding/binary" "encoding/pem" "errors" "fmt" - "io" "io/ioutil" "os" - "github.com/google/certificate-transparency-go" + ct "github.com/google/certificate-transparency-go" cttls "github.com/google/certificate-transparency-go/tls" + ctx509 "github.com/google/certificate-transparency-go/x509" "golang.org/x/crypto/ocsp" "strings" @@ -185,7 +184,20 @@ func HashAlgoString(alg x509.SignatureAlgorithm) string { } } -// EncodeCertificatesPEM encodes a number of x509 certficates to PEM +// StringTLSVersion returns underlying enum values from human names for TLS +// versions, defaults to current golang default of TLS 1.0 +func StringTLSVersion(version string) uint16 { + switch version { + case "1.2": + return tls.VersionTLS12 + case "1.1": + return tls.VersionTLS11 + default: + return tls.VersionTLS10 + } +} + +// EncodeCertificatesPEM encodes a number of x509 certificates to PEM func EncodeCertificatesPEM(certs []*x509.Certificate) []byte { var buffer bytes.Buffer for _, cert := range certs { @@ -198,7 +210,7 @@ func EncodeCertificatesPEM(certs []*x509.Certificate) []byte { return buffer.Bytes() } -// EncodeCertificatePEM encodes a single x509 certficates to PEM +// EncodeCertificatePEM encodes a single x509 certificates to PEM func EncodeCertificatePEM(cert *x509.Certificate) []byte { return EncodeCertificatesPEM([]*x509.Certificate{cert}) } @@ -366,7 +378,15 @@ func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto. // GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes. func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) { - keyDER, _ := pem.Decode(in) + // Ignore any EC PARAMETERS blocks when looking for a key (openssl includes + // them by default). + var keyDER *pem.Block + for { + keyDER, in = pem.Decode(in) + if keyDER == nil || keyDER.Type != "EC PARAMETERS" { + break + } + } if keyDER != nil { if procType, ok := keyDER.Headers["Proc-Type"]; ok { if strings.Contains(procType, "ENCRYPTED") { @@ -408,7 +428,7 @@ func ParseCSR(in []byte) (csr *x509.CertificateRequest, rest []byte, err error) return csr, rest, nil } -// ParseCSRPEM parses a PEM-encoded certificiate signing request. +// ParseCSRPEM parses a PEM-encoded certificate signing request. // It does not check the signature. This is useful for dumping data from a CSR // locally. func ParseCSRPEM(csrPEM []byte) (*x509.CertificateRequest, error) { @@ -461,7 +481,7 @@ func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, e if certFile != "" && keyFile != "" { cert, err := tls.LoadX509KeyPair(certFile, keyFile) if err != nil { - log.Critical("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile) + log.Criticalf("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile) return nil, err } log.Debug("Client certificate loaded ") @@ -484,64 +504,40 @@ func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Confi // SerializeSCTList serializes a list of SCTs. func SerializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) { - var buf bytes.Buffer + list := ctx509.SignedCertificateTimestampList{} for _, sct := range sctList { - sct, err := cttls.Marshal(sct) + sctBytes, err := cttls.Marshal(sct) if err != nil { return nil, err } - binary.Write(&buf, binary.BigEndian, uint16(len(sct))) - buf.Write(sct) + list.SCTList = append(list.SCTList, ctx509.SerializedSCT{Val: sctBytes}) } - - var sctListLengthField = make([]byte, 2) - binary.BigEndian.PutUint16(sctListLengthField, uint16(buf.Len())) - return bytes.Join([][]byte{sctListLengthField, buf.Bytes()}, nil), nil + return cttls.Marshal(list) } // DeserializeSCTList deserializes a list of SCTs. -func DeserializeSCTList(serializedSCTList []byte) (*[]ct.SignedCertificateTimestamp, error) { - sctList := new([]ct.SignedCertificateTimestamp) - sctReader := bytes.NewBuffer(serializedSCTList) - - var sctListLen uint16 - err := binary.Read(sctReader, binary.BigEndian, &sctListLen) +func DeserializeSCTList(serializedSCTList []byte) ([]ct.SignedCertificateTimestamp, error) { + var sctList ctx509.SignedCertificateTimestampList + rest, err := cttls.Unmarshal(serializedSCTList, &sctList) if err != nil { - if err == io.EOF { - return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, - errors.New("serialized SCT list could not be read")) - } - return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) + return nil, err } - if sctReader.Len() != int(sctListLen) { - return sctList, errors.New("SCT length field and SCT length don't match") + if len(rest) != 0 { + return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT list contained trailing garbage")) } - - for err != io.EOF { - var sctLen uint16 - err = binary.Read(sctReader, binary.BigEndian, &sctLen) + list := make([]ct.SignedCertificateTimestamp, len(sctList.SCTList)) + for i, serializedSCT := range sctList.SCTList { + var sct ct.SignedCertificateTimestamp + rest, err := cttls.Unmarshal(serializedSCT.Val, &sct) if err != nil { - if err == io.EOF { - return sctList, nil - } - return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) - } - - if sctReader.Len() < int(sctLen) { - return sctList, errors.New("SCT length field and SCT length don't match") + return nil, err } - - serializedSCT := sctReader.Next(int(sctLen)) - var sct ct.SignedCertificateTimestamp - if _, err := cttls.Unmarshal(serializedSCT, &sct); err != nil { - return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) + if len(rest) != 0 { + return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT contained trailing garbage")) } - - temp := append(*sctList, sct) - sctList = &temp + list[i] = sct } - - return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err) + return list, nil } // SCTListFromOCSPResponse extracts the SCTList from an ocsp.Response, @@ -560,22 +556,21 @@ func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTim } // This code block extracts the sctList from the SCT extension. - var emptySCTList []ct.SignedCertificateTimestamp - sctList := &emptySCTList + var sctList []ct.SignedCertificateTimestamp var err error if numBytes := len(SCTListExtension.Value); numBytes != 0 { - serializedSCTList := new([]byte) + var serializedSCTList []byte rest := make([]byte, numBytes) copy(rest, SCTListExtension.Value) for len(rest) != 0 { - rest, err = asn1.Unmarshal(rest, serializedSCTList) + rest, err = asn1.Unmarshal(rest, &serializedSCTList) if err != nil { return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) } } - sctList, err = DeserializeSCTList(*serializedSCTList) + sctList, err = DeserializeSCTList(serializedSCTList) } - return *sctList, err + return sctList, err } // ReadBytes reads a []byte either from a file or an environment variable. diff --git a/vendor/github.com/cloudflare/cfssl/initca/initca.go b/vendor/github.com/cloudflare/cfssl/initca/initca.go index 89fcfb54b9..40a608502a 100644 --- a/vendor/github.com/cloudflare/cfssl/initca/initca.go +++ b/vendor/github.com/cloudflare/cfssl/initca/initca.go @@ -69,6 +69,10 @@ func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { } } + if req.CRL != "" { + policy.Default.CRL = req.CRL + } + g := &csr.Generator{Validator: validator} csrPEM, key, err = g.ProcessRequest(req) if err != nil { @@ -113,7 +117,7 @@ func NewFromPEM(req *csr.CertificateRequest, keyFile string) (cert, csrPEM []byt // RenewFromPEM re-creates a root certificate from the CA cert and key // files. The resulting root certificate will have the input CA certificate -// as the template and have the same expiry length. E.g. the exsiting CA +// as the template and have the same expiry length. E.g. the existing CA // is valid for a year from Jan 01 2015 to Jan 01 2016, the renewed certificate // will be valid from now and expire in one year as well. func RenewFromPEM(caFile, keyFile string) ([]byte, error) { @@ -178,7 +182,7 @@ func NewFromSigner(req *csr.CertificateRequest, priv crypto.Signer) (cert, csrPE // RenewFromSigner re-creates a root certificate from the CA cert and crypto.Signer. // The resulting root certificate will have ca certificate -// as the template and have the same expiry length. E.g. the exsiting CA +// as the template and have the same expiry length. E.g. the existing CA // is valid for a year from Jan 01 2015 to Jan 01 2016, the renewed certificate // will be valid from now and expire in one year as well. func RenewFromSigner(ca *x509.Certificate, priv crypto.Signer) ([]byte, error) { diff --git a/vendor/github.com/cloudflare/cfssl/signer/local/local.go b/vendor/github.com/cloudflare/cfssl/signer/local/local.go index 67701af7b6..d0dbad18c6 100644 --- a/vendor/github.com/cloudflare/cfssl/signer/local/local.go +++ b/vendor/github.com/cloudflare/cfssl/signer/local/local.go @@ -4,19 +4,25 @@ package local import ( "bytes" "crypto" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rand" "crypto/x509" "crypto/x509/pkix" + "database/sql" "encoding/asn1" "encoding/hex" "encoding/pem" "errors" + "fmt" "io" "math/big" "net" "net/http" "net/mail" + "net/url" "os" + "time" "github.com/cloudflare/cfssl/certdb" "github.com/cloudflare/cfssl/config" @@ -25,17 +31,24 @@ import ( "github.com/cloudflare/cfssl/info" "github.com/cloudflare/cfssl/log" "github.com/cloudflare/cfssl/signer" - "github.com/google/certificate-transparency-go" + ct "github.com/google/certificate-transparency-go" "github.com/google/certificate-transparency-go/client" "github.com/google/certificate-transparency-go/jsonclient" + + zx509 "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2" + "github.com/zmap/zlint/v2/lint" "golang.org/x/net/context" ) // Signer contains a signer that uses the standard library to // support both ECDSA and RSA CA keys. type Signer struct { - ca *x509.Certificate - priv crypto.Signer + ca *x509.Certificate + priv crypto.Signer + // lintPriv is generated randomly when pre-issuance linting is configured and + // used to sign TBSCertificates for linting. + lintPriv crypto.Signer policy *config.Signing sigAlgo x509.SignatureAlgorithm dbAccessor certdb.Accessor @@ -54,11 +67,30 @@ func NewSigner(priv crypto.Signer, cert *x509.Certificate, sigAlgo x509.Signatur return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy) } + var lintPriv crypto.Signer + // If there is at least one profile (including the default) that configures + // pre-issuance linting then generate the one-off lintPriv key. + for _, profile := range policy.Profiles { + if profile.LintErrLevel > 0 || policy.Default.LintErrLevel > 0 { + // In the future there may be demand for specifying the type of signer used + // for pre-issuance linting in configuration. For now we assume that signing + // with a randomly generated P-256 ECDSA private key is acceptable for all cases + // where linting is requested. + k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, cferr.New(cferr.PrivateKeyError, cferr.GenerationFailed) + } + lintPriv = k + break + } + } + return &Signer{ - ca: cert, - priv: priv, - sigAlgo: sigAlgo, - policy: policy, + ca: cert, + priv: priv, + lintPriv: lintPriv, + sigAlgo: sigAlgo, + policy: policy, }, nil } @@ -89,14 +121,75 @@ func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signe priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password) if err != nil { - log.Debug("Malformed private key %v", err) + log.Debugf("Malformed private key %v", err) return nil, err } return NewSigner(priv, parsedCa, signer.DefaultSigAlgo(priv), policy) } -func (s *Signer) sign(template *x509.Certificate) (cert []byte, err error) { +// LintError is an error type returned when pre-issuance linting is configured +// in a signing profile and a TBS Certificate fails linting. It wraps the +// concrete zlint LintResults so that callers can further inspect the cause of +// the failing lints. +type LintError struct { + ErrorResults map[string]lint.LintResult +} + +func (e *LintError) Error() string { + return fmt.Sprintf("pre-issuance linting found %d error results", + len(e.ErrorResults)) +} + +// lint performs pre-issuance linting of a given TBS certificate template when +// the provided errLevel is > 0. Note that the template is provided by-value and +// not by-reference. This is important as the lint function needs to mutate the +// template's signature algorithm to match the lintPriv. +func (s *Signer) lint(template x509.Certificate, errLevel lint.LintStatus, lintRegistry lint.Registry) error { + // Always return nil when linting is disabled (lint.Reserved == 0). + if errLevel == lint.Reserved { + return nil + } + // without a lintPriv key to use to sign the tbsCertificate we can't lint it. + if s.lintPriv == nil { + return cferr.New(cferr.PrivateKeyError, cferr.Unavailable) + } + + // The template's SignatureAlgorithm must be mutated to match the lintPriv or + // x509.CreateCertificate will error because of the mismatch. At the time of + // writing s.lintPriv is always an ECDSA private key. This switch will need to + // be expanded if the lint key type is made configurable. + switch s.lintPriv.(type) { + case *ecdsa.PrivateKey: + template.SignatureAlgorithm = x509.ECDSAWithSHA256 + default: + return cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch) + } + + prelintBytes, err := x509.CreateCertificate(rand.Reader, &template, s.ca, template.PublicKey, s.lintPriv) + if err != nil { + return cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) + } + prelintCert, err := zx509.ParseCertificate(prelintBytes) + if err != nil { + return cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + errorResults := map[string]lint.LintResult{} + results := zlint.LintCertificateEx(prelintCert, lintRegistry) + for name, res := range results.Results { + if res.Status > errLevel { + errorResults[name] = *res + } + } + if len(errorResults) > 0 { + return &LintError{ + ErrorResults: errorResults, + } + } + return nil +} + +func (s *Signer) sign(template *x509.Certificate, lintErrLevel lint.LintStatus, lintRegistry lint.Registry) (cert []byte, err error) { var initRoot bool if s.ca == nil { if !template.IsCA { @@ -105,10 +198,15 @@ func (s *Signer) sign(template *x509.Certificate) (cert []byte, err error) { } template.DNSNames = nil template.EmailAddresses = nil + template.URIs = nil s.ca = template initRoot = true } + if err := s.lint(*template, lintErrLevel, lintRegistry); err != nil { + return nil, err + } + derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) @@ -159,13 +257,14 @@ func PopulateSubjectFromCSR(s *signer.Subject, req pkix.Name) pkix.Name { return name } -// OverrideHosts fills template's IPAddresses, EmailAddresses, and DNSNames with the +// OverrideHosts fills template's IPAddresses, EmailAddresses, DNSNames, and URIs with the // content of hosts, if it is not nil. func OverrideHosts(template *x509.Certificate, hosts []string) { if hosts != nil { template.IPAddresses = []net.IP{} template.EmailAddresses = []string{} template.DNSNames = []string{} + template.URIs = []*url.URL{} } for i := range hosts { @@ -173,6 +272,8 @@ func OverrideHosts(template *x509.Certificate, hosts []string) { template.IPAddresses = append(template.IPAddresses, ip) } else if email, err := mail.ParseAddress(hosts[i]); err == nil && email != nil { template.EmailAddresses = append(template.EmailAddresses, email.Address) + } else if uri, err := url.ParseRequestURI(hosts[i]); err == nil && uri != nil { + template.URIs = append(template.URIs, uri) } else { template.DNSNames = append(template.DNSNames, hosts[i]) } @@ -199,7 +300,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { cferr.BadRequest, errors.New("not a csr")) } - csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes) + csrTemplate, err := signer.ParseCertificateRequest(s, profile, block.Bytes) if err != nil { return nil, err } @@ -232,6 +333,9 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { if profile.CSRWhitelist.EmailAddresses { safeTemplate.EmailAddresses = csrTemplate.EmailAddresses } + if profile.CSRWhitelist.URIs { + safeTemplate.URIs = csrTemplate.URIs + } } if req.CRLOverride != "" { @@ -277,6 +381,11 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) } } + for _, name := range safeTemplate.URIs { + if profile.NameWhitelist.Find([]byte(name.String())) == nil { + return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist) + } + } } if profile.ClientProvidesSerialNumbers { @@ -337,16 +446,20 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { var certTBS = safeTemplate - if len(profile.CTLogServers) > 0 { + if len(profile.CTLogServers) > 0 || req.ReturnPrecert { // Add a poison extension which prevents validation var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}} var poisonedPreCert = certTBS poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension) - cert, err = s.sign(&poisonedPreCert) + cert, err = s.sign(&poisonedPreCert, profile.LintErrLevel, profile.LintRegistry) if err != nil { return } + if req.ReturnPrecert { + return cert, nil + } + derCert, _ := pem.Decode(cert) prechain := []ct.ASN1Cert{{Data: derCert.Bytes}, {Data: s.ca.Raw}} var sctList []ct.SignedCertificateTimestamp @@ -381,8 +494,9 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList} certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension) } + var signedCert []byte - signedCert, err = s.sign(&certTBS) + signedCert, err = s.sign(&certTBS, profile.LintErrLevel, profile.LintRegistry) if err != nil { return nil, err } @@ -393,19 +507,29 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { parsedCert, _ := helpers.ParseCertificatePEM(signedCert) if s.dbAccessor != nil { + now := time.Now() var certRecord = certdb.CertificateRecord{ Serial: certTBS.SerialNumber.String(), // this relies on the specific behavior of x509.CreateCertificate // which sets the AuthorityKeyId from the signer's SubjectKeyId - AKI: hex.EncodeToString(parsedCert.AuthorityKeyId), - CALabel: req.Label, - Status: "good", - Expiry: certTBS.NotAfter, - PEM: string(signedCert), + AKI: hex.EncodeToString(parsedCert.AuthorityKeyId), + CALabel: req.Label, + Status: "good", + Expiry: certTBS.NotAfter, + PEM: string(signedCert), + IssuedAt: &now, + NotBefore: &certTBS.NotBefore, + CommonName: sql.NullString{String: certTBS.Subject.CommonName, Valid: true}, } - err = s.dbAccessor.InsertCertificate(certRecord) - if err != nil { + if err := certRecord.SetMetadata(req.Metadata); err != nil { + return nil, err + } + if err := certRecord.SetSANs(certTBS.DNSNames); err != nil { + return nil, err + } + + if err := s.dbAccessor.InsertCertificate(certRecord); err != nil { return nil, err } log.Debug("saved certificate with serial number ", certTBS.SerialNumber) @@ -414,6 +538,89 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { return signedCert, nil } +// SignFromPrecert creates and signs a certificate from an existing precertificate +// that was previously signed by Signer.ca and inserts the provided SCTs into the +// new certificate. The resulting certificate will be a exact copy of the precert +// except for the removal of the poison extension and the addition of the SCT list +// extension. SignFromPrecert does not verify that the contents of the certificate +// still match the signing profile of the signer, it only requires that the precert +// was previously signed by the Signers CA. Similarly, any linting configured +// by the profile used to sign the precert will not be re-applied to the final +// cert and must be done separately by the caller. +func (s *Signer) SignFromPrecert(precert *x509.Certificate, scts []ct.SignedCertificateTimestamp) ([]byte, error) { + // Verify certificate was signed by s.ca + if err := precert.CheckSignatureFrom(s.ca); err != nil { + return nil, err + } + + // Verify certificate is a precert + isPrecert := false + poisonIndex := 0 + for i, ext := range precert.Extensions { + if ext.Id.Equal(signer.CTPoisonOID) { + if !ext.Critical { + return nil, cferr.New(cferr.CTError, cferr.PrecertInvalidPoison) + } + // Check extension contains ASN.1 NULL + if bytes.Compare(ext.Value, []byte{0x05, 0x00}) != 0 { + return nil, cferr.New(cferr.CTError, cferr.PrecertInvalidPoison) + } + isPrecert = true + poisonIndex = i + break + } + } + if !isPrecert { + return nil, cferr.New(cferr.CTError, cferr.PrecertMissingPoison) + } + + // Serialize SCTs into list format and create extension + serializedList, err := helpers.SerializeSCTList(scts) + if err != nil { + return nil, err + } + // Serialize again as an octet string before embedding + serializedList, err = asn1.Marshal(serializedList) + if err != nil { + return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err) + } + sctExt := pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedList} + + // Create the new tbsCert from precert. Do explicit copies of any slices so that we don't + // use memory that may be altered by us or the caller at a later stage. + tbsCert := x509.Certificate{ + SignatureAlgorithm: precert.SignatureAlgorithm, + PublicKeyAlgorithm: precert.PublicKeyAlgorithm, + PublicKey: precert.PublicKey, + Version: precert.Version, + SerialNumber: precert.SerialNumber, + Issuer: precert.Issuer, + Subject: precert.Subject, + NotBefore: precert.NotBefore, + NotAfter: precert.NotAfter, + KeyUsage: precert.KeyUsage, + BasicConstraintsValid: precert.BasicConstraintsValid, + IsCA: precert.IsCA, + MaxPathLen: precert.MaxPathLen, + MaxPathLenZero: precert.MaxPathLenZero, + PermittedDNSDomainsCritical: precert.PermittedDNSDomainsCritical, + } + if len(precert.Extensions) > 0 { + tbsCert.ExtraExtensions = make([]pkix.Extension, len(precert.Extensions)) + copy(tbsCert.ExtraExtensions, precert.Extensions) + } + + // Remove the poison extension from ExtraExtensions + tbsCert.ExtraExtensions = append(tbsCert.ExtraExtensions[:poisonIndex], tbsCert.ExtraExtensions[poisonIndex+1:]...) + // Insert the SCT list extension + tbsCert.ExtraExtensions = append(tbsCert.ExtraExtensions, sctExt) + + // Sign the tbsCert. Linting is always disabled because there is no way for + // this API to know the correct lint settings to use because there is no + // reference to the signing profile of the precert available. + return s.sign(&tbsCert, 0, nil) +} + // Info return a populated info.Resp struct or an error. func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) { cert, err := s.Certificate(req.Label, req.Profile) diff --git a/vendor/github.com/cloudflare/cfssl/signer/signer.go b/vendor/github.com/cloudflare/cfssl/signer/signer.go index 20101f682b..7ce79d7571 100644 --- a/vendor/github.com/cloudflare/cfssl/signer/signer.go +++ b/vendor/github.com/cloudflare/cfssl/signer/signer.go @@ -64,6 +64,15 @@ type SignRequest struct { // for canonicalization) as the value of the notAfter field of the // certificate. NotAfter time.Time + // If ReturnPrecert is true a certificate with the CT poison extension + // will be returned from the Signer instead of attempting to retrieve + // SCTs and populate the tbsCert with them itself. This precert can then + // be passed to SignFromPrecert with the SCTs in order to create a + // valid certificate. + ReturnPrecert bool + + // Arbitrary metadata to be stored in certdb. + Metadata map[string]interface{} `json:"metadata"` } // appendIf appends to a if s is not an empty string. @@ -165,7 +174,7 @@ func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm { // ParseCertificateRequest takes an incoming certificate request and // builds a certificate template from it. -func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certificate, err error) { +func ParseCertificateRequest(s Signer, p *config.SigningProfile, csrBytes []byte) (template *x509.Certificate, err error) { csrv, err := x509.ParseCertificateRequest(csrBytes) if err != nil { err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err) @@ -186,6 +195,9 @@ func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certific DNSNames: csrv.DNSNames, IPAddresses: csrv.IPAddresses, EmailAddresses: csrv.EmailAddresses, + URIs: csrv.URIs, + Extensions: csrv.Extensions, + ExtraExtensions: []pkix.Extension{}, } for _, val := range csrv.Extensions { @@ -205,6 +217,11 @@ func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certific template.IsCA = constraints.IsCA template.MaxPathLen = constraints.MaxPathLen template.MaxPathLenZero = template.MaxPathLen == 0 + } else { + // If the profile has 'copy_extensions' to true then lets add it + if p.CopyExtensions { + template.ExtraExtensions = append(template.ExtraExtensions, val) + } } } @@ -314,6 +331,7 @@ func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.Si } template.DNSNames = nil template.EmailAddresses = nil + template.URIs = nil } template.SubjectKeyId = ski diff --git a/vendor/github.com/gogo/protobuf/AUTHORS b/vendor/github.com/gogo/protobuf/AUTHORS deleted file mode 100644 index 3d97fc7a29..0000000000 --- a/vendor/github.com/gogo/protobuf/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -# This is the official list of GoGo authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS file, which -# lists people. For example, employees are listed in CONTRIBUTORS, -# but not in AUTHORS, because the employer holds the copyright. - -# Names should be added to this file as one of -# Organization's name -# Individual's name -# Individual's name - -# Please keep the list sorted. - -Sendgrid, Inc -Vastech SA (PTY) LTD -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/CONTRIBUTORS b/vendor/github.com/gogo/protobuf/CONTRIBUTORS deleted file mode 100644 index 1b4f6c208a..0000000000 --- a/vendor/github.com/gogo/protobuf/CONTRIBUTORS +++ /dev/null @@ -1,23 +0,0 @@ -Anton Povarov -Brian Goff -Clayton Coleman -Denis Smirnov -DongYun Kang -Dwayne Schultz -Georg Apitz -Gustav Paul -Johan Brandhorst -John Shahid -John Tuley -Laurent -Patrick Lee -Peter Edge -Roger Johansson -Sam Nguyen -Sergio Arbeo -Stephen J Day -Tamir Duberstein -Todd Eisenberger -Tormod Erevik Lea -Vyacheslav Kim -Walter Schulze diff --git a/vendor/github.com/gogo/protobuf/LICENSE b/vendor/github.com/gogo/protobuf/LICENSE deleted file mode 100644 index f57de90da8..0000000000 --- a/vendor/github.com/gogo/protobuf/LICENSE +++ /dev/null @@ -1,35 +0,0 @@ -Copyright (c) 2013, The GoGo Authors. All rights reserved. - -Protocol Buffers for Go with Gadgets - -Go support for Protocol Buffers - Google's data interchange format - -Copyright 2010 The Go Authors. All rights reserved. -https://github.com/golang/protobuf - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/vendor/github.com/gogo/protobuf/proto/Makefile b/vendor/github.com/gogo/protobuf/proto/Makefile deleted file mode 100644 index 00d65f3277..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Go support for Protocol Buffers - Google's data interchange format -# -# Copyright 2010 The Go Authors. All rights reserved. -# https://github.com/golang/protobuf -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -install: - go install - -test: install generate-test-pbs - go test - - -generate-test-pbs: - make install - make -C test_proto - make -C proto3_proto - make diff --git a/vendor/github.com/gogo/protobuf/proto/clone.go b/vendor/github.com/gogo/protobuf/proto/clone.go deleted file mode 100644 index a26b046d94..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/clone.go +++ /dev/null @@ -1,258 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer deep copy and merge. -// TODO: RawMessage. - -package proto - -import ( - "fmt" - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(src Message) Message { - in := reflect.ValueOf(src) - if in.IsNil() { - return src - } - out := reflect.New(in.Type().Elem()) - dst := out.Interface().(Message) - Merge(dst, src) - return dst -} - -// Merger is the interface representing objects that can merge messages of the same type. -type Merger interface { - // Merge merges src into this message. - // Required and optional fields that are set in src will be set to that value in dst. - // Elements of repeated fields will be appended. - // - // Merge may panic if called with a different argument type than the receiver. - Merge(src Message) -} - -// generatedMerger is the custom merge method that generated protos will have. -// We must add this method since a generate Merge method will conflict with -// many existing protos that have a Merge data field already defined. -type generatedMerger interface { - XXX_Merge(src Message) -} - -// Merge merges src into dst. -// Required and optional fields that are set in src will be set to that value in dst. -// Elements of repeated fields will be appended. -// Merge panics if src and dst are not the same type, or if dst is nil. -func Merge(dst, src Message) { - if m, ok := dst.(Merger); ok { - m.Merge(src) - return - } - - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) - } - if in.IsNil() { - return // Merge from nil src is a noop - } - if m, ok := dst.(generatedMerger); ok { - m.XXX_Merge(src) - return - } - mergeStruct(out.Elem(), in.Elem()) -} - -func mergeStruct(out, in reflect.Value) { - sprop := GetProperties(in.Type()) - for i := 0; i < in.NumField(); i++ { - f := in.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) - } - - if emIn, ok := in.Addr().Interface().(extensionsBytes); ok { - emOut := out.Addr().Interface().(extensionsBytes) - bIn := emIn.GetExtensions() - bOut := emOut.GetExtensions() - *bOut = append(*bOut, *bIn...) - } else if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - uf := in.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return - } - uin := uf.Bytes() - if len(uin) > 0 { - out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) - } -} - -// mergeAny performs a merge between two values of the same type. -// viaPtr indicates whether the values were indirected through a pointer (implying proto2). -// prop is set if this is a struct field (it may be nil). -func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { - if in.Type() == protoMessageType { - if !in.IsNil() { - if out.IsNil() { - out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) - } else { - Merge(out.Interface().(Message), in.Interface().(Message)) - } - } - return - } - switch in.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - if !viaPtr && isProto3Zero(in) { - return - } - out.Set(in) - case reflect.Interface: - // Probably a oneof field; copy non-nil values. - if in.IsNil() { - return - } - // Allocate destination if it is not set, or set to a different type. - // Otherwise we will merge as normal. - if out.IsNil() || out.Elem().Type() != in.Elem().Type() { - out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) - } - mergeAny(out.Elem(), in.Elem(), false, nil) - case reflect.Map: - if in.Len() == 0 { - return - } - if out.IsNil() { - out.Set(reflect.MakeMap(in.Type())) - } - // For maps with value types of *T or []byte we need to deep copy each value. - elemKind := in.Type().Elem().Kind() - for _, key := range in.MapKeys() { - var val reflect.Value - switch elemKind { - case reflect.Ptr: - val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key), false, nil) - case reflect.Slice: - val = in.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - default: - val = in.MapIndex(key) - } - out.SetMapIndex(key, val) - } - case reflect.Ptr: - if in.IsNil() { - return - } - if out.IsNil() { - out.Set(reflect.New(in.Elem().Type())) - } - mergeAny(out.Elem(), in.Elem(), true, nil) - case reflect.Slice: - if in.IsNil() { - return - } - if in.Type().Elem().Kind() == reflect.Uint8 { - // []byte is a scalar bytes field, not a repeated field. - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value, and should not - // be merged. - if prop != nil && prop.proto3 && in.Len() == 0 { - return - } - - // Make a deep copy. - // Append to []byte{} instead of []byte(nil) so that we never end up - // with a nil result. - out.SetBytes(append([]byte{}, in.Bytes()...)) - return - } - n := in.Len() - if out.IsNil() { - out.Set(reflect.MakeSlice(in.Type(), 0, n)) - } - switch in.Type().Elem().Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - out.Set(reflect.AppendSlice(out, in)) - default: - for i := 0; i < n; i++ { - x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i), false, nil) - out.Set(reflect.Append(out, x)) - } - } - case reflect.Struct: - mergeStruct(out, in) - default: - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to copy %v", in) - } -} - -func mergeExtension(out, in map[int32]Extension) { - for extNum, eIn := range in { - eOut := Extension{desc: eIn.desc} - if eIn.value != nil { - v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value), false, nil) - eOut.value = v.Interface() - } - if eIn.enc != nil { - eOut.enc = make([]byte, len(eIn.enc)) - copy(eOut.enc, eIn.enc) - } - - out[extNum] = eOut - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/custom_gogo.go b/vendor/github.com/gogo/protobuf/proto/custom_gogo.go deleted file mode 100644 index 24552483c6..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/custom_gogo.go +++ /dev/null @@ -1,39 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import "reflect" - -type custom interface { - Marshal() ([]byte, error) - Unmarshal(data []byte) error - Size() int -} - -var customType = reflect.TypeOf((*custom)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/decode.go b/vendor/github.com/gogo/protobuf/proto/decode.go deleted file mode 100644 index 63b0f08bef..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/decode.go +++ /dev/null @@ -1,427 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for decoding protocol buffer data to construct in-memory representations. - */ - -import ( - "errors" - "fmt" - "io" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// ErrInternalBadWireType is returned by generated code when an incorrect -// wire type is encountered. It does not get returned to user code. -var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") - -// DecodeVarint reads a varint-encoded integer from the slice. -// It returns the integer and the number of bytes consumed, or -// zero if there is not enough. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func DecodeVarint(buf []byte) (x uint64, n int) { - for shift := uint(0); shift < 64; shift += 7 { - if n >= len(buf) { - return 0, 0 - } - b := uint64(buf[n]) - n++ - x |= (b & 0x7F) << shift - if (b & 0x80) == 0 { - return x, n - } - } - - // The number is too large to represent in a 64-bit value. - return 0, 0 -} - -func (p *Buffer) decodeVarintSlow() (x uint64, err error) { - i := p.index - l := len(p.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := p.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - p.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = errOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - i := p.index - buf := p.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - p.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return p.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x = uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - - return 0, errOverflow - -done: - p.index = i - return x, nil -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := p.index + 8 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-8]) - x |= uint64(p.buf[i-7]) << 8 - x |= uint64(p.buf[i-6]) << 16 - x |= uint64(p.buf[i-5]) << 24 - x |= uint64(p.buf[i-4]) << 32 - x |= uint64(p.buf[i-3]) << 40 - x |= uint64(p.buf[i-2]) << 48 - x |= uint64(p.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := p.index + 4 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-4]) - x |= uint64(p.buf[i-3]) << 8 - x |= uint64(p.buf[i-2]) << 16 - x |= uint64(p.buf[i-1]) << 24 - return -} - -// DecodeZigzag64 reads a zigzag-encoded 64-bit integer -// from the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) DecodeZigzag64() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) - return -} - -// DecodeZigzag32 reads a zigzag-encoded 32-bit integer -// from the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) DecodeZigzag32() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) - return -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := p.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := p.index + nb - if end < p.index || end > len(p.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - // todo: check if can get more uses of alloc=false - buf = p.buf[p.index:end] - p.index += nb - return - } - - buf = make([]byte, nb) - copy(buf, p.buf[p.index:]) - p.index += nb - return -} - -// DecodeStringBytes reads an encoded string from the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) DecodeStringBytes() (s string, err error) { - buf, err := p.DecodeRawBytes(false) - if err != nil { - return - } - return string(buf), nil -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -// Unmarshal implementations should not clear the receiver. -// Any unmarshaled data should be merged into the receiver. -// Callers of Unmarshal that do not want to retain existing data -// should Reset the receiver before calling Unmarshal. -type Unmarshaler interface { - Unmarshal([]byte) error -} - -// newUnmarshaler is the interface representing objects that can -// unmarshal themselves. The semantics are identical to Unmarshaler. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newUnmarshaler interface { - XXX_Unmarshal([]byte) error -} - -// Unmarshal parses the protocol buffer representation in buf and places the -// decoded result in pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// Unmarshal resets pb before starting to unmarshal, so any -// existing data in pb is always removed. Use UnmarshalMerge -// to preserve and append to existing data. -func Unmarshal(buf []byte, pb Message) error { - pb.Reset() - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// UnmarshalMerge parses the protocol buffer representation in buf and -// writes the decoded result to pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// UnmarshalMerge merges into existing data in pb. -// Most code should use Unmarshal instead. -func UnmarshalMerge(buf []byte, pb Message) error { - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// DecodeMessage reads a count-delimited message from the Buffer. -func (p *Buffer) DecodeMessage(pb Message) error { - enc, err := p.DecodeRawBytes(false) - if err != nil { - return err - } - return NewBuffer(enc).Unmarshal(pb) -} - -// DecodeGroup reads a tag-delimited group from the Buffer. -// StartGroup tag is already consumed. This function consumes -// EndGroup tag. -func (p *Buffer) DecodeGroup(pb Message) error { - b := p.buf[p.index:] - x, y := findEndGroup(b) - if x < 0 { - return io.ErrUnexpectedEOF - } - err := Unmarshal(b[:x], pb) - p.index += y - return err -} - -// Unmarshal parses the protocol buffer representation in the -// Buffer and places the decoded result in pb. If the struct -// underlying pb does not match the data in the buffer, the results can be -// unpredictable. -// -// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(newUnmarshaler); ok { - err := u.XXX_Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - // Slow workaround for messages that aren't Unmarshalers. - // This includes some hand-coded .pb.go files and - // bootstrap protos. - // TODO: fix all of those and then add Unmarshal to - // the Message interface. Then: - // The cast above and code below can be deleted. - // The old unmarshaler can be deleted. - // Clients can call Unmarshal directly (can already do that, actually). - var info InternalMessageInfo - err := info.Unmarshal(pb, p.buf[p.index:]) - p.index = len(p.buf) - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/deprecated.go b/vendor/github.com/gogo/protobuf/proto/deprecated.go deleted file mode 100644 index 35b882c09a..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/deprecated.go +++ /dev/null @@ -1,63 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2018 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import "errors" - -// Deprecated: do not use. -type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } - -// Deprecated: do not use. -func GetStats() Stats { return Stats{} } - -// Deprecated: do not use. -func MarshalMessageSet(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func UnmarshalMessageSet([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func MarshalMessageSetJSON(interface{}) ([]byte, error) { - return nil, errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func UnmarshalMessageSetJSON([]byte, interface{}) error { - return errors.New("proto: not implemented") -} - -// Deprecated: do not use. -func RegisterMessageSetType(Message, int32, string) {} diff --git a/vendor/github.com/gogo/protobuf/proto/discard.go b/vendor/github.com/gogo/protobuf/proto/discard.go deleted file mode 100644 index fe1bd7d904..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/discard.go +++ /dev/null @@ -1,350 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2017 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -type generatedDiscarder interface { - XXX_DiscardUnknown() -} - -// DiscardUnknown recursively discards all unknown fields from this message -// and all embedded messages. -// -// When unmarshaling a message with unrecognized fields, the tags and values -// of such fields are preserved in the Message. This allows a later call to -// marshal to be able to produce a message that continues to have those -// unrecognized fields. To avoid this, DiscardUnknown is used to -// explicitly clear the unknown fields after unmarshaling. -// -// For proto2 messages, the unknown fields of message extensions are only -// discarded from messages that have been accessed via GetExtension. -func DiscardUnknown(m Message) { - if m, ok := m.(generatedDiscarder); ok { - m.XXX_DiscardUnknown() - return - } - // TODO: Dynamically populate a InternalMessageInfo for legacy messages, - // but the master branch has no implementation for InternalMessageInfo, - // so it would be more work to replicate that approach. - discardLegacy(m) -} - -// DiscardUnknown recursively discards all unknown fields. -func (a *InternalMessageInfo) DiscardUnknown(m Message) { - di := atomicLoadDiscardInfo(&a.discard) - if di == nil { - di = getDiscardInfo(reflect.TypeOf(m).Elem()) - atomicStoreDiscardInfo(&a.discard, di) - } - di.discard(toPointer(&m)) -} - -type discardInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []discardFieldInfo - unrecognized field -} - -type discardFieldInfo struct { - field field // Offset of field, guaranteed to be valid - discard func(src pointer) -} - -var ( - discardInfoMap = map[reflect.Type]*discardInfo{} - discardInfoLock sync.Mutex -) - -func getDiscardInfo(t reflect.Type) *discardInfo { - discardInfoLock.Lock() - defer discardInfoLock.Unlock() - di := discardInfoMap[t] - if di == nil { - di = &discardInfo{typ: t} - discardInfoMap[t] = di - } - return di -} - -func (di *discardInfo) discard(src pointer) { - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&di.initialized) == 0 { - di.computeDiscardInfo() - } - - for _, fi := range di.fields { - sfp := src.offset(fi.field) - fi.discard(sfp) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { - // Ignore lock since DiscardUnknown is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - DiscardUnknown(m) - } - } - } - - if di.unrecognized.IsValid() { - *src.offset(di.unrecognized).toBytes() = nil - } -} - -func (di *discardInfo) computeDiscardInfo() { - di.lock.Lock() - defer di.lock.Unlock() - if di.initialized != 0 { - return - } - t := di.typ - n := t.NumField() - - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - dfi := discardFieldInfo{field: toField(&f)} - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) - case isSlice: // E.g., []*pb.T - discardInfo := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sps := src.getPointerSlice() - for _, sp := range sps { - if !sp.isNil() { - discardInfo.discard(sp) - } - } - } - default: // E.g., *pb.T - discardInfo := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sp := src.getPointer() - if !sp.isNil() { - discardInfo.discard(sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) - default: // E.g., map[K]V - if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) - dfi.discard = func(src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - DiscardUnknown(val.Interface().(Message)) - } - } - } else { - dfi.discard = func(pointer) {} // Noop - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) - default: // E.g., interface{} - // TODO: Make this faster? - dfi.discard = func(src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - DiscardUnknown(sv.Interface().(Message)) - } - } - } - } - default: - continue - } - di.fields = append(di.fields, dfi) - } - - di.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - di.unrecognized = toField(&f) - } - - atomic.StoreInt32(&di.initialized, 1) -} - -func discardLegacy(m Message) { - v := reflect.ValueOf(m) - if v.Kind() != reflect.Ptr || v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - vf := v.Field(i) - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) - case isSlice: // E.g., []*pb.T - for j := 0; j < vf.Len(); j++ { - discardLegacy(vf.Index(j).Interface().(Message)) - } - default: // E.g., *pb.T - discardLegacy(vf.Interface().(Message)) - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) - default: // E.g., map[K]V - tv := vf.Type().Elem() - if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) - for _, key := range vf.MapKeys() { - val := vf.MapIndex(key) - discardLegacy(val.Interface().(Message)) - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) - default: // E.g., test_proto.isCommunique_Union interface - if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { - vf = vf.Elem() // E.g., *test_proto.Communique_Msg - if !vf.IsNil() { - vf = vf.Elem() // E.g., test_proto.Communique_Msg - vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value - if vf.Kind() == reflect.Ptr { - discardLegacy(vf.Interface().(Message)) - } - } - } - } - } - } - - if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { - if vf.Type() != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - vf.Set(reflect.ValueOf([]byte(nil))) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(m); err == nil { - // Ignore lock since discardLegacy is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - discardLegacy(m) - } - } - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration.go b/vendor/github.com/gogo/protobuf/proto/duration.go deleted file mode 100644 index 93464c91cf..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/duration.go +++ /dev/null @@ -1,100 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements conversions between google.protobuf.Duration -// and time.Duration. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Range of a Duration in seconds, as specified in - // google/protobuf/duration.proto. This is about 10,000 years in seconds. - maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) - minSeconds = -maxSeconds -) - -// validateDuration determines whether the Duration is valid according to the -// definition in google/protobuf/duration.proto. A valid Duration -// may still be too large to fit into a time.Duration (the range of Duration -// is about 10,000 years, and the range of time.Duration is about 290). -func validateDuration(d *duration) error { - if d == nil { - return errors.New("duration: nil Duration") - } - if d.Seconds < minSeconds || d.Seconds > maxSeconds { - return fmt.Errorf("duration: %#v: seconds out of range", d) - } - if d.Nanos <= -1e9 || d.Nanos >= 1e9 { - return fmt.Errorf("duration: %#v: nanos out of range", d) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { - return fmt.Errorf("duration: %#v: seconds and nanos have different signs", d) - } - return nil -} - -// DurationFromProto converts a Duration to a time.Duration. DurationFromProto -// returns an error if the Duration is invalid or is too large to be -// represented in a time.Duration. -func durationFromProto(p *duration) (time.Duration, error) { - if err := validateDuration(p); err != nil { - return 0, err - } - d := time.Duration(p.Seconds) * time.Second - if int64(d/time.Second) != p.Seconds { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - if p.Nanos != 0 { - d += time.Duration(p.Nanos) - if (d < 0) != (p.Nanos < 0) { - return 0, fmt.Errorf("duration: %#v is out of range for time.Duration", p) - } - } - return d, nil -} - -// DurationProto converts a time.Duration to a Duration. -func durationProto(d time.Duration) *duration { - nanos := d.Nanoseconds() - secs := nanos / 1e9 - nanos -= secs * 1e9 - return &duration{ - Seconds: secs, - Nanos: int32(nanos), - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go b/vendor/github.com/gogo/protobuf/proto/duration_gogo.go deleted file mode 100644 index e748e1730e..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/duration_gogo.go +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var durationType = reflect.TypeOf((*time.Duration)(nil)).Elem() - -type duration struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *duration) Reset() { *m = duration{} } -func (*duration) ProtoMessage() {} -func (*duration) String() string { return "duration" } - -func init() { - RegisterType((*duration)(nil), "gogo.protobuf.proto.duration") -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode.go b/vendor/github.com/gogo/protobuf/proto/encode.go deleted file mode 100644 index 9581ccd304..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/encode.go +++ /dev/null @@ -1,205 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "errors" - "reflect" -) - -var ( - // errRepeatedHasNil is the error returned if Marshal is called with - // a struct with a repeated field containing a nil element. - errRepeatedHasNil = errors.New("proto: repeated field has nil element") - - // errOneofHasNil is the error returned if Marshal is called with - // a struct with a oneof field containing a nil element. - errOneofHasNil = errors.New("proto: oneof field has nil value") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") - - // ErrTooLarge is the error returned if Marshal is called with a - // message that encodes to >2GB. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") -) - -// The fundamental encoders that put bytes on the wire. -// Those that take integer types all accept uint64 and are -// therefore of type valueEncoder. - -const maxVarintBytes = 10 // maximum length of a varint - -// EncodeVarint returns the varint encoding of x. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -// Not used by the package itself, but helpful to clients -// wishing to use the same encoding. -func EncodeVarint(x uint64) []byte { - var buf [maxVarintBytes]byte - var n int - for n = 0; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return buf[0:n] -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - p.buf = append(p.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - p.buf = append(p.buf, uint8(x)) - return nil -} - -// SizeVarint returns the varint encoding size of an integer. -func SizeVarint(x uint64) int { - switch { - case x < 1<<7: - return 1 - case x < 1<<14: - return 2 - case x < 1<<21: - return 3 - case x < 1<<28: - return 4 - case x < 1<<35: - return 5 - case x < 1<<42: - return 6 - case x < 1<<49: - return 7 - case x < 1<<56: - return 8 - case x < 1<<63: - return 9 - } - return 10 -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) EncodeFixed64(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) EncodeFixed32(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -// EncodeZigzag64 writes a zigzag-encoded 64-bit integer -// to the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) EncodeZigzag64(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} - -// EncodeZigzag32 writes a zigzag-encoded 32-bit integer -// to the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) EncodeZigzag32(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) EncodeRawBytes(b []byte) error { - p.EncodeVarint(uint64(len(b))) - p.buf = append(p.buf, b...) - return nil -} - -// EncodeStringBytes writes an encoded string to the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) EncodeStringBytes(s string) error { - p.EncodeVarint(uint64(len(s))) - p.buf = append(p.buf, s...) - return nil -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// EncodeMessage writes the protocol buffer to the Buffer, -// prefixed by a varint-encoded length. -func (p *Buffer) EncodeMessage(pb Message) error { - siz := Size(pb) - sizVar := SizeVarint(uint64(siz)) - p.grow(siz + sizVar) - p.EncodeVarint(uint64(siz)) - return p.Marshal(pb) -} - -// All protocol buffer fields are nillable, but be careful. -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - return false -} diff --git a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go b/vendor/github.com/gogo/protobuf/proto/encode_gogo.go deleted file mode 100644 index 0f5fb173e9..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/encode_gogo.go +++ /dev/null @@ -1,33 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -func NewRequiredNotSetError(field string) *RequiredNotSetError { - return &RequiredNotSetError{field} -} diff --git a/vendor/github.com/gogo/protobuf/proto/equal.go b/vendor/github.com/gogo/protobuf/proto/equal.go deleted file mode 100644 index d4db5a1c14..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/equal.go +++ /dev/null @@ -1,300 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer comparison. - -package proto - -import ( - "bytes" - "log" - "reflect" - "strings" -) - -/* -Equal returns true iff protocol buffers a and b are equal. -The arguments must both be pointers to protocol buffer structs. - -Equality is defined in this way: - - Two messages are equal iff they are the same type, - corresponding fields are equal, unknown field sets - are equal, and extensions sets are equal. - - Two set scalar fields are equal iff their values are equal. - If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. If the message is defined - in a proto3 .proto file, fields are not "set"; specifically, - zero length proto3 "bytes" fields are equal (nil == {}). - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal. Note a "bytes" field, - although represented by []byte, is not a repeated field and the - rule for the scalar fields described above applies. - - Two unset fields are equal. - - Two unknown field sets are equal if their current - encoded state is equal. - - Two extension sets are equal iff they have corresponding - elements that are pairwise equal. - - Two map fields are equal iff their lengths are the same, - and they contain the same set of elements. Zero-length map - fields are equal. - - Every other combination of things are not equal. - -The return value is undefined if a and b are not protocol buffers. -*/ -func Equal(a, b Message) bool { - if a == nil || b == nil { - return a == b - } - v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) - if v1.Type() != v2.Type() { - return false - } - if v1.Kind() == reflect.Ptr { - if v1.IsNil() { - return v2.IsNil() - } - if v2.IsNil() { - return false - } - v1, v2 = v1.Elem(), v2.Elem() - } - if v1.Kind() != reflect.Struct { - return false - } - return equalStruct(v1, v2) -} - -// v1 and v2 are known to have the same type. -func equalStruct(v1, v2 reflect.Value) bool { - sprop := GetProperties(v1.Type()) - for i := 0; i < v1.NumField(); i++ { - f := v1.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - f1, f2 := v1.Field(i), v2.Field(i) - if f.Type.Kind() == reflect.Ptr { - if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { - // both unset - continue - } else if n1 != n2 { - // set/unset mismatch - return false - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2, sprop.Prop[i]) { - return false - } - } - - if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_InternalExtensions") - if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { - return false - } - } - - uf := v1.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return true - } - - u1 := uf.Bytes() - u2 := v2.FieldByName("XXX_unrecognized").Bytes() - return bytes.Equal(u1, u2) -} - -// v1 and v2 are known to have the same type. -// prop may be nil. -func equalAny(v1, v2 reflect.Value, prop *Properties) bool { - if v1.Type() == protoMessageType { - m1, _ := v1.Interface().(Message) - m2, _ := v2.Interface().(Message) - return Equal(m1, m2) - } - switch v1.Kind() { - case reflect.Bool: - return v1.Bool() == v2.Bool() - case reflect.Float32, reflect.Float64: - return v1.Float() == v2.Float() - case reflect.Int32, reflect.Int64: - return v1.Int() == v2.Int() - case reflect.Interface: - // Probably a oneof field; compare the inner values. - n1, n2 := v1.IsNil(), v2.IsNil() - if n1 || n2 { - return n1 == n2 - } - e1, e2 := v1.Elem(), v2.Elem() - if e1.Type() != e2.Type() { - return false - } - return equalAny(e1, e2, nil) - case reflect.Map: - if v1.Len() != v2.Len() { - return false - } - for _, key := range v1.MapKeys() { - val2 := v2.MapIndex(key) - if !val2.IsValid() { - // This key was not found in the second map. - return false - } - if !equalAny(v1.MapIndex(key), val2, nil) { - return false - } - } - return true - case reflect.Ptr: - // Maps may have nil values in them, so check for nil. - if v1.IsNil() && v2.IsNil() { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return equalAny(v1.Elem(), v2.Elem(), prop) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value. - if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) - } - - if v1.Len() != v2.Len() { - return false - } - for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i), prop) { - return false - } - } - return true - case reflect.String: - return v1.Interface().(string) == v2.Interface().(string) - case reflect.Struct: - return equalStruct(v1, v2) - case reflect.Uint32, reflect.Uint64: - return v1.Uint() == v2.Uint() - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to compare %v", v1) - return false -} - -// base is the struct type that the extensions are based on. -// x1 and x2 are InternalExtensions. -func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { - em1, _ := x1.extensionsRead() - em2, _ := x2.extensionsRead() - return equalExtMap(base, em1, em2) -} - -func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { - if len(em1) != len(em2) { - return false - } - - for extNum, e1 := range em1 { - e2, ok := em2[extNum] - if !ok { - return false - } - - m1, m2 := e1.value, e2.value - - if m1 == nil && m2 == nil { - // Both have only encoded form. - if bytes.Equal(e1.enc, e2.enc) { - continue - } - // The bytes are different, but the extensions might still be - // equal. We need to decode them to compare. - } - - if m1 != nil && m2 != nil { - // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - continue - } - - // At least one is encoded. To do a semantically correct comparison - // we need to unmarshal them first. - var desc *ExtensionDesc - if m := extensionMaps[base]; m != nil { - desc = m[extNum] - } - if desc == nil { - // If both have only encoded form and the bytes are the same, - // it is handled above. We get here when the bytes are different. - // We don't know how to decode it, so just compare them as byte - // slices. - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - return false - } - var err error - if m1 == nil { - m1, err = decodeExtension(e1.enc, desc) - } - if m2 == nil && err == nil { - m2, err = decodeExtension(e2.enc, desc) - } - if err != nil { - // The encoded form is invalid. - log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) - return false - } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - } - - return true -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions.go b/vendor/github.com/gogo/protobuf/proto/extensions.go deleted file mode 100644 index 341c6f57f5..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions.go +++ /dev/null @@ -1,605 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Types and routines for supporting protocol buffer extensions. - */ - -import ( - "errors" - "fmt" - "io" - "reflect" - "strconv" - "sync" -) - -// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. -var ErrMissingExtension = errors.New("proto: missing extension") - -// ExtensionRange represents a range of message extensions for a protocol buffer. -// Used in code generated by the protocol compiler. -type ExtensionRange struct { - Start, End int32 // both inclusive -} - -// extendableProto is an interface implemented by any protocol buffer generated by the current -// proto compiler that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - extensionsWrite() map[int32]Extension - extensionsRead() (map[int32]Extension, sync.Locker) -} - -// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous -// version of the proto compiler that may be extended. -type extendableProtoV1 interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} - -// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. -type extensionAdapter struct { - extendableProtoV1 -} - -func (e extensionAdapter) extensionsWrite() map[int32]Extension { - return e.ExtensionMap() -} - -func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - return e.ExtensionMap(), notLocker{} -} - -// notLocker is a sync.Locker whose Lock and Unlock methods are nops. -type notLocker struct{} - -func (n notLocker) Lock() {} -func (n notLocker) Unlock() {} - -// extendable returns the extendableProto interface for the given generated proto message. -// If the proto message has the old extension format, it returns a wrapper that implements -// the extendableProto interface. -func extendable(p interface{}) (extendableProto, error) { - switch p := p.(type) { - case extendableProto: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return p, nil - case extendableProtoV1: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return extensionAdapter{p}, nil - case extensionsBytes: - return slowExtensionAdapter{p}, nil - } - // Don't allocate a specific error containing %T: - // this is the hot path for Clone and MarshalText. - return nil, errNotExtendable -} - -var errNotExtendable = errors.New("proto: not an extendable proto.Message") - -func isNilPtr(x interface{}) bool { - v := reflect.ValueOf(x) - return v.Kind() == reflect.Ptr && v.IsNil() -} - -// XXX_InternalExtensions is an internal representation of proto extensions. -// -// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, -// thus gaining the unexported 'extensions' method, which can be called only from the proto package. -// -// The methods of XXX_InternalExtensions are not concurrency safe in general, -// but calls to logically read-only methods such as has and get may be executed concurrently. -type XXX_InternalExtensions struct { - // The struct must be indirect so that if a user inadvertently copies a - // generated message and its embedded XXX_InternalExtensions, they - // avoid the mayhem of a copied mutex. - // - // The mutex serializes all logically read-only operations to p.extensionMap. - // It is up to the client to ensure that write operations to p.extensionMap are - // mutually exclusive with other accesses. - p *struct { - mu sync.Mutex - extensionMap map[int32]Extension - } -} - -// extensionsWrite returns the extension map, creating it on first use. -func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { - if e.p == nil { - e.p = new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }) - e.p.extensionMap = make(map[int32]Extension) - } - return e.p.extensionMap -} - -// extensionsRead returns the extensions map for read-only use. It may be nil. -// The caller must hold the returned mutex's lock when accessing Elements within the map. -func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { - if e.p == nil { - return nil, nil - } - return e.p.extensionMap, &e.p.mu -} - -// ExtensionDesc represents an extension specification. -// Used in generated code from the protocol compiler. -type ExtensionDesc struct { - ExtendedType Message // nil pointer to the type that is being extended - ExtensionType interface{} // nil pointer to the extension type - Field int32 // field number - Name string // fully-qualified name of extension, for text formatting - Tag string // protobuf tag style - Filename string // name of the file in which the extension is defined -} - -func (ed *ExtensionDesc) repeated() bool { - t := reflect.TypeOf(ed.ExtensionType) - return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 -} - -// Extension represents an extension in a message. -type Extension struct { - // When an extension is stored in a message using SetExtension - // only desc and value are set. When the message is marshaled - // enc will be set to the encoded form of the message. - // - // When a message is unmarshaled and contains extensions, each - // extension will have only enc set. When such an extension is - // accessed using GetExtension (or GetExtensions) desc and value - // will be set. - desc *ExtensionDesc - value interface{} - enc []byte -} - -// SetRawExtension is for testing only. -func SetRawExtension(base Message, id int32, b []byte) { - if ebase, ok := base.(extensionsBytes); ok { - clearExtension(base, id) - ext := ebase.GetExtensions() - *ext = append(*ext, b...) - return - } - epb, err := extendable(base) - if err != nil { - return - } - extmap := epb.extensionsWrite() - extmap[id] = Extension{enc: b} -} - -// isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extendableProto, field int32) bool { - for _, er := range pb.ExtensionRangeArray() { - if er.Start <= field && field <= er.End { - return true - } - } - return false -} - -// checkExtensionTypes checks that the given extension is valid for pb. -func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { - var pbi interface{} = pb - // Check the extended type. - if ea, ok := pbi.(extensionAdapter); ok { - pbi = ea.extendableProtoV1 - } - if ea, ok := pbi.(slowExtensionAdapter); ok { - pbi = ea.extensionsBytes - } - if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { - return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) - } - // Check the range. - if !isExtensionField(pb, extension.Field) { - return errors.New("proto: bad extension number; not in declared ranges") - } - return nil -} - -// extPropKey is sufficient to uniquely identify an extension. -type extPropKey struct { - base reflect.Type - field int32 -} - -var extProp = struct { - sync.RWMutex - m map[extPropKey]*Properties -}{ - m: make(map[extPropKey]*Properties), -} - -func extensionProperties(ed *ExtensionDesc) *Properties { - key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} - - extProp.RLock() - if prop, ok := extProp.m[key]; ok { - extProp.RUnlock() - return prop - } - extProp.RUnlock() - - extProp.Lock() - defer extProp.Unlock() - // Check again. - if prop, ok := extProp.m[key]; ok { - return prop - } - - prop := new(Properties) - prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) - extProp.m[key] = prop - return prop -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb Message, extension *ExtensionDesc) bool { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - buf := *ext - o := 0 - for o < len(buf) { - tag, n := DecodeVarint(buf[o:]) - fieldNum := int32(tag >> 3) - if int32(fieldNum) == extension.Field { - return true - } - wireType := int(tag & 0x7) - o += n - l, err := size(buf[o:], wireType) - if err != nil { - return false - } - o += l - } - return false - } - // TODO: Check types, field numbers, etc.? - epb, err := extendable(pb) - if err != nil { - return false - } - extmap, mu := epb.extensionsRead() - if extmap == nil { - return false - } - mu.Lock() - _, ok := extmap[extension.Field] - mu.Unlock() - return ok -} - -// ClearExtension removes the given extension from pb. -func ClearExtension(pb Message, extension *ExtensionDesc) { - clearExtension(pb, extension.Field) -} - -func clearExtension(pb Message, fieldNum int32) { - if epb, ok := pb.(extensionsBytes); ok { - offset := 0 - for offset != -1 { - offset = deleteExtension(epb, fieldNum, offset) - } - return - } - epb, err := extendable(pb) - if err != nil { - return - } - // TODO: Check types, field numbers, etc.? - extmap := epb.extensionsWrite() - delete(extmap, fieldNum) -} - -// GetExtension retrieves a proto2 extended field from pb. -// -// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), -// then GetExtension parses the encoded field and returns a Go value of the specified type. -// If the field is not present, then the default value is returned (if one is specified), -// otherwise ErrMissingExtension is reported. -// -// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), -// then GetExtension returns the raw encoded bytes of the field extension. -func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - return decodeExtensionFromBytes(extension, *ext) - } - - epb, err := extendable(pb) - if err != nil { - return nil, err - } - - if extension.ExtendedType != nil { - // can only check type if this is a complete descriptor - if cerr := checkExtensionTypes(epb, extension); cerr != nil { - return nil, cerr - } - } - - emap, mu := epb.extensionsRead() - if emap == nil { - return defaultExtensionValue(extension) - } - mu.Lock() - defer mu.Unlock() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return e.value, nil - } - - if extension.ExtensionType == nil { - // incomplete descriptor - return e.enc, nil - } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err - } - - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = v - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return e.value, nil -} - -// defaultExtensionValue returns the default value for extension. -// If no default for an extension is defined ErrMissingExtension is returned. -func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { - if extension.ExtensionType == nil { - // incomplete descriptor, so no default - return nil, ErrMissingExtension - } - - t := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - - sf, _, err := fieldDefault(t, props) - if err != nil { - return nil, err - } - - if sf == nil || sf.value == nil { - // There is no default value. - return nil, ErrMissingExtension - } - - if t.Kind() != reflect.Ptr { - // We do not need to return a Ptr, we can directly return sf.value. - return sf.value, nil - } - - // We need to return an interface{} that is a pointer to sf.value. - value := reflect.New(t).Elem() - value.Set(reflect.New(value.Type().Elem())) - if sf.kind == reflect.Int32 { - // We may have an int32 or an enum, but the underlying data is int32. - // Since we can't set an int32 into a non int32 reflect.value directly - // set it as a int32. - value.Elem().SetInt(int64(sf.value.(int32))) - } else { - value.Elem().Set(reflect.ValueOf(sf.value)) - } - return value.Interface(), nil -} - -// decodeExtension decodes an extension encoded in b. -func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { - t := reflect.TypeOf(extension.ExtensionType) - unmarshal := typeUnmarshaler(t, extension.Tag) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate space to store the pointer/slice. - value := reflect.New(t).Elem() - - var err error - for { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - wire := int(x) & 7 - - b, err = unmarshal(b, valToPointer(value.Addr()), wire) - if err != nil { - return nil, err - } - - if len(b) == 0 { - break - } - } - return value.Interface(), nil -} - -// GetExtensions returns a slice of the extensions present in pb that are also listed in es. -// The returned slice has the same length as es; missing extensions will appear as nil elements. -func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - extensions = make([]interface{}, len(es)) - for i, e := range es { - extensions[i], err = GetExtension(epb, e) - if err == ErrMissingExtension { - err = nil - } - if err != nil { - return - } - } - return -} - -// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. -// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing -// just the Field field, which defines the extension's field number. -func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - registeredExtensions := RegisteredExtensions(pb) - - emap, mu := epb.extensionsRead() - if emap == nil { - return nil, nil - } - mu.Lock() - defer mu.Unlock() - extensions := make([]*ExtensionDesc, 0, len(emap)) - for extid, e := range emap { - desc := e.desc - if desc == nil { - desc = registeredExtensions[extid] - if desc == nil { - desc = &ExtensionDesc{Field: extid} - } - } - - extensions = append(extensions, desc) - } - return extensions, nil -} - -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { - if epb, ok := pb.(extensionsBytes); ok { - ClearExtension(pb, extension) - newb, err := encodeExtension(extension, value) - if err != nil { - return err - } - bb := epb.GetExtensions() - *bb = append(*bb, newb...) - return nil - } - epb, err := extendable(pb) - if err != nil { - return err - } - if err := checkExtensionTypes(epb, extension); err != nil { - return err - } - typ := reflect.TypeOf(extension.ExtensionType) - if typ != reflect.TypeOf(value) { - return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) - } - // nil extension values need to be caught early, because the - // encoder can't distinguish an ErrNil due to a nil extension - // from an ErrNil due to a missing field. Extensions are - // always optional, so the encoder would just swallow the error - // and drop all the extensions from the encoded message. - if reflect.ValueOf(value).IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) - } - - extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: value} - return nil -} - -// ClearAllExtensions clears all extensions from pb. -func ClearAllExtensions(pb Message) { - if epb, doki := pb.(extensionsBytes); doki { - ext := epb.GetExtensions() - *ext = []byte{} - return - } - epb, err := extendable(pb) - if err != nil { - return - } - m := epb.extensionsWrite() - for k := range m { - delete(m, k) - } -} - -// A global registry of extensions. -// The generated code will register the generated descriptors by calling RegisterExtension. - -var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) - -// RegisterExtension is called from the generated code. -func RegisterExtension(desc *ExtensionDesc) { - st := reflect.TypeOf(desc.ExtendedType).Elem() - m := extensionMaps[st] - if m == nil { - m = make(map[int32]*ExtensionDesc) - extensionMaps[st] = m - } - if _, ok := m[desc.Field]; ok { - panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) - } - m[desc.Field] = desc -} - -// RegisteredExtensions returns a map of the registered extensions of a -// protocol buffer struct, indexed by the extension number. -// The argument pb should be a nil pointer to the struct type. -func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { - return extensionMaps[reflect.TypeOf(pb).Elem()] -} diff --git a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go b/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go deleted file mode 100644 index 6f1ae120ec..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/extensions_gogo.go +++ /dev/null @@ -1,389 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "bytes" - "errors" - "fmt" - "io" - "reflect" - "sort" - "strings" - "sync" -) - -type extensionsBytes interface { - Message - ExtensionRangeArray() []ExtensionRange - GetExtensions() *[]byte -} - -type slowExtensionAdapter struct { - extensionsBytes -} - -func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension { - panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.") -} - -func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - b := s.GetExtensions() - m, err := BytesToExtensionsMap(*b) - if err != nil { - panic(err) - } - return m, notLocker{} -} - -func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool { - if reflect.ValueOf(pb).IsNil() { - return ifnotset - } - value, err := GetExtension(pb, extension) - if err != nil { - return ifnotset - } - if value == nil { - return ifnotset - } - if value.(*bool) == nil { - return ifnotset - } - return *(value.(*bool)) -} - -func (this *Extension) Equal(that *Extension) bool { - if err := this.Encode(); err != nil { - return false - } - if err := that.Encode(); err != nil { - return false - } - return bytes.Equal(this.enc, that.enc) -} - -func (this *Extension) Compare(that *Extension) int { - if err := this.Encode(); err != nil { - return 1 - } - if err := that.Encode(); err != nil { - return -1 - } - return bytes.Compare(this.enc, that.enc) -} - -func SizeOfInternalExtension(m extendableProto) (n int) { - info := getMarshalInfo(reflect.TypeOf(m)) - return info.sizeV1Extensions(m.extensionsWrite()) -} - -type sortableMapElem struct { - field int32 - ext Extension -} - -func newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions { - s := make(sortableExtensions, 0, len(m)) - for k, v := range m { - s = append(s, &sortableMapElem{field: k, ext: v}) - } - return s -} - -type sortableExtensions []*sortableMapElem - -func (this sortableExtensions) Len() int { return len(this) } - -func (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] } - -func (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field } - -func (this sortableExtensions) String() string { - sort.Sort(this) - ss := make([]string, len(this)) - for i := range this { - ss[i] = fmt.Sprintf("%d: %v", this[i].field, this[i].ext) - } - return "map[" + strings.Join(ss, ",") + "]" -} - -func StringFromInternalExtension(m extendableProto) string { - return StringFromExtensionsMap(m.extensionsWrite()) -} - -func StringFromExtensionsMap(m map[int32]Extension) string { - return newSortableExtensionsFromMap(m).String() -} - -func StringFromExtensionsBytes(ext []byte) string { - m, err := BytesToExtensionsMap(ext) - if err != nil { - panic(err) - } - return StringFromExtensionsMap(m) -} - -func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) { - return EncodeExtensionMap(m.extensionsWrite(), data) -} - -func EncodeInternalExtensionBackwards(m extendableProto, data []byte) (n int, err error) { - return EncodeExtensionMapBackwards(m.extensionsWrite(), data) -} - -func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) { - o := 0 - for _, e := range m { - if err := e.Encode(); err != nil { - return 0, err - } - n := copy(data[o:], e.enc) - if n != len(e.enc) { - return 0, io.ErrShortBuffer - } - o += n - } - return o, nil -} - -func EncodeExtensionMapBackwards(m map[int32]Extension, data []byte) (n int, err error) { - o := 0 - end := len(data) - for _, e := range m { - if err := e.Encode(); err != nil { - return 0, err - } - n := copy(data[end-len(e.enc):], e.enc) - if n != len(e.enc) { - return 0, io.ErrShortBuffer - } - end -= n - o += n - } - return o, nil -} - -func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) { - e := m[id] - if err := e.Encode(); err != nil { - return nil, err - } - return e.enc, nil -} - -func size(buf []byte, wire int) (int, error) { - switch wire { - case WireVarint: - _, n := DecodeVarint(buf) - return n, nil - case WireFixed64: - return 8, nil - case WireBytes: - v, n := DecodeVarint(buf) - return int(v) + n, nil - case WireFixed32: - return 4, nil - case WireStartGroup: - offset := 0 - for { - u, n := DecodeVarint(buf[offset:]) - fwire := int(u & 0x7) - offset += n - if fwire == WireEndGroup { - return offset, nil - } - s, err := size(buf[offset:], wire) - if err != nil { - return 0, err - } - offset += s - } - } - return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", wire) -} - -func BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) { - m := make(map[int32]Extension) - i := 0 - for i < len(buf) { - tag, n := DecodeVarint(buf[i:]) - if n <= 0 { - return nil, fmt.Errorf("unable to decode varint") - } - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - l, err := size(buf[i+n:], wireType) - if err != nil { - return nil, err - } - end := i + int(l) + n - m[int32(fieldNum)] = Extension{enc: buf[i:end]} - i = end - } - return m, nil -} - -func NewExtension(e []byte) Extension { - ee := Extension{enc: make([]byte, len(e))} - copy(ee.enc, e) - return ee -} - -func AppendExtension(e Message, tag int32, buf []byte) { - if ee, eok := e.(extensionsBytes); eok { - ext := ee.GetExtensions() - *ext = append(*ext, buf...) - return - } - if ee, eok := e.(extendableProto); eok { - m := ee.extensionsWrite() - ext := m[int32(tag)] // may be missing - ext.enc = append(ext.enc, buf...) - m[int32(tag)] = ext - } -} - -func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) { - u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType)) - ei := u.getExtElemInfo(extension) - v := value - p := toAddrPointer(&v, ei.isptr) - siz := ei.sizer(p, SizeVarint(ei.wiretag)) - buf := make([]byte, 0, siz) - return ei.marshaler(buf, p, ei.wiretag, false) -} - -func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) { - o := 0 - for o < len(buf) { - tag, n := DecodeVarint((buf)[o:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - if o+n > len(buf) { - return nil, fmt.Errorf("unable to decode extension") - } - l, err := size((buf)[o+n:], wireType) - if err != nil { - return nil, err - } - if int32(fieldNum) == extension.Field { - if o+n+l > len(buf) { - return nil, fmt.Errorf("unable to decode extension") - } - v, err := decodeExtension((buf)[o:o+n+l], extension) - if err != nil { - return nil, err - } - return v, nil - } - o += n + l - } - return defaultExtensionValue(extension) -} - -func (this *Extension) Encode() error { - if this.enc == nil { - var err error - this.enc, err = encodeExtension(this.desc, this.value) - if err != nil { - return err - } - } - return nil -} - -func (this Extension) GoString() string { - if err := this.Encode(); err != nil { - return fmt.Sprintf("error encoding extension: %v", err) - } - return fmt.Sprintf("proto.NewExtension(%#v)", this.enc) -} - -func SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return errors.New("proto: bad extension number; not in declared ranges") - } - return SetExtension(pb, desc, value) -} - -func GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) { - typ := reflect.TypeOf(pb).Elem() - ext, ok := extensionMaps[typ] - if !ok { - return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", typ.String()) - } - desc, ok := ext[fieldNum] - if !ok { - return nil, fmt.Errorf("unregistered field number %d", fieldNum) - } - return GetExtension(pb, desc) -} - -func NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions { - x := &XXX_InternalExtensions{ - p: new(struct { - mu sync.Mutex - extensionMap map[int32]Extension - }), - } - x.p.extensionMap = m - return *x -} - -func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension { - pb := extendable.(extendableProto) - return pb.extensionsWrite() -} - -func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int { - ext := pb.GetExtensions() - for offset < len(*ext) { - tag, n1 := DecodeVarint((*ext)[offset:]) - fieldNum := int32(tag >> 3) - wireType := int(tag & 0x7) - n2, err := size((*ext)[offset+n1:], wireType) - if err != nil { - panic(err) - } - newOffset := offset + n1 + n2 - if fieldNum == theFieldNum { - *ext = append((*ext)[:offset], (*ext)[newOffset:]...) - return offset - } - offset = newOffset - } - return -1 -} diff --git a/vendor/github.com/gogo/protobuf/proto/lib.go b/vendor/github.com/gogo/protobuf/proto/lib.go deleted file mode 100644 index 80db1c155b..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/lib.go +++ /dev/null @@ -1,973 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package proto converts data structures to and from the wire format of -protocol buffers. It works in concert with the Go source code generated -for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed by the enclosing message's name, or by the - enum's type name if it is a top-level enum. Enum types have a String - method, and a Enum method to assist in message construction. - - Nested messages, groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Enum types do not get an Enum method. - -The simplest way to describe this is to see an example. -Given file test.proto, containing - - package example; - - enum FOO { X = 17; } - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - oneof union { - int32 number = 6; - string name = 7; - } - } - -The resulting file, test.pb.go, is: - - package example - - import proto "github.com/gogo/protobuf/proto" - import math "math" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) - } - func (x *FOO) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FOO_value, data) - if err != nil { - return err - } - *x = FOO(value) - return nil - } - - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - // Types that are valid to be assigned to Union: - // *Test_Number - // *Test_Name - Union isTest_Union `protobuf_oneof:"union"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - - type isTest_Union interface { - isTest_Union() - } - - type Test_Number struct { - Number int32 `protobuf:"varint,6,opt,name=number"` - } - type Test_Name struct { - Name string `protobuf:"bytes,7,opt,name=name"` - } - - func (*Test_Number) isTest_Union() {} - func (*Test_Name) isTest_Union() {} - - func (m *Test) GetUnion() isTest_Union { - if m != nil { - return m.Union - } - return nil - } - const Default_Test_Type int32 = 77 - - func (m *Test) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" - } - - func (m *Test) GetType() int32 { - if m != nil && m.Type != nil { - return *m.Type - } - return Default_Test_Type - } - - func (m *Test) GetOptionalgroup() *Test_OptionalGroup { - if m != nil { - return m.Optionalgroup - } - return nil - } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - } - func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } - func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - - func (m *Test_OptionalGroup) GetRequiredField() string { - if m != nil && m.RequiredField != nil { - return *m.RequiredField - } - return "" - } - - func (m *Test) GetNumber() int32 { - if x, ok := m.GetUnion().(*Test_Number); ok { - return x.Number - } - return 0 - } - - func (m *Test) GetName() string { - if x, ok := m.GetUnion().(*Test_Name); ok { - return x.Name - } - return "" - } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } - -To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/gogo/protobuf/proto" - pb "./example.pb" - ) - - func main() { - test := &pb.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - Union: &pb.Test_Name{"fred"}, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &pb.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // Use a type switch to determine which oneof was set. - switch u := test.Union.(type) { - case *pb.Test_Number: // u.Number contains the number. - case *pb.Test_Name: // u.Name contains the string. - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "sync" -) - -// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. -// Marshal reports this when a required field is not initialized. -// Unmarshal reports this when a required field is missing from the wire data. -type RequiredNotSetError struct{ field string } - -func (e *RequiredNotSetError) Error() string { - if e.field == "" { - return fmt.Sprintf("proto: required field not set") - } - return fmt.Sprintf("proto: required field %q not set", e.field) -} -func (e *RequiredNotSetError) RequiredNotSet() bool { - return true -} - -type invalidUTF8Error struct{ field string } - -func (e *invalidUTF8Error) Error() string { - if e.field == "" { - return "proto: invalid UTF-8 detected" - } - return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) -} -func (e *invalidUTF8Error) InvalidUTF8() bool { - return true -} - -// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. -// This error should not be exposed to the external API as such errors should -// be recreated with the field information. -var errInvalidUTF8 = &invalidUTF8Error{} - -// isNonFatal reports whether the error is either a RequiredNotSet error -// or a InvalidUTF8 error. -func isNonFatal(err error) bool { - if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { - return true - } - if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { - return true - } - return false -} - -type nonFatal struct{ E error } - -// Merge merges err into nf and reports whether it was successful. -// Otherwise it returns false for any fatal non-nil errors. -func (nf *nonFatal) Merge(err error) (ok bool) { - if err == nil { - return true // not an error - } - if !isNonFatal(err) { - return false // fatal error - } - if nf.E == nil { - nf.E = err // store first instance of non-fatal error - } - return true -} - -// Message is implemented by generated protocol buffer messages. -type Message interface { - Reset() - String() string - ProtoMessage() -} - -// A Buffer is a buffer manager for marshaling and unmarshaling -// protocol buffers. It may be reused between invocations to -// reduce memory usage. It is not necessary to use a Buffer; -// the global functions Marshal and Unmarshal create a -// temporary Buffer and are fine for most applications. -type Buffer struct { - buf []byte // encode/decode byte stream - index int // read point - - deterministic bool -} - -// NewBuffer allocates a new Buffer and initializes its internal data to -// the contents of the argument slice. -func NewBuffer(e []byte) *Buffer { - return &Buffer{buf: e} -} - -// Reset resets the Buffer, ready for marshaling a new protocol buffer. -func (p *Buffer) Reset() { - p.buf = p.buf[0:0] // for reading/writing - p.index = 0 // for reading -} - -// SetBuf replaces the internal buffer with the slice, -// ready for unmarshaling the contents of the slice. -func (p *Buffer) SetBuf(s []byte) { - p.buf = s - p.index = 0 -} - -// Bytes returns the contents of the Buffer. -func (p *Buffer) Bytes() []byte { return p.buf } - -// SetDeterministic sets whether to use deterministic serialization. -// -// Deterministic serialization guarantees that for a given binary, equal -// messages will always be serialized to the same bytes. This implies: -// -// - Repeated serialization of a message will return the same bytes. -// - Different processes of the same binary (which may be executing on -// different machines) will serialize equal messages to the same bytes. -// -// Note that the deterministic serialization is NOT canonical across -// languages. It is not guaranteed to remain stable over time. It is unstable -// across different builds with schema changes due to unknown fields. -// Users who need canonical serialization (e.g., persistent storage in a -// canonical form, fingerprinting, etc.) should define their own -// canonicalization specification and implement their own serializer rather -// than relying on this API. -// -// If deterministic serialization is requested, map entries will be sorted -// by keys in lexographical order. This is an implementation detail and -// subject to change. -func (p *Buffer) SetDeterministic(deterministic bool) { - p.deterministic = deterministic -} - -/* - * Helper routines for simplifying the creation of optional fields of basic type. - */ - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - return &v -} - -// Int32 is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it. -func Int32(v int32) *int32 { - return &v -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int32 { - p := new(int32) - *p = int32(v) - return p -} - -// Int64 is a helper routine that allocates a new int64 value -// to store v and returns a pointer to it. -func Int64(v int64) *int64 { - return &v -} - -// Float32 is a helper routine that allocates a new float32 value -// to store v and returns a pointer to it. -func Float32(v float32) *float32 { - return &v -} - -// Float64 is a helper routine that allocates a new float64 value -// to store v and returns a pointer to it. -func Float64(v float64) *float64 { - return &v -} - -// Uint32 is a helper routine that allocates a new uint32 value -// to store v and returns a pointer to it. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint64 is a helper routine that allocates a new uint64 value -// to store v and returns a pointer to it. -func Uint64(v uint64) *uint64 { - return &v -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - return &v -} - -// EnumName is a helper function to simplify printing protocol buffer enums -// by name. Given an enum map and a value, it returns a useful string. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// UnmarshalJSONEnum is a helper function to simplify recovering enum int values -// from their JSON-encoded representation. Given a map from the enum's symbolic -// names to its int values, and a byte buffer containing the JSON-encoded -// value, it returns an int32 that can be cast to the enum type by the caller. -// -// The function can deal with both JSON representations, numeric and symbolic. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// DebugPrint dumps the encoded data in b in a debugging format with a header -// including the string s. Used in testing but made available for general debugging. -func (p *Buffer) DebugPrint(s string, b []byte) { - var u uint64 - - obuf := p.buf - sindex := p.index - p.buf = b - p.index = 0 - depth := 0 - - fmt.Printf("\n--- %s ---\n", s) - -out: - for { - for i := 0; i < depth; i++ { - fmt.Print(" ") - } - - index := p.index - if index == len(p.buf) { - break - } - - op, err := p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: fetching op err %v\n", index, err) - break out - } - tag := op >> 3 - wire := op & 7 - - switch wire { - default: - fmt.Printf("%3d: t=%3d unknown wire=%d\n", - index, tag, wire) - break out - - case WireBytes: - var r []byte - - r, err = p.DecodeRawBytes(false) - if err != nil { - break out - } - fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) - if len(r) <= 6 { - for i := 0; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } else { - for i := 0; i < 3; i++ { - fmt.Printf(" %.2x", r[i]) - } - fmt.Printf(" ..") - for i := len(r) - 3; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } - fmt.Printf("\n") - - case WireFixed32: - u, err = p.DecodeFixed32() - if err != nil { - fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) - - case WireFixed64: - u, err = p.DecodeFixed64() - if err != nil { - fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - - case WireVarint: - u, err = p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) - - case WireStartGroup: - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - fmt.Printf("%3d: t=%3d end\n", index, tag) - } - } - - if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) - } - fmt.Printf("\n") - - p.buf = obuf - p.index = sindex -} - -// SetDefaults sets unset protocol buffer fields to their default values. -// It only modifies fields that are both unset and have defined defaults. -// It recursively sets default values in any non-nil sub-messages. -func SetDefaults(pb Message) { - setDefaults(reflect.ValueOf(pb), true, false) -} - -// v is a struct. -func setDefaults(v reflect.Value, recur, zeros bool) { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - defaultMu.RLock() - dm, ok := defaults[v.Type()] - defaultMu.RUnlock() - if !ok { - dm = buildDefaultMessage(v.Type()) - defaultMu.Lock() - defaults[v.Type()] = dm - defaultMu.Unlock() - } - - for _, sf := range dm.scalars { - f := v.Field(sf.index) - if !f.IsNil() { - // field already set - continue - } - dv := sf.value - if dv == nil && !zeros { - // no explicit default, and don't want to set zeros - continue - } - fptr := f.Addr().Interface() // **T - // TODO: Consider batching the allocations we do here. - switch sf.kind { - case reflect.Bool: - b := new(bool) - if dv != nil { - *b = dv.(bool) - } - *(fptr.(**bool)) = b - case reflect.Float32: - f := new(float32) - if dv != nil { - *f = dv.(float32) - } - *(fptr.(**float32)) = f - case reflect.Float64: - f := new(float64) - if dv != nil { - *f = dv.(float64) - } - *(fptr.(**float64)) = f - case reflect.Int32: - // might be an enum - if ft := f.Type(); ft != int32PtrType { - // enum - f.Set(reflect.New(ft.Elem())) - if dv != nil { - f.Elem().SetInt(int64(dv.(int32))) - } - } else { - // int32 field - i := new(int32) - if dv != nil { - *i = dv.(int32) - } - *(fptr.(**int32)) = i - } - case reflect.Int64: - i := new(int64) - if dv != nil { - *i = dv.(int64) - } - *(fptr.(**int64)) = i - case reflect.String: - s := new(string) - if dv != nil { - *s = dv.(string) - } - *(fptr.(**string)) = s - case reflect.Uint8: - // exceptional case: []byte - var b []byte - if dv != nil { - db := dv.([]byte) - b = make([]byte, len(db)) - copy(b, db) - } else { - b = []byte{} - } - *(fptr.(*[]byte)) = b - case reflect.Uint32: - u := new(uint32) - if dv != nil { - *u = dv.(uint32) - } - *(fptr.(**uint32)) = u - case reflect.Uint64: - u := new(uint64) - if dv != nil { - *u = dv.(uint64) - } - *(fptr.(**uint64)) = u - default: - log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) - } - } - - for _, ni := range dm.nested { - f := v.Field(ni) - // f is *T or T or []*T or []T - switch f.Kind() { - case reflect.Struct: - setDefaults(f, recur, zeros) - - case reflect.Ptr: - if f.IsNil() { - continue - } - setDefaults(f, recur, zeros) - - case reflect.Slice: - for i := 0; i < f.Len(); i++ { - e := f.Index(i) - if e.Kind() == reflect.Ptr && e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - - case reflect.Map: - for _, k := range f.MapKeys() { - e := f.MapIndex(k) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - } - } -} - -var ( - // defaults maps a protocol buffer struct type to a slice of the fields, - // with its scalar fields set to their proto-declared non-zero default values. - defaultMu sync.RWMutex - defaults = make(map[reflect.Type]defaultMessage) - - int32PtrType = reflect.TypeOf((*int32)(nil)) -) - -// defaultMessage represents information about the default values of a message. -type defaultMessage struct { - scalars []scalarField - nested []int // struct field index of nested messages -} - -type scalarField struct { - index int // struct field index - kind reflect.Kind // element type (the T in *T or []T) - value interface{} // the proto-declared default value, or nil -} - -// t is a struct type. -func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { - sprop := GetProperties(t) - for _, prop := range sprop.Prop { - fi, ok := sprop.decoderTags.get(prop.Tag) - if !ok { - // XXX_unrecognized - continue - } - ft := t.Field(fi).Type - - sf, nested, err := fieldDefault(ft, prop) - switch { - case err != nil: - log.Print(err) - case nested: - dm.nested = append(dm.nested, fi) - case sf != nil: - sf.index = fi - dm.scalars = append(dm.scalars, *sf) - } - } - - return dm -} - -// fieldDefault returns the scalarField for field type ft. -// sf will be nil if the field can not have a default. -// nestedMessage will be true if this is a nested message. -// Note that sf.index is not set on return. -func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { - var canHaveDefault bool - switch ft.Kind() { - case reflect.Struct: - nestedMessage = true // non-nullable - - case reflect.Ptr: - if ft.Elem().Kind() == reflect.Struct { - nestedMessage = true - } else { - canHaveDefault = true // proto2 scalar field - } - - case reflect.Slice: - switch ft.Elem().Kind() { - case reflect.Ptr, reflect.Struct: - nestedMessage = true // repeated message - case reflect.Uint8: - canHaveDefault = true // bytes field - } - - case reflect.Map: - if ft.Elem().Kind() == reflect.Ptr { - nestedMessage = true // map with message values - } - } - - if !canHaveDefault { - if nestedMessage { - return nil, true, nil - } - return nil, false, nil - } - - // We now know that ft is a pointer or slice. - sf = &scalarField{kind: ft.Elem().Kind()} - - // scalar fields without defaults - if !prop.HasDefault { - return sf, false, nil - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) - } - sf.value = x - default: - return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) - } - - return sf, false, nil -} - -// mapKeys returns a sort.Interface to be used for sorting the map keys. -// Map fields may have key types of non-float scalars, strings and enums. -func mapKeys(vs []reflect.Value) sort.Interface { - s := mapKeySorter{vs: vs} - - // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. - if len(vs) == 0 { - return s - } - switch vs[0].Kind() { - case reflect.Int32, reflect.Int64: - s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } - case reflect.Uint32, reflect.Uint64: - s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } - case reflect.Bool: - s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true - case reflect.String: - s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } - default: - panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) - } - - return s -} - -type mapKeySorter struct { - vs []reflect.Value - less func(a, b reflect.Value) bool -} - -func (s mapKeySorter) Len() int { return len(s.vs) } -func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } -func (s mapKeySorter) Less(i, j int) bool { - return s.less(s.vs[i], s.vs[j]) -} - -// isProto3Zero reports whether v is a zero proto3 value. -func isProto3Zero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint32, reflect.Uint64: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.String: - return v.String() == "" - } - return false -} - -const ( - // ProtoPackageIsVersion3 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion3 = true - - // ProtoPackageIsVersion2 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion2 = true - - // ProtoPackageIsVersion1 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - GoGoProtoPackageIsVersion1 = true -) - -// InternalMessageInfo is a type used internally by generated .pb.go files. -// This type is not intended to be used by non-generated code. -// This type is not subject to any compatibility guarantee. -type InternalMessageInfo struct { - marshal *marshalInfo - unmarshal *unmarshalInfo - merge *mergeInfo - discard *discardInfo -} diff --git a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go b/vendor/github.com/gogo/protobuf/proto/lib_gogo.go deleted file mode 100644 index b3aa39190a..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/lib_gogo.go +++ /dev/null @@ -1,50 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "encoding/json" - "strconv" -) - -type Sizer interface { - Size() int -} - -type ProtoSizer interface { - ProtoSize() int -} - -func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) { - s, ok := m[value] - if !ok { - s = strconv.Itoa(int(value)) - } - return json.Marshal(s) -} diff --git a/vendor/github.com/gogo/protobuf/proto/message_set.go b/vendor/github.com/gogo/protobuf/proto/message_set.go deleted file mode 100644 index f48a756761..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/message_set.go +++ /dev/null @@ -1,181 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Support for message sets. - */ - -import ( - "errors" -) - -// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. -// A message type ID is required for storing a protocol buffer in a message set. -var errNoMessageTypeID = errors.New("proto does not have a message type ID") - -// The first two types (_MessageSet_Item and messageSet) -// model what the protocol compiler produces for the following protocol message: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } -// That is the MessageSet wire format. We can't use a proto to generate these -// because that would introduce a circular dependency between it and this package. - -type _MessageSet_Item struct { - TypeId *int32 `protobuf:"varint,2,req,name=type_id"` - Message []byte `protobuf:"bytes,3,req,name=message"` -} - -type messageSet struct { - Item []*_MessageSet_Item `protobuf:"group,1,rep"` - XXX_unrecognized []byte - // TODO: caching? -} - -// Make sure messageSet is a Message. -var _ Message = (*messageSet)(nil) - -// messageTypeIder is an interface satisfied by a protocol buffer type -// that may be stored in a MessageSet. -type messageTypeIder interface { - MessageTypeId() int32 -} - -func (ms *messageSet) find(pb Message) *_MessageSet_Item { - mti, ok := pb.(messageTypeIder) - if !ok { - return nil - } - id := mti.MessageTypeId() - for _, item := range ms.Item { - if *item.TypeId == id { - return item - } - } - return nil -} - -func (ms *messageSet) Has(pb Message) bool { - return ms.find(pb) != nil -} - -func (ms *messageSet) Unmarshal(pb Message) error { - if item := ms.find(pb); item != nil { - return Unmarshal(item.Message, pb) - } - if _, ok := pb.(messageTypeIder); !ok { - return errNoMessageTypeID - } - return nil // TODO: return error instead? -} - -func (ms *messageSet) Marshal(pb Message) error { - msg, err := Marshal(pb) - if err != nil { - return err - } - if item := ms.find(pb); item != nil { - // reuse existing item - item.Message = msg - return nil - } - - mti, ok := pb.(messageTypeIder) - if !ok { - return errNoMessageTypeID - } - - mtid := mti.MessageTypeId() - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: &mtid, - Message: msg, - }) - return nil -} - -func (ms *messageSet) Reset() { *ms = messageSet{} } -func (ms *messageSet) String() string { return CompactTextString(ms) } -func (*messageSet) ProtoMessage() {} - -// Support for the message_set_wire_format message option. - -func skipVarint(buf []byte) []byte { - i := 0 - for ; buf[i]&0x80 != 0; i++ { - } - return buf[i+1:] -} - -// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func unmarshalMessageSet(buf []byte, exts interface{}) error { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m = exts.extensionsWrite() - case map[int32]Extension: - m = exts - default: - return errors.New("proto: not an extension map") - } - - ms := new(messageSet) - if err := Unmarshal(buf, ms); err != nil { - return err - } - for _, item := range ms.Item { - id := *item.TypeId - msg := item.Message - - // Restore wire type and field number varint, plus length varint. - // Be careful to preserve duplicate items. - b := EncodeVarint(uint64(id)<<3 | WireBytes) - if ext, ok := m[id]; ok { - // Existing data; rip off the tag and length varint - // so we join the new data correctly. - // We can assume that ext.enc is set because we are unmarshaling. - o := ext.enc[len(b):] // skip wire type and field number - _, n := DecodeVarint(o) // calculate length of length varint - o = o[n:] // skip length varint - msg = append(o, msg...) // join old data and new data - } - b = append(b, EncodeVarint(uint64(len(msg)))...) - b = append(b, msg...) - - m[id] = Extension{enc: b} - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go deleted file mode 100644 index b6cad90834..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,357 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" - "sync" -) - -const unsafeAllowed = false - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by the sequence of field indices -// passed to reflect's FieldByIndex. -type field []int - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return f.Index -} - -// invalidField is an invalid field identifier. -var invalidField = field(nil) - -// zeroField is a noop when calling pointer.offset. -var zeroField = field([]int{}) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// The pointer type is for the table-driven decoder. -// The implementation here uses a reflect.Value of pointer type to -// create a generic pointer. In pointer_unsafe.go we use unsafe -// instead of reflect to implement the same (but faster) interface. -type pointer struct { - v reflect.Value -} - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - return pointer{v: reflect.ValueOf(*i)} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - v := reflect.ValueOf(*i) - u := reflect.New(v.Type()) - u.Elem().Set(v) - return pointer{v: u} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{v: v} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} -} - -func (p pointer) isNil() bool { - return p.v.IsNil() -} - -// grow updates the slice s in place to make it one element longer. -// s must be addressable. -// Returns the (addressable) new element. -func grow(s reflect.Value) reflect.Value { - n, m := s.Len(), s.Cap() - if n < m { - s.SetLen(n + 1) - } else { - s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) - } - return s.Index(n) -} - -func (p pointer) toInt64() *int64 { - return p.v.Interface().(*int64) -} -func (p pointer) toInt64Ptr() **int64 { - return p.v.Interface().(**int64) -} -func (p pointer) toInt64Slice() *[]int64 { - return p.v.Interface().(*[]int64) -} - -var int32ptr = reflect.TypeOf((*int32)(nil)) - -func (p pointer) toInt32() *int32 { - return p.v.Convert(int32ptr).Interface().(*int32) -} - -// The toInt32Ptr/Slice methods don't work because of enums. -// Instead, we must use set/get methods for the int32ptr/slice case. -/* - func (p pointer) toInt32Ptr() **int32 { - return p.v.Interface().(**int32) -} - func (p pointer) toInt32Slice() *[]int32 { - return p.v.Interface().(*[]int32) -} -*/ -func (p pointer) getInt32Ptr() *int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().(*int32) - } - // an enum - return p.v.Elem().Convert(int32PtrType).Interface().(*int32) -} -func (p pointer) setInt32Ptr(v int32) { - // Allocate value in a *int32. Possibly convert that to a *enum. - // Then assign it to a **int32 or **enum. - // Note: we can convert *int32 to *enum, but we can't convert - // **int32 to **enum! - p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) -} - -// getInt32Slice copies []int32 from p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getInt32Slice() []int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().([]int32) - } - // an enum - // Allocate a []int32, then assign []enum's values into it. - // Note: we can't convert []enum to []int32. - slice := p.v.Elem() - s := make([]int32, slice.Len()) - for i := 0; i < slice.Len(); i++ { - s[i] = int32(slice.Index(i).Int()) - } - return s -} - -// setInt32Slice copies []int32 into p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setInt32Slice(v []int32) { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - p.v.Elem().Set(reflect.ValueOf(v)) - return - } - // an enum - // Allocate a []enum, then assign []int32's values into it. - // Note: we can't convert []enum to []int32. - slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) - for i, x := range v { - slice.Index(i).SetInt(int64(x)) - } - p.v.Elem().Set(slice) -} -func (p pointer) appendInt32Slice(v int32) { - grow(p.v.Elem()).SetInt(int64(v)) -} - -func (p pointer) toUint64() *uint64 { - return p.v.Interface().(*uint64) -} -func (p pointer) toUint64Ptr() **uint64 { - return p.v.Interface().(**uint64) -} -func (p pointer) toUint64Slice() *[]uint64 { - return p.v.Interface().(*[]uint64) -} -func (p pointer) toUint32() *uint32 { - return p.v.Interface().(*uint32) -} -func (p pointer) toUint32Ptr() **uint32 { - return p.v.Interface().(**uint32) -} -func (p pointer) toUint32Slice() *[]uint32 { - return p.v.Interface().(*[]uint32) -} -func (p pointer) toBool() *bool { - return p.v.Interface().(*bool) -} -func (p pointer) toBoolPtr() **bool { - return p.v.Interface().(**bool) -} -func (p pointer) toBoolSlice() *[]bool { - return p.v.Interface().(*[]bool) -} -func (p pointer) toFloat64() *float64 { - return p.v.Interface().(*float64) -} -func (p pointer) toFloat64Ptr() **float64 { - return p.v.Interface().(**float64) -} -func (p pointer) toFloat64Slice() *[]float64 { - return p.v.Interface().(*[]float64) -} -func (p pointer) toFloat32() *float32 { - return p.v.Interface().(*float32) -} -func (p pointer) toFloat32Ptr() **float32 { - return p.v.Interface().(**float32) -} -func (p pointer) toFloat32Slice() *[]float32 { - return p.v.Interface().(*[]float32) -} -func (p pointer) toString() *string { - return p.v.Interface().(*string) -} -func (p pointer) toStringPtr() **string { - return p.v.Interface().(**string) -} -func (p pointer) toStringSlice() *[]string { - return p.v.Interface().(*[]string) -} -func (p pointer) toBytes() *[]byte { - return p.v.Interface().(*[]byte) -} -func (p pointer) toBytesSlice() *[][]byte { - return p.v.Interface().(*[][]byte) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return p.v.Interface().(*XXX_InternalExtensions) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return p.v.Interface().(*map[int32]Extension) -} -func (p pointer) getPointer() pointer { - return pointer{v: p.v.Elem()} -} -func (p pointer) setPointer(q pointer) { - p.v.Elem().Set(q.v) -} -func (p pointer) appendPointer(q pointer) { - grow(p.v.Elem()).Set(q.v) -} - -// getPointerSlice copies []*T from p as a new []pointer. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getPointerSlice() []pointer { - if p.v.IsNil() { - return nil - } - n := p.v.Elem().Len() - s := make([]pointer, n) - for i := 0; i < n; i++ { - s[i] = pointer{v: p.v.Elem().Index(i)} - } - return s -} - -// setPointerSlice copies []pointer into p as a new []*T. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setPointerSlice(v []pointer) { - if v == nil { - p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) - return - } - s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) - for _, p := range v { - s = reflect.Append(s, p.v) - } - p.v.Elem().Set(s) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - if p.v.Elem().IsNil() { - return pointer{v: p.v.Elem()} - } - return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct -} - -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - // TODO: check that p.v.Type().Elem() == t? - return p.v -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} - -var atomicLock sync.Mutex diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go deleted file mode 100644 index 7ffd3c29d9..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go +++ /dev/null @@ -1,59 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" -) - -// TODO: untested, so probably incorrect. - -func (p pointer) getRef() pointer { - return pointer{v: p.v.Addr()} -} - -func (p pointer) appendRef(v pointer, typ reflect.Type) { - slice := p.getSlice(typ) - elem := v.asPointerTo(typ).Elem() - newSlice := reflect.Append(slice, elem) - slice.Set(newSlice) -} - -func (p pointer) getSlice(typ reflect.Type) reflect.Value { - sliceTyp := reflect.SliceOf(typ) - slice := p.asPointerTo(sliceTyp) - slice = slice.Elem() - return slice -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index d55a335d94..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,308 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "sync/atomic" - "unsafe" -) - -const unsafeAllowed = true - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by its byte offset from the start of the struct. -type field uintptr - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return field(f.Offset) -} - -// invalidField is an invalid field identifier. -const invalidField = ^field(0) - -// zeroField is a noop when calling pointer.offset. -const zeroField = field(0) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != invalidField -} - -// The pointer type below is for the new table-driven encoder/decoder. -// The implementation here uses unsafe.Pointer to create a generic pointer. -// In pointer_reflect.go we use reflect instead of unsafe to implement -// the same (but slower) interface. -type pointer struct { - p unsafe.Pointer -} - -// size of pointer -var ptrSize = unsafe.Sizeof(uintptr(0)) - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - // Super-tricky - read pointer out of data word of interface value. - // Saves ~25ns over the equivalent: - // return valToPointer(reflect.ValueOf(*i)) - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr bool) pointer { - // Super-tricky - read or get the address of data word of interface value. - if isptr { - // The interface is of pointer type, thus it is a direct interface. - // The data word is the pointer data itself. We take its address. - return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} - } - // The interface is not of pointer type. The data word is the pointer - // to the data. - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{p: unsafe.Pointer(v.Pointer())} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - // For safety, we should panic if !f.IsValid, however calling panic causes - // this to no longer be inlineable, which is a serious performance cost. - /* - if !f.IsValid() { - panic("invalid field") - } - */ - return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} -} - -func (p pointer) isNil() bool { - return p.p == nil -} - -func (p pointer) toInt64() *int64 { - return (*int64)(p.p) -} -func (p pointer) toInt64Ptr() **int64 { - return (**int64)(p.p) -} -func (p pointer) toInt64Slice() *[]int64 { - return (*[]int64)(p.p) -} -func (p pointer) toInt32() *int32 { - return (*int32)(p.p) -} - -// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. -/* - func (p pointer) toInt32Ptr() **int32 { - return (**int32)(p.p) - } - func (p pointer) toInt32Slice() *[]int32 { - return (*[]int32)(p.p) - } -*/ -func (p pointer) getInt32Ptr() *int32 { - return *(**int32)(p.p) -} -func (p pointer) setInt32Ptr(v int32) { - *(**int32)(p.p) = &v -} - -// getInt32Slice loads a []int32 from p. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getInt32Slice() []int32 { - return *(*[]int32)(p.p) -} - -// setInt32Slice stores a []int32 to p. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setInt32Slice(v []int32) { - *(*[]int32)(p.p) = v -} - -// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? -func (p pointer) appendInt32Slice(v int32) { - s := (*[]int32)(p.p) - *s = append(*s, v) -} - -func (p pointer) toUint64() *uint64 { - return (*uint64)(p.p) -} -func (p pointer) toUint64Ptr() **uint64 { - return (**uint64)(p.p) -} -func (p pointer) toUint64Slice() *[]uint64 { - return (*[]uint64)(p.p) -} -func (p pointer) toUint32() *uint32 { - return (*uint32)(p.p) -} -func (p pointer) toUint32Ptr() **uint32 { - return (**uint32)(p.p) -} -func (p pointer) toUint32Slice() *[]uint32 { - return (*[]uint32)(p.p) -} -func (p pointer) toBool() *bool { - return (*bool)(p.p) -} -func (p pointer) toBoolPtr() **bool { - return (**bool)(p.p) -} -func (p pointer) toBoolSlice() *[]bool { - return (*[]bool)(p.p) -} -func (p pointer) toFloat64() *float64 { - return (*float64)(p.p) -} -func (p pointer) toFloat64Ptr() **float64 { - return (**float64)(p.p) -} -func (p pointer) toFloat64Slice() *[]float64 { - return (*[]float64)(p.p) -} -func (p pointer) toFloat32() *float32 { - return (*float32)(p.p) -} -func (p pointer) toFloat32Ptr() **float32 { - return (**float32)(p.p) -} -func (p pointer) toFloat32Slice() *[]float32 { - return (*[]float32)(p.p) -} -func (p pointer) toString() *string { - return (*string)(p.p) -} -func (p pointer) toStringPtr() **string { - return (**string)(p.p) -} -func (p pointer) toStringSlice() *[]string { - return (*[]string)(p.p) -} -func (p pointer) toBytes() *[]byte { - return (*[]byte)(p.p) -} -func (p pointer) toBytesSlice() *[][]byte { - return (*[][]byte)(p.p) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return (*XXX_InternalExtensions)(p.p) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return (*map[int32]Extension)(p.p) -} - -// getPointerSlice loads []*T from p as a []pointer. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getPointerSlice() []pointer { - // Super-tricky - p should point to a []*T where T is a - // message type. We load it as []pointer. - return *(*[]pointer)(p.p) -} - -// setPointerSlice stores []pointer into p as a []*T. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setPointerSlice(v []pointer) { - // Super-tricky - p should point to a []*T where T is a - // message type. We store it as []pointer. - *(*[]pointer)(p.p) = v -} - -// getPointer loads the pointer at p and returns it. -func (p pointer) getPointer() pointer { - return pointer{p: *(*unsafe.Pointer)(p.p)} -} - -// setPointer stores the pointer q at p. -func (p pointer) setPointer(q pointer) { - *(*unsafe.Pointer)(p.p) = q.p -} - -// append q to the slice pointed to by p. -func (p pointer) appendPointer(q pointer) { - s := (*[]unsafe.Pointer)(p.p) - *s = append(*s, q.p) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - // Super-tricky - read pointer out of data word of interface value. - return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} -} - -// asPointerTo returns a reflect.Value that is a pointer to an -// object of type t stored at p. -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - return reflect.NewAt(t, p.p) -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} diff --git a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go b/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go deleted file mode 100644 index aca8eed02a..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go +++ /dev/null @@ -1,56 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "unsafe" -) - -func (p pointer) getRef() pointer { - return pointer{p: (unsafe.Pointer)(&p.p)} -} - -func (p pointer) appendRef(v pointer, typ reflect.Type) { - slice := p.getSlice(typ) - elem := v.asPointerTo(typ).Elem() - newSlice := reflect.Append(slice, elem) - slice.Set(newSlice) -} - -func (p pointer) getSlice(typ reflect.Type) reflect.Value { - sliceTyp := reflect.SliceOf(typ) - slice := p.asPointerTo(sliceTyp) - slice = slice.Elem() - return slice -} diff --git a/vendor/github.com/gogo/protobuf/proto/properties.go b/vendor/github.com/gogo/protobuf/proto/properties.go deleted file mode 100644 index 28da1475fb..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/properties.go +++ /dev/null @@ -1,610 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "fmt" - "log" - "reflect" - "sort" - "strconv" - "strings" - "sync" -) - -const debug bool = false - -// Constants that identify the encoding of a value on the wire. -const ( - WireVarint = 0 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 - WireFixed32 = 5 -) - -// tagMap is an optimization over map[int]int for typical protocol buffer -// use-cases. Encoded protocol buffers are often in tag order with small tag -// numbers. -type tagMap struct { - fastTags []int - slowTags map[int]int -} - -// tagMapFastLimit is the upper bound on the tag number that will be stored in -// the tagMap slice rather than its map. -const tagMapFastLimit = 1024 - -func (p *tagMap) get(t int) (int, bool) { - if t > 0 && t < tagMapFastLimit { - if t >= len(p.fastTags) { - return 0, false - } - fi := p.fastTags[t] - return fi, fi >= 0 - } - fi, ok := p.slowTags[t] - return fi, ok -} - -func (p *tagMap) put(t int, fi int) { - if t > 0 && t < tagMapFastLimit { - for len(p.fastTags) < t+1 { - p.fastTags = append(p.fastTags, -1) - } - p.fastTags[t] = fi - return - } - if p.slowTags == nil { - p.slowTags = make(map[int]int) - } - p.slowTags[t] = fi -} - -// StructProperties represents properties for all the fields of a struct. -// decoderTags and decoderOrigNames should only be used by the decoder. -type StructProperties struct { - Prop []*Properties // properties for each field - reqCount int // required count - decoderTags tagMap // map from proto tag to struct field number - decoderOrigNames map[string]int // map from original name to struct field number - order []int // list of struct field numbers in tag order - - // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the original name of a field. - OneofTypes map[string]*OneofProperties -} - -// OneofProperties represents information about a specific field in a oneof. -type OneofProperties struct { - Type reflect.Type // pointer to generated struct type for this oneof field - Field int // struct field number of the containing oneof in the message - Prop *Properties -} - -// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encode.go, (*Buffer).enc_struct. - -func (sp *StructProperties) Len() int { return len(sp.order) } -func (sp *StructProperties) Less(i, j int) bool { - return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag -} -func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } - -// Properties represents the protocol-specific behavior of a single struct field. -type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - JSONName string // name to use for JSON; determined by protoc - Wire string - WireType int - Tag int - Required bool - Optional bool - Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field - oneof bool // whether this is a oneof field - - Default string // default value - HasDefault bool // whether an explicit default was provided - CustomType string - CastType string - StdTime bool - StdDuration bool - WktPointer bool - - stype reflect.Type // set for struct types only - ctype reflect.Type // set for custom types only - sprop *StructProperties // set for struct types only - - mtype reflect.Type // set for map types only - MapKeyProp *Properties // set for map types only - MapValProp *Properties // set for map types only -} - -// String formats the properties in the protobuf struct field tag style. -func (p *Properties) String() string { - s := p.Wire - s += "," - s += strconv.Itoa(p.Tag) - if p.Required { - s += ",req" - } - if p.Optional { - s += ",opt" - } - if p.Repeated { - s += ",rep" - } - if p.Packed { - s += ",packed" - } - s += ",name=" + p.OrigName - if p.JSONName != p.OrigName { - s += ",json=" + p.JSONName - } - if p.proto3 { - s += ",proto3" - } - if p.oneof { - s += ",oneof" - } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } - if p.HasDefault { - s += ",def=" + p.Default - } - return s -} - -// Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(s string) { - // "bytes,49,opt,name=foo,def=hello!" - fields := strings.Split(s, ",") // breaks def=, but handled below. - if len(fields) < 2 { - log.Printf("proto: tag has too few fields: %q", s) - return - } - - p.Wire = fields[0] - switch p.Wire { - case "varint": - p.WireType = WireVarint - case "fixed32": - p.WireType = WireFixed32 - case "fixed64": - p.WireType = WireFixed64 - case "zigzag32": - p.WireType = WireVarint - case "zigzag64": - p.WireType = WireVarint - case "bytes", "group": - p.WireType = WireBytes - // no numeric converter for non-numeric types - default: - log.Printf("proto: tag has unknown wire type: %q", s) - return - } - - var err error - p.Tag, err = strconv.Atoi(fields[1]) - if err != nil { - return - } - -outer: - for i := 2; i < len(fields); i++ { - f := fields[i] - switch { - case f == "req": - p.Required = true - case f == "opt": - p.Optional = true - case f == "rep": - p.Repeated = true - case f == "packed": - p.Packed = true - case strings.HasPrefix(f, "name="): - p.OrigName = f[5:] - case strings.HasPrefix(f, "json="): - p.JSONName = f[5:] - case strings.HasPrefix(f, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = true - case f == "oneof": - p.oneof = true - case strings.HasPrefix(f, "def="): - p.HasDefault = true - p.Default = f[4:] // rest of string - if i+1 < len(fields) { - // Commas aren't escaped, and def is always last. - p.Default += "," + strings.Join(fields[i+1:], ",") - break outer - } - case strings.HasPrefix(f, "embedded="): - p.OrigName = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "customtype="): - p.CustomType = strings.Split(f, "=")[1] - case strings.HasPrefix(f, "casttype="): - p.CastType = strings.Split(f, "=")[1] - case f == "stdtime": - p.StdTime = true - case f == "stdduration": - p.StdDuration = true - case f == "wktptr": - p.WktPointer = true - } - } -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// setFieldProps initializes the field properties for submessages and maps. -func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - isMap := typ.Kind() == reflect.Map - if len(p.CustomType) > 0 && !isMap { - p.ctype = typ - p.setTag(lockGetProp) - return - } - if p.StdTime && !isMap { - p.setTag(lockGetProp) - return - } - if p.StdDuration && !isMap { - p.setTag(lockGetProp) - return - } - if p.WktPointer && !isMap { - p.setTag(lockGetProp) - return - } - switch t1 := typ; t1.Kind() { - case reflect.Struct: - p.stype = typ - case reflect.Ptr: - if t1.Elem().Kind() == reflect.Struct { - p.stype = t1.Elem() - } - case reflect.Slice: - switch t2 := t1.Elem(); t2.Kind() { - case reflect.Ptr: - switch t3 := t2.Elem(); t3.Kind() { - case reflect.Struct: - p.stype = t3 - } - case reflect.Struct: - p.stype = t2 - } - - case reflect.Map: - - p.mtype = t1 - p.MapKeyProp = &Properties{} - p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.MapValProp = &Properties{} - vtype := p.mtype.Elem() - if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { - // The value type is not a message (*T) or bytes ([]byte), - // so we need encoders for the pointer to this type. - vtype = reflect.PtrTo(vtype) - } - - p.MapValProp.CustomType = p.CustomType - p.MapValProp.StdDuration = p.StdDuration - p.MapValProp.StdTime = p.StdTime - p.MapValProp.WktPointer = p.WktPointer - p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - p.setTag(lockGetProp) -} - -func (p *Properties) setTag(lockGetProp bool) { - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) - } - } -} - -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() -) - -// Init populates the properties from a protocol buffer struct tag. -func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.init(typ, name, tag, f, true) -} - -func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { - // "bytes,49,opt,def=hello!" - p.Name = name - p.OrigName = name - if tag == "" { - return - } - p.Parse(tag) - p.setFieldProps(typ, f, lockGetProp) -} - -var ( - propertiesMu sync.RWMutex - propertiesMap = make(map[reflect.Type]*StructProperties) -) - -// GetProperties returns the list of properties for the type represented by t. -// t must represent a generated struct type of a protocol message. -func GetProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic("proto: type must have kind struct") - } - - // Most calls to GetProperties in a long-running program will be - // retrieving details for types we have seen before. - propertiesMu.RLock() - sprop, ok := propertiesMap[t] - propertiesMu.RUnlock() - if ok { - return sprop - } - - propertiesMu.Lock() - sprop = getPropertiesLocked(t) - propertiesMu.Unlock() - return sprop -} - -type ( - oneofFuncsIface interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) - } - oneofWrappersIface interface { - XXX_OneofWrappers() []interface{} - } -) - -// getPropertiesLocked requires that propertiesMu is held. -func getPropertiesLocked(t reflect.Type) *StructProperties { - if prop, ok := propertiesMap[t]; ok { - return prop - } - - prop := new(StructProperties) - // in case of recursive protos, fill this in now. - propertiesMap[t] = prop - - // build properties - prop.Prop = make([]*Properties, t.NumField()) - prop.order = make([]int, t.NumField()) - - isOneofMessage := false - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - p := new(Properties) - name := f.Name - p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) - - oneof := f.Tag.Get("protobuf_oneof") // special case - if oneof != "" { - isOneofMessage = true - // Oneof fields don't use the traditional protobuf tag. - p.OrigName = oneof - } - prop.Prop[i] = p - prop.order[i] = i - if debug { - print(i, " ", f.Name, " ", t.String(), " ") - if p.Tag > 0 { - print(p.String()) - } - print("\n") - } - } - - // Re-order prop.order. - sort.Sort(prop) - - if isOneofMessage { - var oots []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oots = m.XXX_OneofFuncs() - case oneofWrappersIface: - oots = m.XXX_OneofWrappers() - } - if len(oots) > 0 { - // Interpret oneof metadata. - prop.OneofTypes = make(map[string]*OneofProperties) - for _, oot := range oots { - oop := &OneofProperties{ - Type: reflect.ValueOf(oot).Type(), // *T - Prop: new(Properties), - } - sft := oop.Type.Elem().Field(0) - oop.Prop.Name = sft.Name - oop.Prop.Parse(sft.Tag.Get("protobuf")) - // There will be exactly one interface field that - // this new value is assignable to. - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Type.Kind() != reflect.Interface { - continue - } - if !oop.Type.AssignableTo(f.Type) { - continue - } - oop.Field = i - break - } - prop.OneofTypes[oop.Prop.OrigName] = oop - } - } - } - - // build required counts - // build tags - reqCount := 0 - prop.decoderOrigNames = make(map[string]int) - for i, p := range prop.Prop { - if strings.HasPrefix(p.Name, "XXX_") { - // Internal fields should not appear in tags/origNames maps. - // They are handled specially when encoding and decoding. - continue - } - if p.Required { - reqCount++ - } - prop.decoderTags.put(p.Tag, i) - prop.decoderOrigNames[p.OrigName] = i - } - prop.reqCount = reqCount - - return prop -} - -// A global registry of enum types. -// The generated code will register the generated maps by calling RegisterEnum. - -var enumValueMaps = make(map[string]map[string]int32) -var enumStringMaps = make(map[string]map[int32]string) - -// RegisterEnum is called from the generated code to install the enum descriptor -// maps into the global table to aid parsing text format protocol buffers. -func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { - if _, ok := enumValueMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumValueMaps[typeName] = valueMap - if _, ok := enumStringMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumStringMaps[typeName] = unusedNameMap -} - -// EnumValueMap returns the mapping from names to integers of the -// enum type enumType, or a nil if not found. -func EnumValueMap(enumType string) map[string]int32 { - return enumValueMaps[enumType] -} - -// A registry of all linked message types. -// The string is a fully-qualified proto name ("pkg.Message"). -var ( - protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers - protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types - revProtoTypes = make(map[reflect.Type]string) -) - -// RegisterType is called from generated code and maps from the fully qualified -// proto name to the type (pointer to struct) of the protocol buffer. -func RegisterType(x Message, name string) { - if _, ok := protoTypedNils[name]; ok { - // TODO: Some day, make this a panic. - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { - // Generated code always calls RegisterType with nil x. - // This check is just for extra safety. - protoTypedNils[name] = x - } else { - protoTypedNils[name] = reflect.Zero(t).Interface().(Message) - } - revProtoTypes[t] = name -} - -// RegisterMapType is called from generated code and maps from the fully qualified -// proto name to the native map type of the proto map definition. -func RegisterMapType(x interface{}, name string) { - if reflect.TypeOf(x).Kind() != reflect.Map { - panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) - } - if _, ok := protoMapTypes[name]; ok { - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - protoMapTypes[name] = t - revProtoTypes[t] = name -} - -// MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { - type xname interface { - XXX_MessageName() string - } - if m, ok := x.(xname); ok { - return m.XXX_MessageName() - } - return revProtoTypes[reflect.TypeOf(x)] -} - -// MessageType returns the message type (pointer to struct) for a named message. -// The type is not guaranteed to implement proto.Message if the name refers to a -// map entry. -func MessageType(name string) reflect.Type { - if t, ok := protoTypedNils[name]; ok { - return reflect.TypeOf(t) - } - return protoMapTypes[name] -} - -// A registry of all linked proto files. -var ( - protoFiles = make(map[string][]byte) // file name => fileDescriptor -) - -// RegisterFile is called from generated code and maps from the -// full file name of a .proto file to its compressed FileDescriptorProto. -func RegisterFile(filename string, fileDescriptor []byte) { - protoFiles[filename] = fileDescriptor -} - -// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. -func FileDescriptor(filename string) []byte { return protoFiles[filename] } diff --git a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go b/vendor/github.com/gogo/protobuf/proto/properties_gogo.go deleted file mode 100644 index 40ea3dd935..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/properties_gogo.go +++ /dev/null @@ -1,36 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" -) - -var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem() -var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem() diff --git a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go b/vendor/github.com/gogo/protobuf/proto/skip_gogo.go deleted file mode 100644 index 5a5fd93f7c..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/skip_gogo.go +++ /dev/null @@ -1,119 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "io" -) - -func Skip(data []byte) (n int, err error) { - l := len(data) - index := 0 - for index < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - index++ - if data[index-1] < 0x80 { - break - } - } - return index, nil - case 1: - index += 8 - return index, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - index += length - return index, nil - case 3: - for { - var innerWire uint64 - var start int = index - for shift := uint(0); ; shift += 7 { - if index >= l { - return 0, io.ErrUnexpectedEOF - } - b := data[index] - index++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := Skip(data[start:]) - if err != nil { - return 0, err - } - index = start + next - } - return index, nil - case 4: - return index, nil - case 5: - index += 4 - return index, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal.go b/vendor/github.com/gogo/protobuf/proto/table_marshal.go deleted file mode 100644 index f8babdefab..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/table_marshal.go +++ /dev/null @@ -1,3009 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// a sizer takes a pointer to a field and the size of its tag, computes the size of -// the encoded data. -type sizer func(pointer, int) int - -// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), -// marshals the field to the end of the slice, returns the slice and error (if any). -type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) - -// marshalInfo is the information used for marshaling a message. -type marshalInfo struct { - typ reflect.Type - fields []*marshalFieldInfo - unrecognized field // offset of XXX_unrecognized - extensions field // offset of XXX_InternalExtensions - v1extensions field // offset of XXX_extensions - sizecache field // offset of XXX_sizecache - initialized int32 // 0 -- only typ is set, 1 -- fully initialized - messageset bool // uses message set wire format - hasmarshaler bool // has custom marshaler - sync.RWMutex // protect extElems map, also for initialization - extElems map[int32]*marshalElemInfo // info of extension elements - - hassizer bool // has custom sizer - hasprotosizer bool // has custom protosizer - - bytesExtensions field // offset of XXX_extensions where the field type is []byte -} - -// marshalFieldInfo is the information used for marshaling a field of a message. -type marshalFieldInfo struct { - field field - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isPointer bool - required bool // field is required - name string // name of the field, for error reporting - oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements -} - -// marshalElemInfo is the information used for marshaling an extension or oneof element. -type marshalElemInfo struct { - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) -} - -var ( - marshalInfoMap = map[reflect.Type]*marshalInfo{} - marshalInfoLock sync.Mutex - - uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind() -) - -// getMarshalInfo returns the information to marshal a given type of message. -// The info it returns may not necessarily initialized. -// t is the type of the message (NOT the pointer to it). -func getMarshalInfo(t reflect.Type) *marshalInfo { - marshalInfoLock.Lock() - u, ok := marshalInfoMap[t] - if !ok { - u = &marshalInfo{typ: t} - marshalInfoMap[t] = u - } - marshalInfoLock.Unlock() - return u -} - -// Size is the entry point from generated code, -// and should be ONLY called by generated code. -// It computes the size of encoded data of msg. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Size(msg Message) int { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return 0 - } - return u.size(ptr) -} - -// Marshal is the entry point from generated code, -// and should be ONLY called by generated code. -// It marshals msg to the end of b. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return b, ErrNil - } - return u.marshal(b, ptr, deterministic) -} - -func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { - // u := a.marshal, but atomically. - // We use an atomic here to ensure memory consistency. - u := atomicLoadMarshalInfo(&a.marshal) - if u == nil { - // Get marshal information from type of message. - t := reflect.ValueOf(msg).Type() - if t.Kind() != reflect.Ptr { - panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) - } - u = getMarshalInfo(t.Elem()) - // Store it in the cache for later users. - // a.marshal = u, but atomically. - atomicStoreMarshalInfo(&a.marshal, u) - } - return u -} - -// size is the main function to compute the size of the encoded data of a message. -// ptr is the pointer to the message. -func (u *marshalInfo) size(ptr pointer) int { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - // Uses the message's Size method if available - if u.hassizer { - s := ptr.asPointerTo(u.typ).Interface().(Sizer) - return s.Size() - } - // Uses the message's ProtoSize method if available - if u.hasprotosizer { - s := ptr.asPointerTo(u.typ).Interface().(ProtoSizer) - return s.ProtoSize() - } - - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b, _ := m.Marshal() - return len(b) - } - - n := 0 - for _, f := range u.fields { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - n += f.sizer(ptr.offset(f.field), f.tagsize) - } - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - n += u.sizeMessageSet(e) - } else { - n += u.sizeExtensions(e) - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - n += u.sizeV1Extensions(m) - } - if u.bytesExtensions.IsValid() { - s := *ptr.offset(u.bytesExtensions).toBytes() - n += len(s) - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - n += len(s) - } - - // cache the result for use in marshal - if u.sizecache.IsValid() { - atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) - } - return n -} - -// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), -// fall back to compute the size. -func (u *marshalInfo) cachedsize(ptr pointer) int { - if u.sizecache.IsValid() { - return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) - } - return u.size(ptr) -} - -// marshal is the main function to marshal a message. It takes a byte slice and appends -// the encoded data to the end of the slice, returns the slice and error (if any). -// ptr is the pointer to the message. -// If deterministic is true, map is marshaled in deterministic order. -func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b1, err := m.Marshal() - b = append(b, b1...) - return b, err - } - - var err, errLater error - // The old marshaler encodes extensions at beginning. - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - b, err = u.appendMessageSet(b, e, deterministic) - } else { - b, err = u.appendExtensions(b, e, deterministic) - } - if err != nil { - return b, err - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - b, err = u.appendV1Extensions(b, m, deterministic) - if err != nil { - return b, err - } - } - if u.bytesExtensions.IsValid() { - s := *ptr.offset(u.bytesExtensions).toBytes() - b = append(b, s...) - } - for _, f := range u.fields { - if f.required { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // Required field is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name} - } - continue - } - } - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) - if err != nil { - if err1, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name + "." + err1.field} - } - continue - } - if err == errRepeatedHasNil { - err = errors.New("proto: repeated field " + f.name + " has nil element") - } - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return b, err - } - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - b = append(b, s...) - } - return b, errLater -} - -// computeMarshalInfo initializes the marshal info. -func (u *marshalInfo) computeMarshalInfo() { - u.Lock() - defer u.Unlock() - if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock - return - } - - t := u.typ - u.unrecognized = invalidField - u.extensions = invalidField - u.v1extensions = invalidField - u.bytesExtensions = invalidField - u.sizecache = invalidField - isOneofMessage := false - - if reflect.PtrTo(t).Implements(sizerType) { - u.hassizer = true - } - if reflect.PtrTo(t).Implements(protosizerType) { - u.hasprotosizer = true - } - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if reflect.PtrTo(t).Implements(marshalerType) { - u.hasmarshaler = true - atomic.StoreInt32(&u.initialized, 1) - return - } - - n := t.NumField() - - // deal with XXX fields first - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Tag.Get("protobuf_oneof") != "" { - isOneofMessage = true - } - if !strings.HasPrefix(f.Name, "XXX_") { - continue - } - switch f.Name { - case "XXX_sizecache": - u.sizecache = toField(&f) - case "XXX_unrecognized": - u.unrecognized = toField(&f) - case "XXX_InternalExtensions": - u.extensions = toField(&f) - u.messageset = f.Tag.Get("protobuf_messageset") == "1" - case "XXX_extensions": - if f.Type.Kind() == reflect.Map { - u.v1extensions = toField(&f) - } else { - u.bytesExtensions = toField(&f) - } - case "XXX_NoUnkeyedLiteral": - // nothing to do - default: - panic("unknown XXX field: " + f.Name) - } - n-- - } - - // get oneof implementers - var oneofImplementers []interface{} - // gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler - if isOneofMessage { - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - } - - // normal fields - fields := make([]marshalFieldInfo, n) // batch allocation - u.fields = make([]*marshalFieldInfo, 0, n) - for i, j := 0, 0; i < t.NumField(); i++ { - f := t.Field(i) - - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - field := &fields[j] - j++ - field.name = f.Name - u.fields = append(u.fields, field) - if f.Tag.Get("protobuf_oneof") != "" { - field.computeOneofFieldInfo(&f, oneofImplementers) - continue - } - if f.Tag.Get("protobuf") == "" { - // field has no tag (not in generated message), ignore it - u.fields = u.fields[:len(u.fields)-1] - j-- - continue - } - field.computeMarshalFieldInfo(&f) - } - - // fields are marshaled in tag order on the wire. - sort.Sort(byTag(u.fields)) - - atomic.StoreInt32(&u.initialized, 1) -} - -// helper for sorting fields by tag -type byTag []*marshalFieldInfo - -func (a byTag) Len() int { return len(a) } -func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } - -// getExtElemInfo returns the information to marshal an extension element. -// The info it returns is initialized. -func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { - // get from cache first - u.RLock() - e, ok := u.extElems[desc.Field] - u.RUnlock() - if ok { - return e - } - - t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct - tags := strings.Split(desc.Tag, ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizr, marshalr := typeMarshaler(t, tags, false, false) - e = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizr, - marshaler: marshalr, - isptr: t.Kind() == reflect.Ptr, - } - - // update cache - u.Lock() - if u.extElems == nil { - u.extElems = make(map[int32]*marshalElemInfo) - } - u.extElems[desc.Field] = e - u.Unlock() - return e -} - -// computeMarshalFieldInfo fills up the information to marshal a field. -func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { - // parse protobuf tag of the field. - // tag has format of "bytes,49,opt,name=foo,def=hello!" - tags := strings.Split(f.Tag.Get("protobuf"), ",") - if tags[0] == "" { - return - } - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - if tags[2] == "req" { - fi.required = true - } - fi.setTag(f, tag, wt) - fi.setMarshaler(f, tags) -} - -func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { - fi.field = toField(f) - fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. - fi.isPointer = true - fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) - fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) - - ityp := f.Type // interface type - for _, o := range oneofImplementers { - t := reflect.TypeOf(o) - if !t.Implements(ityp) { - continue - } - sf := t.Elem().Field(0) // oneof implementer is a struct with a single field - tags := strings.Split(sf.Tag.Get("protobuf"), ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value - fi.oneofElems[t.Elem()] = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizr, - marshaler: marshalr, - } - } -} - -// wiretype returns the wire encoding of the type. -func wiretype(encoding string) uint64 { - switch encoding { - case "fixed32": - return WireFixed32 - case "fixed64": - return WireFixed64 - case "varint", "zigzag32", "zigzag64": - return WireVarint - case "bytes": - return WireBytes - case "group": - return WireStartGroup - } - panic("unknown wire type " + encoding) -} - -// setTag fills up the tag (in wire format) and its size in the info of a field. -func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { - fi.field = toField(f) - fi.wiretag = uint64(tag)<<3 | wt - fi.tagsize = SizeVarint(uint64(tag) << 3) -} - -// setMarshaler fills up the sizer and marshaler in the info of a field. -func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { - switch f.Type.Kind() { - case reflect.Map: - // map field - fi.isPointer = true - fi.sizer, fi.marshaler = makeMapMarshaler(f) - return - case reflect.Ptr, reflect.Slice: - fi.isPointer = true - } - fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) -} - -// typeMarshaler returns the sizer and marshaler of a given field. -// t is the type of the field. -// tags is the generated "protobuf" tag of the field. -// If nozero is true, zero value is not marshaled to the wire. -// If oneof is true, it is a oneof field. -func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { - encoding := tags[0] - - pointer := false - slice := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - packed := false - proto3 := false - ctype := false - isTime := false - isDuration := false - isWktPointer := false - validateUTF8 := true - for i := 2; i < len(tags); i++ { - if tags[i] == "packed" { - packed = true - } - if tags[i] == "proto3" { - proto3 = true - } - if strings.HasPrefix(tags[i], "customtype=") { - ctype = true - } - if tags[i] == "stdtime" { - isTime = true - } - if tags[i] == "stdduration" { - isDuration = true - } - if tags[i] == "wktptr" { - isWktPointer = true - } - } - validateUTF8 = validateUTF8 && proto3 - if !proto3 && !pointer && !slice { - nozero = false - } - - if ctype { - if reflect.PtrTo(t).Implements(customType) { - if slice { - return makeMessageRefSliceMarshaler(getMarshalInfo(t)) - } - if pointer { - return makeCustomPtrMarshaler(getMarshalInfo(t)) - } - return makeCustomMarshaler(getMarshalInfo(t)) - } else { - panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) - } - } - - if isTime { - if pointer { - if slice { - return makeTimePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeTimePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeTimeSliceMarshaler(getMarshalInfo(t)) - } - return makeTimeMarshaler(getMarshalInfo(t)) - } - - if isDuration { - if pointer { - if slice { - return makeDurationPtrSliceMarshaler(getMarshalInfo(t)) - } - return makeDurationPtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeDurationSliceMarshaler(getMarshalInfo(t)) - } - return makeDurationMarshaler(getMarshalInfo(t)) - } - - if isWktPointer { - switch t.Kind() { - case reflect.Float64: - if pointer { - if slice { - return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdDoubleValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdDoubleValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdDoubleValueMarshaler(getMarshalInfo(t)) - case reflect.Float32: - if pointer { - if slice { - return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdFloatValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdFloatValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdFloatValueMarshaler(getMarshalInfo(t)) - case reflect.Int64: - if pointer { - if slice { - return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt64ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdInt64ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt64ValueMarshaler(getMarshalInfo(t)) - case reflect.Uint64: - if pointer { - if slice { - return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt64ValueMarshaler(getMarshalInfo(t)) - case reflect.Int32: - if pointer { - if slice { - return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt32ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdInt32ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdInt32ValueMarshaler(getMarshalInfo(t)) - case reflect.Uint32: - if pointer { - if slice { - return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdUInt32ValueMarshaler(getMarshalInfo(t)) - case reflect.Bool: - if pointer { - if slice { - return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBoolValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdBoolValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBoolValueMarshaler(getMarshalInfo(t)) - case reflect.String: - if pointer { - if slice { - return makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdStringValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdStringValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdStringValueMarshaler(getMarshalInfo(t)) - case uint8SliceType: - if pointer { - if slice { - return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBytesValuePtrMarshaler(getMarshalInfo(t)) - } - if slice { - return makeStdBytesValueSliceMarshaler(getMarshalInfo(t)) - } - return makeStdBytesValueMarshaler(getMarshalInfo(t)) - default: - panic(fmt.Sprintf("unknown wktpointer type %#v", t)) - } - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return sizeBoolPtr, appendBoolPtr - } - if slice { - if packed { - return sizeBoolPackedSlice, appendBoolPackedSlice - } - return sizeBoolSlice, appendBoolSlice - } - if nozero { - return sizeBoolValueNoZero, appendBoolValueNoZero - } - return sizeBoolValue, appendBoolValue - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixed32Ptr, appendFixed32Ptr - } - if slice { - if packed { - return sizeFixed32PackedSlice, appendFixed32PackedSlice - } - return sizeFixed32Slice, appendFixed32Slice - } - if nozero { - return sizeFixed32ValueNoZero, appendFixed32ValueNoZero - } - return sizeFixed32Value, appendFixed32Value - case "varint": - if pointer { - return sizeVarint32Ptr, appendVarint32Ptr - } - if slice { - if packed { - return sizeVarint32PackedSlice, appendVarint32PackedSlice - } - return sizeVarint32Slice, appendVarint32Slice - } - if nozero { - return sizeVarint32ValueNoZero, appendVarint32ValueNoZero - } - return sizeVarint32Value, appendVarint32Value - } - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixedS32Ptr, appendFixedS32Ptr - } - if slice { - if packed { - return sizeFixedS32PackedSlice, appendFixedS32PackedSlice - } - return sizeFixedS32Slice, appendFixedS32Slice - } - if nozero { - return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero - } - return sizeFixedS32Value, appendFixedS32Value - case "varint": - if pointer { - return sizeVarintS32Ptr, appendVarintS32Ptr - } - if slice { - if packed { - return sizeVarintS32PackedSlice, appendVarintS32PackedSlice - } - return sizeVarintS32Slice, appendVarintS32Slice - } - if nozero { - return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero - } - return sizeVarintS32Value, appendVarintS32Value - case "zigzag32": - if pointer { - return sizeZigzag32Ptr, appendZigzag32Ptr - } - if slice { - if packed { - return sizeZigzag32PackedSlice, appendZigzag32PackedSlice - } - return sizeZigzag32Slice, appendZigzag32Slice - } - if nozero { - return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero - } - return sizeZigzag32Value, appendZigzag32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixed64Ptr, appendFixed64Ptr - } - if slice { - if packed { - return sizeFixed64PackedSlice, appendFixed64PackedSlice - } - return sizeFixed64Slice, appendFixed64Slice - } - if nozero { - return sizeFixed64ValueNoZero, appendFixed64ValueNoZero - } - return sizeFixed64Value, appendFixed64Value - case "varint": - if pointer { - return sizeVarint64Ptr, appendVarint64Ptr - } - if slice { - if packed { - return sizeVarint64PackedSlice, appendVarint64PackedSlice - } - return sizeVarint64Slice, appendVarint64Slice - } - if nozero { - return sizeVarint64ValueNoZero, appendVarint64ValueNoZero - } - return sizeVarint64Value, appendVarint64Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixedS64Ptr, appendFixedS64Ptr - } - if slice { - if packed { - return sizeFixedS64PackedSlice, appendFixedS64PackedSlice - } - return sizeFixedS64Slice, appendFixedS64Slice - } - if nozero { - return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero - } - return sizeFixedS64Value, appendFixedS64Value - case "varint": - if pointer { - return sizeVarintS64Ptr, appendVarintS64Ptr - } - if slice { - if packed { - return sizeVarintS64PackedSlice, appendVarintS64PackedSlice - } - return sizeVarintS64Slice, appendVarintS64Slice - } - if nozero { - return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero - } - return sizeVarintS64Value, appendVarintS64Value - case "zigzag64": - if pointer { - return sizeZigzag64Ptr, appendZigzag64Ptr - } - if slice { - if packed { - return sizeZigzag64PackedSlice, appendZigzag64PackedSlice - } - return sizeZigzag64Slice, appendZigzag64Slice - } - if nozero { - return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero - } - return sizeZigzag64Value, appendZigzag64Value - } - case reflect.Float32: - if pointer { - return sizeFloat32Ptr, appendFloat32Ptr - } - if slice { - if packed { - return sizeFloat32PackedSlice, appendFloat32PackedSlice - } - return sizeFloat32Slice, appendFloat32Slice - } - if nozero { - return sizeFloat32ValueNoZero, appendFloat32ValueNoZero - } - return sizeFloat32Value, appendFloat32Value - case reflect.Float64: - if pointer { - return sizeFloat64Ptr, appendFloat64Ptr - } - if slice { - if packed { - return sizeFloat64PackedSlice, appendFloat64PackedSlice - } - return sizeFloat64Slice, appendFloat64Slice - } - if nozero { - return sizeFloat64ValueNoZero, appendFloat64ValueNoZero - } - return sizeFloat64Value, appendFloat64Value - case reflect.String: - if validateUTF8 { - if pointer { - return sizeStringPtr, appendUTF8StringPtr - } - if slice { - return sizeStringSlice, appendUTF8StringSlice - } - if nozero { - return sizeStringValueNoZero, appendUTF8StringValueNoZero - } - return sizeStringValue, appendUTF8StringValue - } - if pointer { - return sizeStringPtr, appendStringPtr - } - if slice { - return sizeStringSlice, appendStringSlice - } - if nozero { - return sizeStringValueNoZero, appendStringValueNoZero - } - return sizeStringValue, appendStringValue - case reflect.Slice: - if slice { - return sizeBytesSlice, appendBytesSlice - } - if oneof { - // Oneof bytes field may also have "proto3" tag. - // We want to marshal it as a oneof field. Do this - // check before the proto3 check. - return sizeBytesOneof, appendBytesOneof - } - if proto3 { - return sizeBytes3, appendBytes3 - } - return sizeBytes, appendBytes - case reflect.Struct: - switch encoding { - case "group": - if slice { - return makeGroupSliceMarshaler(getMarshalInfo(t)) - } - return makeGroupMarshaler(getMarshalInfo(t)) - case "bytes": - if pointer { - if slice { - return makeMessageSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageMarshaler(getMarshalInfo(t)) - } else { - if slice { - return makeMessageRefSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageRefMarshaler(getMarshalInfo(t)) - } - } - } - panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) -} - -// Below are functions to size/marshal a specific type of a field. -// They are stored in the field's info, and called by function pointers. -// They have type sizer or marshaler. - -func sizeFixed32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixedS32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFloat32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - return (4 + tagsize) * len(s) -} -func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixed64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFixedS64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFloat64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - return (8 + tagsize) * len(s) -} -func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeVarint32Value(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarint32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarint64Value(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - return SizeVarint(v) + tagsize -} -func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return SizeVarint(v) + tagsize -} -func sizeVarint64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return SizeVarint(*p) + tagsize -} -func sizeVarint64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(v) + tagsize - } - return n -} -func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize - } - return n -} -func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize - } - return n -} -func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeBoolValue(_ pointer, tagsize int) int { - return 1 + tagsize -} -func sizeBoolValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toBool() - if !v { - return 0 - } - return 1 + tagsize -} -func sizeBoolPtr(ptr pointer, tagsize int) int { - p := *ptr.toBoolPtr() - if p == nil { - return 0 - } - return 1 + tagsize -} -func sizeBoolSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - return (1 + tagsize) * len(s) -} -func sizeBoolPackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return 0 - } - return len(s) + SizeVarint(uint64(len(s))) + tagsize -} -func sizeStringValue(ptr pointer, tagsize int) int { - v := *ptr.toString() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toString() - if v == "" { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringPtr(ptr pointer, tagsize int) int { - p := *ptr.toStringPtr() - if p == nil { - return 0 - } - v := *p - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringSlice(ptr pointer, tagsize int) int { - s := *ptr.toStringSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} -func sizeBytes(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if v == nil { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytes3(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if len(v) == 0 { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesOneof(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesSlice(ptr pointer, tagsize int) int { - s := *ptr.toBytesSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} - -// appendFixed32 appends an encoded fixed32 to b. -func appendFixed32(b []byte, v uint32) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24)) - return b -} - -// appendFixed64 appends an encoded fixed64 to b. -func appendFixed64(b []byte, v uint64) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - byte(v>>32), - byte(v>>40), - byte(v>>48), - byte(v>>56)) - return b -} - -// appendVarint appends an encoded varint to b. -func appendVarint(b []byte, v uint64) []byte { - // TODO: make 1-byte (maybe 2-byte) case inline-able, once we - // have non-leaf inliner. - switch { - case v < 1<<7: - b = append(b, byte(v)) - case v < 1<<14: - b = append(b, - byte(v&0x7f|0x80), - byte(v>>7)) - case v < 1<<21: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte(v>>14)) - case v < 1<<28: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte(v>>21)) - case v < 1<<35: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte(v>>28)) - case v < 1<<42: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte(v>>35)) - case v < 1<<49: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte(v>>42)) - case v < 1<<56: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte(v>>49)) - case v < 1<<63: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte(v>>56)) - default: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte((v>>56)&0x7f|0x80), - 1) - } - return b -} - -func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, *p) - return b, nil -} -func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(*p)) - return b, nil -} -func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(*p)) - return b, nil -} -func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, *p) - return b, nil -} -func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(*p)) - return b, nil -} -func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(*p)) - return b, nil -} -func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, *p) - return b, nil -} -func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - } - return b, nil -} -func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, v) - } - return b, nil -} -func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - if !v { - return b, nil - } - b = appendVarint(b, wiretag) - b = append(b, 1) - return b, nil -} - -func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toBoolPtr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - if *p { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(len(s))) - for _, v := range s { - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - if v == "" { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toStringSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} -func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if v == "" { - return b, nil - } - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - s := *ptr.toStringSlice() - for _, v := range s { - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if v == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if len(v) == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBytesSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} - -// makeGroupMarshaler returns the sizer and marshaler for a group. -// u is the marshal info of the underlying message. -func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - return u.size(p) + 2*tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - var err error - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, p, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - return b, err - } -} - -// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. -// u is the marshal info of the underlying message. -func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - n += u.size(v) + 2*tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, v, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMessageMarshaler returns the sizer and marshaler for a message field. -// u is the marshal info of the message. -func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.size(p) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(p) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, p, deterministic) - } -} - -// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. -// u is the marshal info of the message. -func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMapMarshaler returns the sizer and marshaler for a map field. -// f is the pointer to the reflect data structure of the field. -func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { - // figure out key and value type - t := f.Type - keyType := t.Key() - valType := t.Elem() - tags := strings.Split(f.Tag.Get("protobuf"), ",") - keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - stdOptions := false - for _, t := range tags { - if strings.HasPrefix(t, "customtype=") { - valTags = append(valTags, t) - } - if t == "stdtime" { - valTags = append(valTags, t) - stdOptions = true - } - if t == "stdduration" { - valTags = append(valTags, t) - stdOptions = true - } - if t == "wktptr" { - valTags = append(valTags, t) - } - } - keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map - valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map - keyWireTag := 1<<3 | wiretype(keyTags[0]) - valWireTag := 2<<3 | wiretype(valTags[0]) - - // We create an interface to get the addresses of the map key and value. - // If value is pointer-typed, the interface is a direct interface, the - // idata itself is the value. Otherwise, the idata is the pointer to the - // value. - // Key cannot be pointer-typed. - valIsPtr := valType.Kind() == reflect.Ptr - - // If value is a message with nested maps, calling - // valSizer in marshal may be quadratic. We should use - // cached version in marshal (but not in size). - // If value is not message type, we don't have size cache, - // but it cannot be nested either. Just use valSizer. - valCachedSizer := valSizer - if valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct { - u := getMarshalInfo(valType.Elem()) - valCachedSizer = func(ptr pointer, tagsize int) int { - // Same as message sizer, but use cache. - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.cachedsize(p) - return siz + SizeVarint(uint64(siz)) + tagsize - } - } - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(t).Elem() // the map - n := 0 - for _, k := range m.MapKeys() { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(t).Elem() // the map - var err error - keys := m.MapKeys() - if len(keys) > 1 && deterministic { - sort.Sort(mapKeys(keys)) - } - - var nerr nonFatal - for _, k := range keys { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value - b = appendVarint(b, tag) - siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - b = appendVarint(b, uint64(siz)) - b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) - if !nerr.Merge(err) { - return b, err - } - b, err = valMarshaler(b, vaddr, valWireTag, deterministic) - if err != ErrNil && !nerr.Merge(err) { // allow nil value in map - return b, err - } - } - return b, nerr.E - } -} - -// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. -// fi is the marshal info of the field. -// f is the pointer to the reflect data structure of the field. -func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { - // Oneof field is an interface. We need to get the actual data type on the fly. - t := f.Type - return func(ptr pointer, _ int) int { - p := ptr.getInterfacePointer() - if p.isNil() { - return 0 - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - e := fi.oneofElems[telem] - return e.sizer(p, e.tagsize) - }, - func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { - p := ptr.getInterfacePointer() - if p.isNil() { - return b, nil - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { - return b, errOneofHasNil - } - e := fi.oneofElems[telem] - return e.marshaler(b, p, e.wiretag, deterministic) - } -} - -// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. -func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - mu.Unlock() - return n -} - -// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. -func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - // Not sure this is required, but the old code does it. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// message set format is: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } - -// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field -// in message set format (above). -func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for id, e := range m { - n += 2 // start group, end group. tag = 1 (size=1) - n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - siz := len(msgWithLen) - n += siz + 1 // message, tag = 3 (size=1) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, 1) // message, tag = 3 (size=1) - } - mu.Unlock() - return n -} - -// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) -// to the end of byte slice b. -func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for id, e := range m { - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - if !nerr.Merge(err) { - return b, err - } - b = append(b, 1<<3|WireEndGroup) - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, id := range keys { - e := m[int32(id)] - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - b = append(b, 1<<3|WireEndGroup) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// sizeV1Extensions computes the size of encoded data for a V1-API extension field. -func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { - if m == nil { - return 0 - } - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - n += ei.sizer(p, ei.tagsize) - } - return n -} - -// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. -func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { - if m == nil { - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - var err error - var nerr nonFatal - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// newMarshaler is the interface representing objects that can marshal themselves. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newMarshaler interface { - XXX_Size() int - XXX_Marshal(b []byte, deterministic bool) ([]byte, error) -} - -// Size returns the encoded size of a protocol buffer message. -// This is the main entry point. -func Size(pb Message) int { - if m, ok := pb.(newMarshaler); ok { - return m.XXX_Size() - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, _ := m.Marshal() - return len(b) - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return 0 - } - var info InternalMessageInfo - return info.Size(pb) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, returning the data. -// This is the main entry point. -func Marshal(pb Message) ([]byte, error) { - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - b := make([]byte, 0, siz) - return m.XXX_Marshal(b, false) - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - return m.Marshal() - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return nil, ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - b := make([]byte, 0, siz) - return info.Marshal(b, pb, false) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, writing the result to the -// Buffer. -// This is an alternative entry point. It is not necessary to use -// a Buffer for most applications. -func (p *Buffer) Marshal(pb Message) error { - var err error - if p.deterministic { - if _, ok := pb.(Marshaler); ok { - return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", pb) - } - } - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - p.grow(siz) // make sure buf has enough capacity - pp := p.buf[len(p.buf) : len(p.buf) : len(p.buf)+siz] - pp, err = m.XXX_Marshal(pp, p.deterministic) - p.buf = append(p.buf, pp...) - return err - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - var b []byte - b, err = m.Marshal() - p.buf = append(p.buf, b...) - return err - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - p.grow(siz) // make sure buf has enough capacity - p.buf, err = info.Marshal(p.buf, pb, p.deterministic) - return err -} - -// grow grows the buffer's capacity, if necessary, to guarantee space for -// another n bytes. After grow(n), at least n bytes can be written to the -// buffer without another allocation. -func (p *Buffer) grow(n int) { - need := len(p.buf) + n - if need <= cap(p.buf) { - return - } - newCap := len(p.buf) * 2 - if newCap < need { - newCap = need - } - p.buf = append(make([]byte, 0, newCap), p.buf...) -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go deleted file mode 100644 index 997f57c1e1..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go +++ /dev/null @@ -1,388 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -// makeMessageRefMarshaler differs a bit from makeMessageMarshaler -// It marshal a message T instead of a *T -func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - siz := u.size(ptr) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - b = appendVarint(b, wiretag) - siz := u.cachedsize(ptr) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, ptr, deterministic) - } -} - -// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler -// It marshals a slice of messages []T instead of []*T -func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - e := elem.Interface() - v := toAddrPointer(&e, false) - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - var err, errreq error - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - e := elem.Interface() - v := toAddrPointer(&e, false) - b = appendVarint(b, wiretag) - siz := u.size(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if err != nil { - if _, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errreq == nil { - errreq = err - } - continue - } - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - - return b, errreq - } -} - -func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) - siz := m.Size() - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom) - siz := m.Size() - buf, err := m.Marshal() - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - return b, nil - } -} - -func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(u.typ).Interface().(custom) - siz := m.Size() - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(u.typ).Interface().(custom) - siz := m.Size() - buf, err := m.Marshal() - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - return b, nil - } -} - -func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(time.Time) - ts, err := timestampProto(t) - if err != nil { - return 0 - } - siz := Size(ts) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(time.Time) - ts, err := timestampProto(t) - if err != nil { - return nil, err - } - siz := Size(ts) - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return 0 - } - siz := Size(ts) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*time.Time) - ts, err := timestampProto(*t) - if err != nil { - return nil, err - } - siz := Size(ts) - buf, err := Marshal(ts) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - d := ptr.asPointerTo(u.typ).Interface().(*time.Duration) - dur := durationProto(*d) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration) - dur := durationProto(*d) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(time.Duration) - dur := durationProto(d) - siz := Size(dur) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(time.Duration) - dur := durationProto(d) - siz := Size(dur) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - d := elem.Interface().(*time.Duration) - dur := durationProto(*d) - siz := Size(dur) - buf, err := Marshal(dur) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_merge.go b/vendor/github.com/gogo/protobuf/proto/table_merge.go deleted file mode 100644 index 60dcf70d1e..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/table_merge.go +++ /dev/null @@ -1,676 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -// Merge merges the src message into dst. -// This assumes that dst and src of the same type and are non-nil. -func (a *InternalMessageInfo) Merge(dst, src Message) { - mi := atomicLoadMergeInfo(&a.merge) - if mi == nil { - mi = getMergeInfo(reflect.TypeOf(dst).Elem()) - atomicStoreMergeInfo(&a.merge, mi) - } - mi.merge(toPointer(&dst), toPointer(&src)) -} - -type mergeInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []mergeFieldInfo - unrecognized field // Offset of XXX_unrecognized -} - -type mergeFieldInfo struct { - field field // Offset of field, guaranteed to be valid - - // isPointer reports whether the value in the field is a pointer. - // This is true for the following situations: - // * Pointer to struct - // * Pointer to basic type (proto2 only) - // * Slice (first value in slice header is a pointer) - // * String (first value in string header is a pointer) - isPointer bool - - // basicWidth reports the width of the field assuming that it is directly - // embedded in the struct (as is the case for basic types in proto3). - // The possible values are: - // 0: invalid - // 1: bool - // 4: int32, uint32, float32 - // 8: int64, uint64, float64 - basicWidth int - - // Where dst and src are pointers to the types being merged. - merge func(dst, src pointer) -} - -var ( - mergeInfoMap = map[reflect.Type]*mergeInfo{} - mergeInfoLock sync.Mutex -) - -func getMergeInfo(t reflect.Type) *mergeInfo { - mergeInfoLock.Lock() - defer mergeInfoLock.Unlock() - mi := mergeInfoMap[t] - if mi == nil { - mi = &mergeInfo{typ: t} - mergeInfoMap[t] = mi - } - return mi -} - -// merge merges src into dst assuming they are both of type *mi.typ. -func (mi *mergeInfo) merge(dst, src pointer) { - if dst.isNil() { - panic("proto: nil destination") - } - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&mi.initialized) == 0 { - mi.computeMergeInfo() - } - - for _, fi := range mi.fields { - sfp := src.offset(fi.field) - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string - continue - } - if fi.basicWidth > 0 { - switch { - case fi.basicWidth == 1 && !*sfp.toBool(): - continue - case fi.basicWidth == 4 && *sfp.toUint32() == 0: - continue - case fi.basicWidth == 8 && *sfp.toUint64() == 0: - continue - } - } - } - - dfp := dst.offset(fi.field) - fi.merge(dfp, sfp) - } - - // TODO: Make this faster? - out := dst.asPointerTo(mi.typ).Elem() - in := src.asPointerTo(mi.typ).Elem() - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - if mi.unrecognized.IsValid() { - if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { - *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) - } - } -} - -func (mi *mergeInfo) computeMergeInfo() { - mi.lock.Lock() - defer mi.lock.Unlock() - if mi.initialized != 0 { - return - } - t := mi.typ - n := t.NumField() - - props := GetProperties(t) - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - mfi := mergeFieldInfo{field: toField(&f)} - tf := f.Type - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - switch tf.Kind() { - case reflect.Ptr, reflect.Slice, reflect.String: - // As a special case, we assume slices and strings are pointers - // since we know that the first field in the SliceSlice or - // StringHeader is a data pointer. - mfi.isPointer = true - case reflect.Bool: - mfi.basicWidth = 1 - case reflect.Int32, reflect.Uint32, reflect.Float32: - mfi.basicWidth = 4 - case reflect.Int64, reflect.Uint64, reflect.Float64: - mfi.basicWidth = 8 - } - } - - // Unwrap tf to get at its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + tf.Name()) - } - - switch tf.Kind() { - case reflect.Int32: - switch { - case isSlice: // E.g., []int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Slice is not defined (see pointer_reflect.go). - /* - sfsp := src.toInt32Slice() - if *sfsp != nil { - dfsp := dst.toInt32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - */ - sfs := src.getInt32Slice() - if sfs != nil { - dfs := dst.getInt32Slice() - dfs = append(dfs, sfs...) - if dfs == nil { - dfs = []int32{} - } - dst.setInt32Slice(dfs) - } - } - case isPointer: // E.g., *int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). - /* - sfpp := src.toInt32Ptr() - if *sfpp != nil { - dfpp := dst.toInt32Ptr() - if *dfpp == nil { - *dfpp = Int32(**sfpp) - } else { - **dfpp = **sfpp - } - } - */ - sfp := src.getInt32Ptr() - if sfp != nil { - dfp := dst.getInt32Ptr() - if dfp == nil { - dst.setInt32Ptr(*sfp) - } else { - *dfp = *sfp - } - } - } - default: // E.g., int32 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt32(); v != 0 { - *dst.toInt32() = v - } - } - } - case reflect.Int64: - switch { - case isSlice: // E.g., []int64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toInt64Slice() - if *sfsp != nil { - dfsp := dst.toInt64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - } - case isPointer: // E.g., *int64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toInt64Ptr() - if *sfpp != nil { - dfpp := dst.toInt64Ptr() - if *dfpp == nil { - *dfpp = Int64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., int64 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt64(); v != 0 { - *dst.toInt64() = v - } - } - } - case reflect.Uint32: - switch { - case isSlice: // E.g., []uint32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint32Slice() - if *sfsp != nil { - dfsp := dst.toUint32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint32{} - } - } - } - case isPointer: // E.g., *uint32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint32Ptr() - if *sfpp != nil { - dfpp := dst.toUint32Ptr() - if *dfpp == nil { - *dfpp = Uint32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint32 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint32(); v != 0 { - *dst.toUint32() = v - } - } - } - case reflect.Uint64: - switch { - case isSlice: // E.g., []uint64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint64Slice() - if *sfsp != nil { - dfsp := dst.toUint64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint64{} - } - } - } - case isPointer: // E.g., *uint64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint64Ptr() - if *sfpp != nil { - dfpp := dst.toUint64Ptr() - if *dfpp == nil { - *dfpp = Uint64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint64 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint64(); v != 0 { - *dst.toUint64() = v - } - } - } - case reflect.Float32: - switch { - case isSlice: // E.g., []float32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat32Slice() - if *sfsp != nil { - dfsp := dst.toFloat32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float32{} - } - } - } - case isPointer: // E.g., *float32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat32Ptr() - if *sfpp != nil { - dfpp := dst.toFloat32Ptr() - if *dfpp == nil { - *dfpp = Float32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float32 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat32(); v != 0 { - *dst.toFloat32() = v - } - } - } - case reflect.Float64: - switch { - case isSlice: // E.g., []float64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat64Slice() - if *sfsp != nil { - dfsp := dst.toFloat64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float64{} - } - } - } - case isPointer: // E.g., *float64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat64Ptr() - if *sfpp != nil { - dfpp := dst.toFloat64Ptr() - if *dfpp == nil { - *dfpp = Float64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float64 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat64(); v != 0 { - *dst.toFloat64() = v - } - } - } - case reflect.Bool: - switch { - case isSlice: // E.g., []bool - mfi.merge = func(dst, src pointer) { - sfsp := src.toBoolSlice() - if *sfsp != nil { - dfsp := dst.toBoolSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []bool{} - } - } - } - case isPointer: // E.g., *bool - mfi.merge = func(dst, src pointer) { - sfpp := src.toBoolPtr() - if *sfpp != nil { - dfpp := dst.toBoolPtr() - if *dfpp == nil { - *dfpp = Bool(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., bool - mfi.merge = func(dst, src pointer) { - if v := *src.toBool(); v { - *dst.toBool() = v - } - } - } - case reflect.String: - switch { - case isSlice: // E.g., []string - mfi.merge = func(dst, src pointer) { - sfsp := src.toStringSlice() - if *sfsp != nil { - dfsp := dst.toStringSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []string{} - } - } - } - case isPointer: // E.g., *string - mfi.merge = func(dst, src pointer) { - sfpp := src.toStringPtr() - if *sfpp != nil { - dfpp := dst.toStringPtr() - if *dfpp == nil { - *dfpp = String(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., string - mfi.merge = func(dst, src pointer) { - if v := *src.toString(); v != "" { - *dst.toString() = v - } - } - } - case reflect.Slice: - isProto3 := props.Prop[i].proto3 - switch { - case isPointer: - panic("bad pointer in byte slice case in " + tf.Name()) - case tf.Elem().Kind() != reflect.Uint8: - panic("bad element kind in byte slice case in " + tf.Name()) - case isSlice: // E.g., [][]byte - mfi.merge = func(dst, src pointer) { - sbsp := src.toBytesSlice() - if *sbsp != nil { - dbsp := dst.toBytesSlice() - for _, sb := range *sbsp { - if sb == nil { - *dbsp = append(*dbsp, nil) - } else { - *dbsp = append(*dbsp, append([]byte{}, sb...)) - } - } - if *dbsp == nil { - *dbsp = [][]byte{} - } - } - } - default: // E.g., []byte - mfi.merge = func(dst, src pointer) { - sbp := src.toBytes() - if *sbp != nil { - dbp := dst.toBytes() - if !isProto3 || len(*sbp) > 0 { - *dbp = append([]byte{}, *sbp...) - } - } - } - } - case reflect.Struct: - switch { - case isSlice && !isPointer: // E.g. []pb.T - mergeInfo := getMergeInfo(tf) - zero := reflect.Zero(tf) - mfi.merge = func(dst, src pointer) { - // TODO: Make this faster? - dstsp := dst.asPointerTo(f.Type) - dsts := dstsp.Elem() - srcs := src.asPointerTo(f.Type).Elem() - for i := 0; i < srcs.Len(); i++ { - dsts = reflect.Append(dsts, zero) - srcElement := srcs.Index(i).Addr() - dstElement := dsts.Index(dsts.Len() - 1).Addr() - mergeInfo.merge(valToPointer(dstElement), valToPointer(srcElement)) - } - if dsts.IsNil() { - dsts = reflect.MakeSlice(f.Type, 0, 0) - } - dstsp.Elem().Set(dsts) - } - case !isPointer: - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - mergeInfo.merge(dst, src) - } - case isSlice: // E.g., []*pb.T - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sps := src.getPointerSlice() - if sps != nil { - dps := dst.getPointerSlice() - for _, sp := range sps { - var dp pointer - if !sp.isNil() { - dp = valToPointer(reflect.New(tf)) - mergeInfo.merge(dp, sp) - } - dps = append(dps, dp) - } - if dps == nil { - dps = []pointer{} - } - dst.setPointerSlice(dps) - } - } - default: // E.g., *pb.T - mergeInfo := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sp := src.getPointer() - if !sp.isNil() { - dp := dst.getPointer() - if dp.isNil() { - dp = valToPointer(reflect.New(tf)) - dst.setPointer(dp) - } - mergeInfo.merge(dp, sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic("bad pointer or slice in map case in " + tf.Name()) - default: // E.g., map[K]V - mfi.merge = func(dst, src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - dm := dst.asPointerTo(tf).Elem() - if dm.IsNil() { - dm.Set(reflect.MakeMap(tf)) - } - - switch tf.Elem().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(Clone(val.Interface().(Message))) - dm.SetMapIndex(key, val) - } - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - dm.SetMapIndex(key, val) - } - default: // Basic type (e.g., string) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - dm.SetMapIndex(key, val) - } - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic("bad pointer or slice in interface case in " + tf.Name()) - default: // E.g., interface{} - // TODO: Make this faster? - mfi.merge = func(dst, src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - du := dst.asPointerTo(tf).Elem() - typ := su.Elem().Type() - if du.IsNil() || du.Elem().Type() != typ { - du.Set(reflect.New(typ.Elem())) // Initialize interface if empty - } - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - dv := du.Elem().Elem().Field(0) - if dv.Kind() == reflect.Ptr && dv.IsNil() { - dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - Merge(dv.Interface().(Message), sv.Interface().(Message)) - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) - default: // Basic type (e.g., string) - dv.Set(sv) - } - } - } - } - default: - panic(fmt.Sprintf("merger not found for type:%s", tf)) - } - mi.fields = append(mi.fields, mfi) - } - - mi.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - mi.unrecognized = toField(&f) - } - - atomic.StoreInt32(&mi.initialized, 1) -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go deleted file mode 100644 index 937229386a..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/table_unmarshal.go +++ /dev/null @@ -1,2249 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// Unmarshal is the entry point from the generated .pb.go files. -// This function is not intended to be used by non-generated code. -// This function is not subject to any compatibility guarantee. -// msg contains a pointer to a protocol buffer struct. -// b is the data to be unmarshaled into the protocol buffer. -// a is a pointer to a place to store cached unmarshal information. -func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { - // Load the unmarshal information for this message type. - // The atomic load ensures memory consistency. - u := atomicLoadUnmarshalInfo(&a.unmarshal) - if u == nil { - // Slow path: find unmarshal info for msg, update a with it. - u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) - atomicStoreUnmarshalInfo(&a.unmarshal, u) - } - // Then do the unmarshaling. - err := u.unmarshal(toPointer(&msg), b) - return err -} - -type unmarshalInfo struct { - typ reflect.Type // type of the protobuf struct - - // 0 = only typ field is initialized - // 1 = completely initialized - initialized int32 - lock sync.Mutex // prevents double initialization - dense []unmarshalFieldInfo // fields indexed by tag # - sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # - reqFields []string // names of required fields - reqMask uint64 // 1< 0 { - // Read tag and wire type. - // Special case 1 and 2 byte varints. - var x uint64 - if b[0] < 128 { - x = uint64(b[0]) - b = b[1:] - } else if len(b) >= 2 && b[1] < 128 { - x = uint64(b[0]&0x7f) + uint64(b[1])<<7 - b = b[2:] - } else { - var n int - x, n = decodeVarint(b) - if n == 0 { - return io.ErrUnexpectedEOF - } - b = b[n:] - } - tag := x >> 3 - wire := int(x) & 7 - - // Dispatch on the tag to one of the unmarshal* functions below. - var f unmarshalFieldInfo - if tag < uint64(len(u.dense)) { - f = u.dense[tag] - } else { - f = u.sparse[tag] - } - if fn := f.unmarshal; fn != nil { - var err error - b, err = fn(b, m.offset(f.field), wire) - if err == nil { - reqMask |= f.reqMask - continue - } - if r, ok := err.(*RequiredNotSetError); ok { - // Remember this error, but keep parsing. We need to produce - // a full parse even if a required field is missing. - if errLater == nil { - errLater = r - } - reqMask |= f.reqMask - continue - } - if err != errInternalBadWireType { - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return err - } - // Fragments with bad wire type are treated as unknown fields. - } - - // Unknown tag. - if !u.unrecognized.IsValid() { - // Don't keep unrecognized data; just skip it. - var err error - b, err = skipField(b, wire) - if err != nil { - return err - } - continue - } - // Keep unrecognized data around. - // maybe in extensions, maybe in the unrecognized field. - z := m.offset(u.unrecognized).toBytes() - var emap map[int32]Extension - var e Extension - for _, r := range u.extensionRanges { - if uint64(r.Start) <= tag && tag <= uint64(r.End) { - if u.extensions.IsValid() { - mp := m.offset(u.extensions).toExtensions() - emap = mp.extensionsWrite() - e = emap[int32(tag)] - z = &e.enc - break - } - if u.oldExtensions.IsValid() { - p := m.offset(u.oldExtensions).toOldExtensions() - emap = *p - if emap == nil { - emap = map[int32]Extension{} - *p = emap - } - e = emap[int32(tag)] - z = &e.enc - break - } - if u.bytesExtensions.IsValid() { - z = m.offset(u.bytesExtensions).toBytes() - break - } - panic("no extensions field available") - } - } - // Use wire type to skip data. - var err error - b0 := b - b, err = skipField(b, wire) - if err != nil { - return err - } - *z = encodeVarint(*z, tag<<3|uint64(wire)) - *z = append(*z, b0[:len(b0)-len(b)]...) - - if emap != nil { - emap[int32(tag)] = e - } - } - if reqMask != u.reqMask && errLater == nil { - // A required field of this message is missing. - for _, n := range u.reqFields { - if reqMask&1 == 0 { - errLater = &RequiredNotSetError{n} - } - reqMask >>= 1 - } - } - return errLater -} - -// computeUnmarshalInfo fills in u with information for use -// in unmarshaling protocol buffers of type u.typ. -func (u *unmarshalInfo) computeUnmarshalInfo() { - u.lock.Lock() - defer u.lock.Unlock() - if u.initialized != 0 { - return - } - t := u.typ - n := t.NumField() - - // Set up the "not found" value for the unrecognized byte buffer. - // This is the default for proto3. - u.unrecognized = invalidField - u.extensions = invalidField - u.oldExtensions = invalidField - u.bytesExtensions = invalidField - - // List of the generated type and offset for each oneof field. - type oneofField struct { - ityp reflect.Type // interface type of oneof field - field field // offset in containing message - } - var oneofFields []oneofField - - for i := 0; i < n; i++ { - f := t.Field(i) - if f.Name == "XXX_unrecognized" { - // The byte slice used to hold unrecognized input is special. - if f.Type != reflect.TypeOf(([]byte)(nil)) { - panic("bad type for XXX_unrecognized field: " + f.Type.Name()) - } - u.unrecognized = toField(&f) - continue - } - if f.Name == "XXX_InternalExtensions" { - // Ditto here. - if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { - panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) - } - u.extensions = toField(&f) - if f.Tag.Get("protobuf_messageset") == "1" { - u.isMessageSet = true - } - continue - } - if f.Name == "XXX_extensions" { - // An older form of the extensions field. - if f.Type == reflect.TypeOf((map[int32]Extension)(nil)) { - u.oldExtensions = toField(&f) - continue - } else if f.Type == reflect.TypeOf(([]byte)(nil)) { - u.bytesExtensions = toField(&f) - continue - } - panic("bad type for XXX_extensions field: " + f.Type.Name()) - } - if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { - continue - } - - oneof := f.Tag.Get("protobuf_oneof") - if oneof != "" { - oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) - // The rest of oneof processing happens below. - continue - } - - tags := f.Tag.Get("protobuf") - tagArray := strings.Split(tags, ",") - if len(tagArray) < 2 { - panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) - } - tag, err := strconv.Atoi(tagArray[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tagArray[1]) - } - - name := "" - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - } - - // Extract unmarshaling function from the field (its type and tags). - unmarshal := fieldUnmarshaler(&f) - - // Required field? - var reqMask uint64 - if tagArray[2] == "req" { - bit := len(u.reqFields) - u.reqFields = append(u.reqFields, name) - reqMask = uint64(1) << uint(bit) - // TODO: if we have more than 64 required fields, we end up - // not verifying that all required fields are present. - // Fix this, perhaps using a count of required fields? - } - - // Store the info in the correct slot in the message. - u.setTag(tag, toField(&f), unmarshal, reqMask, name) - } - - // Find any types associated with oneof fields. - // gogo: len(oneofFields) > 0 is needed for embedded oneof messages, without a marshaler and unmarshaler - if len(oneofFields) > 0 { - var oneofImplementers []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - for _, v := range oneofImplementers { - tptr := reflect.TypeOf(v) // *Msg_X - typ := tptr.Elem() // Msg_X - - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tags := strings.Split(f.Tag.Get("protobuf"), ",") - fieldNum, err := strconv.Atoi(tags[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tags[1]) - } - var name string - for _, tag := range tags { - if strings.HasPrefix(tag, "name=") { - name = strings.TrimPrefix(tag, "name=") - break - } - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(fieldNum, of.field, unmarshal, 0, name) - } - } - - } - } - - // Get extension ranges, if any. - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") - if fn.IsValid() { - if !u.extensions.IsValid() && !u.oldExtensions.IsValid() && !u.bytesExtensions.IsValid() { - panic("a message with extensions, but no extensions field in " + t.Name()) - } - u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) - } - - // Explicitly disallow tag 0. This will ensure we flag an error - // when decoding a buffer of all zeros. Without this code, we - // would decode and skip an all-zero buffer of even length. - // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. - u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { - return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) - }, 0, "") - - // Set mask for required field check. - u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? - for len(u.dense) <= tag { - u.dense = append(u.dense, unmarshalFieldInfo{}) - } - u.dense[tag] = i - return - } - if u.sparse == nil { - u.sparse = map[uint64]unmarshalFieldInfo{} - } - u.sparse[uint64(tag)] = i -} - -// fieldUnmarshaler returns an unmarshaler for the given field. -func fieldUnmarshaler(f *reflect.StructField) unmarshaler { - if f.Type.Kind() == reflect.Map { - return makeUnmarshalMap(f) - } - return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) -} - -// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. -func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { - tagArray := strings.Split(tags, ",") - encoding := tagArray[0] - name := "unknown" - ctype := false - isTime := false - isDuration := false - isWktPointer := false - proto3 := false - validateUTF8 := true - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - if tag == "proto3" { - proto3 = true - } - if strings.HasPrefix(tag, "customtype=") { - ctype = true - } - if tag == "stdtime" { - isTime = true - } - if tag == "stdduration" { - isDuration = true - } - if tag == "wktptr" { - isWktPointer = true - } - } - validateUTF8 = validateUTF8 && proto3 - - // Figure out packaging (pointer, slice, or both) - slice := false - pointer := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - if ctype { - if reflect.PtrTo(t).Implements(customType) { - if slice { - return makeUnmarshalCustomSlice(getUnmarshalInfo(t), name) - } - if pointer { - return makeUnmarshalCustomPtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalCustom(getUnmarshalInfo(t), name) - } else { - panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t)) - } - } - - if isTime { - if pointer { - if slice { - return makeUnmarshalTimePtrSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalTimePtr(getUnmarshalInfo(t), name) - } - if slice { - return makeUnmarshalTimeSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalTime(getUnmarshalInfo(t), name) - } - - if isDuration { - if pointer { - if slice { - return makeUnmarshalDurationPtrSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalDurationPtr(getUnmarshalInfo(t), name) - } - if slice { - return makeUnmarshalDurationSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalDuration(getUnmarshalInfo(t), name) - } - - if isWktPointer { - switch t.Kind() { - case reflect.Float64: - if pointer { - if slice { - return makeStdDoubleValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdDoubleValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdDoubleValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdDoubleValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Float32: - if pointer { - if slice { - return makeStdFloatValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdFloatValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdFloatValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdFloatValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Int64: - if pointer { - if slice { - return makeStdInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt64ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Uint64: - if pointer { - if slice { - return makeStdUInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdUInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt64ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Int32: - if pointer { - if slice { - return makeStdInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdInt32ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Uint32: - if pointer { - if slice { - return makeStdUInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdUInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdUInt32ValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.Bool: - if pointer { - if slice { - return makeStdBoolValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBoolValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdBoolValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBoolValueUnmarshaler(getUnmarshalInfo(t), name) - case reflect.String: - if pointer { - if slice { - return makeStdStringValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdStringValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdStringValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdStringValueUnmarshaler(getUnmarshalInfo(t), name) - case uint8SliceType: - if pointer { - if slice { - return makeStdBytesValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBytesValuePtrUnmarshaler(getUnmarshalInfo(t), name) - } - if slice { - return makeStdBytesValueSliceUnmarshaler(getUnmarshalInfo(t), name) - } - return makeStdBytesValueUnmarshaler(getUnmarshalInfo(t), name) - default: - panic(fmt.Sprintf("unknown wktpointer type %#v", t)) - } - } - - // We'll never have both pointer and slice for basic types. - if pointer && slice && t.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + t.Name()) - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return unmarshalBoolPtr - } - if slice { - return unmarshalBoolSlice - } - return unmarshalBoolValue - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixedS32Ptr - } - if slice { - return unmarshalFixedS32Slice - } - return unmarshalFixedS32Value - case "varint": - // this could be int32 or enum - if pointer { - return unmarshalInt32Ptr - } - if slice { - return unmarshalInt32Slice - } - return unmarshalInt32Value - case "zigzag32": - if pointer { - return unmarshalSint32Ptr - } - if slice { - return unmarshalSint32Slice - } - return unmarshalSint32Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixedS64Ptr - } - if slice { - return unmarshalFixedS64Slice - } - return unmarshalFixedS64Value - case "varint": - if pointer { - return unmarshalInt64Ptr - } - if slice { - return unmarshalInt64Slice - } - return unmarshalInt64Value - case "zigzag64": - if pointer { - return unmarshalSint64Ptr - } - if slice { - return unmarshalSint64Slice - } - return unmarshalSint64Value - } - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixed32Ptr - } - if slice { - return unmarshalFixed32Slice - } - return unmarshalFixed32Value - case "varint": - if pointer { - return unmarshalUint32Ptr - } - if slice { - return unmarshalUint32Slice - } - return unmarshalUint32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixed64Ptr - } - if slice { - return unmarshalFixed64Slice - } - return unmarshalFixed64Value - case "varint": - if pointer { - return unmarshalUint64Ptr - } - if slice { - return unmarshalUint64Slice - } - return unmarshalUint64Value - } - case reflect.Float32: - if pointer { - return unmarshalFloat32Ptr - } - if slice { - return unmarshalFloat32Slice - } - return unmarshalFloat32Value - case reflect.Float64: - if pointer { - return unmarshalFloat64Ptr - } - if slice { - return unmarshalFloat64Slice - } - return unmarshalFloat64Value - case reflect.Map: - panic("map type in typeUnmarshaler in " + t.Name()) - case reflect.Slice: - if pointer { - panic("bad pointer in slice case in " + t.Name()) - } - if slice { - return unmarshalBytesSlice - } - return unmarshalBytesValue - case reflect.String: - if validateUTF8 { - if pointer { - return unmarshalUTF8StringPtr - } - if slice { - return unmarshalUTF8StringSlice - } - return unmarshalUTF8StringValue - } - if pointer { - return unmarshalStringPtr - } - if slice { - return unmarshalStringSlice - } - return unmarshalStringValue - case reflect.Struct: - // message or group field - if !pointer { - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlice(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessage(getUnmarshalInfo(t), name) - } - } - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) - case "group": - if slice { - return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) - } - } - panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) -} - -// Below are all the unmarshalers for individual fields of various types. - -func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64() = v - return b, nil -} - -func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64() = v - return b, nil -} - -func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64() = v - return b, nil -} - -func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64Ptr() = &v - return b, nil -} - -func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - *f.toInt32() = v - return b, nil -} - -func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - *f.toInt32() = v - return b, nil -} - -func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32() = v - return b, nil -} - -func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32Ptr() = &v - return b, nil -} - -func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64() = v - return b[8:], nil -} - -func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64() = v - return b[8:], nil -} - -func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32() = v - return b[4:], nil -} - -func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32Ptr() = &v - return b[4:], nil -} - -func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - *f.toInt32() = v - return b[4:], nil -} - -func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.setInt32Ptr(v) - return b[4:], nil -} - -func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - return b[4:], nil -} - -func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - // Note: any length varint is allowed, even though any sane - // encoder will use one byte. - // See https://github.com/golang/protobuf/issues/76 - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - // TODO: check if x>1? Tests seem to indicate no. - v := x != 0 - *f.toBool() = v - return b[n:], nil -} - -func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - *f.toBoolPtr() = &v - return b[n:], nil -} - -func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - b = b[n:] - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - return b[n:], nil -} - -func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64() = v - return b[8:], nil -} - -func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64Ptr() = &v - return b[8:], nil -} - -func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32() = v - return b[4:], nil -} - -func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32Ptr() = &v - return b[4:], nil -} - -func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - return b[x:], nil -} - -func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - return b[x:], nil -} - -func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - return b[x:], nil -} - -func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -var emptyBuf [0]byte - -func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // The use of append here is a trick which avoids the zeroing - // that would be required if we used a make/copy pair. - // We append to emptyBuf instead of nil because we want - // a non-nil result even when the length is 0. - v := append(emptyBuf[:], b[:x]...) - *f.toBytes() = v - return b[x:], nil -} - -func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := append(emptyBuf[:], b[:x]...) - s := f.toBytesSlice() - *s = append(*s, v) - return b[x:], nil -} - -func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[y:], err - } -} - -func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[y:], err - } -} - -func makeUnmarshalMap(f *reflect.StructField) unmarshaler { - t := f.Type - kt := t.Key() - vt := t.Elem() - tagArray := strings.Split(f.Tag.Get("protobuf"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - for _, t := range tagArray { - if strings.HasPrefix(t, "customtype=") { - valTags = append(valTags, t) - } - if t == "stdtime" { - valTags = append(valTags, t) - } - if t == "stdduration" { - valTags = append(valTags, t) - } - if t == "wktptr" { - valTags = append(valTags, t) - } - } - unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) - unmarshalVal := typeUnmarshaler(vt, strings.Join(valTags, ",")) - return func(b []byte, f pointer, w int) ([]byte, error) { - // The map entry is a submessage. Figure out how big it is. - if w != WireBytes { - return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - r := b[x:] // unused data to return - b = b[:x] // data for map entry - - // Note: we could use #keys * #values ~= 200 functions - // to do map decoding without reflection. Probably not worth it. - // Maps will be somewhat slow. Oh well. - - // Read key and value from data. - var nerr nonFatal - k := reflect.New(kt) - v := reflect.New(vt) - for len(b) > 0 { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - wire := int(x) & 7 - b = b[n:] - - var err error - switch x >> 3 { - case 1: - b, err = unmarshalKey(b, valToPointer(k), wire) - case 2: - b, err = unmarshalVal(b, valToPointer(v), wire) - default: - err = errInternalBadWireType // skip unknown tag - } - - if nerr.Merge(err) { - continue - } - if err != errInternalBadWireType { - return nil, err - } - - // Skip past unknown fields. - b, err = skipField(b, wire) - if err != nil { - return nil, err - } - } - - // Get map, allocate if needed. - m := f.asPointerTo(t).Elem() // an addressable map[K]T - if m.IsNil() { - m.Set(reflect.MakeMap(t)) - } - - // Insert into map. - m.SetMapIndex(k.Elem(), v.Elem()) - - return r, nerr.E - } -} - -// makeUnmarshalOneof makes an unmarshaler for oneof fields. -// for: -// message Msg { -// oneof F { -// int64 X = 1; -// float64 Y = 2; -// } -// } -// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). -// ityp is the interface type of the oneof field (e.g. isMsg_F). -// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). -// Note that this function will be called once for each case in the oneof. -func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { - sf := typ.Field(0) - field0 := toField(&sf) - return func(b []byte, f pointer, w int) ([]byte, error) { - // Allocate holder for value. - v := reflect.New(typ) - - // Unmarshal data into holder. - // We unmarshal into the first field of the holder object. - var err error - var nerr nonFatal - b, err = unmarshal(b, valToPointer(v).offset(field0), w) - if !nerr.Merge(err) { - return nil, err - } - - // Write pointer to holder into target field. - f.asPointerTo(ityp).Elem().Set(v) - - return b, nerr.E - } -} - -// Error used by decode internally. -var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") - -// skipField skips past a field of type wire and returns the remaining bytes. -func skipField(b []byte, wire int) ([]byte, error) { - switch wire { - case WireVarint: - _, k := decodeVarint(b) - if k == 0 { - return b, io.ErrUnexpectedEOF - } - b = b[k:] - case WireFixed32: - if len(b) < 4 { - return b, io.ErrUnexpectedEOF - } - b = b[4:] - case WireFixed64: - if len(b) < 8 { - return b, io.ErrUnexpectedEOF - } - b = b[8:] - case WireBytes: - m, k := decodeVarint(b) - if k == 0 || uint64(len(b)-k) < m { - return b, io.ErrUnexpectedEOF - } - b = b[uint64(k)+m:] - case WireStartGroup: - _, i := findEndGroup(b) - if i == -1 { - return b, io.ErrUnexpectedEOF - } - b = b[i:] - default: - return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) - } - return b, nil -} - -// findEndGroup finds the index of the next EndGroup tag. -// Groups may be nested, so the "next" EndGroup tag is the first -// unpaired EndGroup. -// findEndGroup returns the indexes of the start and end of the EndGroup tag. -// Returns (-1,-1) if it can't find one. -func findEndGroup(b []byte) (int, int) { - depth := 1 - i := 0 - for { - x, n := decodeVarint(b[i:]) - if n == 0 { - return -1, -1 - } - j := i - i += n - switch x & 7 { - case WireVarint: - _, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - case WireFixed32: - if len(b)-4 < i { - return -1, -1 - } - i += 4 - case WireFixed64: - if len(b)-8 < i { - return -1, -1 - } - i += 8 - case WireBytes: - m, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - if uint64(len(b)-i) < m { - return -1, -1 - } - i += int(m) - case WireStartGroup: - depth++ - case WireEndGroup: - depth-- - if depth == 0 { - return j, i - } - default: - return -1, -1 - } - } -} - -// encodeVarint appends a varint-encoded integer to b and returns the result. -func encodeVarint(b []byte, x uint64) []byte { - for x >= 1<<7 { - b = append(b, byte(x&0x7f|0x80)) - x >>= 7 - } - return append(b, byte(x)) -} - -// decodeVarint reads a varint-encoded integer from b. -// Returns the decoded integer and the number of bytes read. -// If there is an error, it returns 0,0. -func decodeVarint(b []byte) (uint64, int) { - var x, y uint64 - if len(b) == 0 { - goto bad - } - x = uint64(b[0]) - if x < 0x80 { - return x, 1 - } - x -= 0x80 - - if len(b) <= 1 { - goto bad - } - y = uint64(b[1]) - x += y << 7 - if y < 0x80 { - return x, 2 - } - x -= 0x80 << 7 - - if len(b) <= 2 { - goto bad - } - y = uint64(b[2]) - x += y << 14 - if y < 0x80 { - return x, 3 - } - x -= 0x80 << 14 - - if len(b) <= 3 { - goto bad - } - y = uint64(b[3]) - x += y << 21 - if y < 0x80 { - return x, 4 - } - x -= 0x80 << 21 - - if len(b) <= 4 { - goto bad - } - y = uint64(b[4]) - x += y << 28 - if y < 0x80 { - return x, 5 - } - x -= 0x80 << 28 - - if len(b) <= 5 { - goto bad - } - y = uint64(b[5]) - x += y << 35 - if y < 0x80 { - return x, 6 - } - x -= 0x80 << 35 - - if len(b) <= 6 { - goto bad - } - y = uint64(b[6]) - x += y << 42 - if y < 0x80 { - return x, 7 - } - x -= 0x80 << 42 - - if len(b) <= 7 { - goto bad - } - y = uint64(b[7]) - x += y << 49 - if y < 0x80 { - return x, 8 - } - x -= 0x80 << 49 - - if len(b) <= 8 { - goto bad - } - y = uint64(b[8]) - x += y << 56 - if y < 0x80 { - return x, 9 - } - x -= 0x80 << 56 - - if len(b) <= 9 { - goto bad - } - y = uint64(b[9]) - x += y << 63 - if y < 2 { - return x, 10 - } - -bad: - return 0, 0 -} diff --git a/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go b/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go deleted file mode 100644 index 00d6c7ad93..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go +++ /dev/null @@ -1,385 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "io" - "reflect" -) - -func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f // gogo: changed from v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.New(sub.typ)) - m := s.Interface().(custom) - if err := m.Unmarshal(b[:x]); err != nil { - return nil, err - } - return b[x:], nil - } -} - -func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := reflect.New(sub.typ) - c := m.Interface().(custom) - if err := c.Unmarshal(b[:x]); err != nil { - return nil, err - } - v := valToPointer(m) - f.appendRef(v, sub.typ) - return b[x:], nil - } -} - -func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - - m := f.asPointerTo(sub.typ).Interface().(custom) - if err := m.Unmarshal(b[:x]); err != nil { - return nil, err - } - return b[x:], nil - } -} - -func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(t)) - return b[x:], nil - } -} - -func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&t)) - return b[x:], nil - } -} - -func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&t)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := ×tamp{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - t, err := timestampFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(t)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&d)) - return b[x:], nil - } -} - -func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(d)) - return b[x:], nil - } -} - -func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&d)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &duration{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - d, err := durationFromProto(m) - if err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(d)) - slice.Set(newSlice) - return b[x:], nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/text.go b/vendor/github.com/gogo/protobuf/proto/text.go deleted file mode 100644 index 87416afe95..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/text.go +++ /dev/null @@ -1,930 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for writing the text protocol buffer format. - -import ( - "bufio" - "bytes" - "encoding" - "errors" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" - "sync" - "time" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - endBraceNewline = []byte("}\n") - backslashN = []byte{'\\', 'n'} - backslashR = []byte{'\\', 'r'} - backslashT = []byte{'\\', 't'} - backslashDQ = []byte{'\\', '"'} - backslashBS = []byte{'\\', '\\'} - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -type writer interface { - io.Writer - WriteByte(byte) error -} - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - ind int - complete bool // if the current position is a complete line - compact bool // whether to write out as a one-liner - w writer -} - -func (w *textWriter) WriteString(s string) (n int, err error) { - if !strings.Contains(s, "\n") { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - return io.WriteString(w.w, s) - } - // WriteString is typically called without newlines, so this - // codepath and its copy are rare. We copy to avoid - // duplicating all of Write's logic here. - return w.Write([]byte(s)) -} - -func (w *textWriter) Write(p []byte) (n int, err error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - n, err = w.w.Write(p) - w.complete = false - return n, err - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - if err := w.w.WriteByte(' '); err != nil { - return n, err - } - n++ - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - if i+1 < len(frags) { - if err := w.w.WriteByte('\n'); err != nil { - return n, err - } - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - err := w.w.WriteByte(c) - w.complete = c == '\n' - return err -} - -func (w *textWriter) indent() { w.ind++ } - -func (w *textWriter) unindent() { - if w.ind == 0 { - log.Print("proto: textWriter unindented too far") - return - } - w.ind-- -} - -func writeName(w *textWriter, props *Properties) error { - if _, err := w.WriteString(props.OrigName); err != nil { - return err - } - if props.Wire != "group" { - return w.WriteByte(':') - } - return nil -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// isAny reports whether sv is a google.protobuf.Any message -func isAny(sv reflect.Value) bool { - type wkt interface { - XXX_WellKnownType() string - } - t, ok := sv.Addr().Interface().(wkt) - return ok && t.XXX_WellKnownType() == "Any" -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { - turl := sv.FieldByName("TypeUrl") - val := sv.FieldByName("Value") - if !turl.IsValid() || !val.IsValid() { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - b, ok := val.Interface().([]byte) - if !ok { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - parts := strings.Split(turl.String(), "/") - mt := MessageType(parts[len(parts)-1]) - if mt == nil { - return false, nil - } - m := reflect.New(mt.Elem()) - if err := Unmarshal(b, m.Interface().(Message)); err != nil { - return false, nil - } - w.Write([]byte("[")) - u := turl.String() - if requiresQuotes(u) { - writeString(w, u) - } else { - w.Write([]byte(u)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.ind++ - } - if err := tm.writeStruct(w, m.Elem()); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.ind-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { - if tm.ExpandAny && isAny(sv) { - if canExpand, err := tm.writeProto3Any(w, sv); canExpand { - return err - } - } - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < sv.NumField(); i++ { - fv := sv.Field(i) - props := sprops.Prop[i] - name := st.Field(i).Name - - if name == "XXX_NoUnkeyedLiteral" { - continue - } - - if strings.HasPrefix(name, "XXX_") { - // There are two XXX_ fields: - // XXX_unrecognized []byte - // XXX_extensions map[int32]proto.Extension - // The first is handled here; - // the second is handled at the bottom of this function. - if name == "XXX_unrecognized" && !fv.IsNil() { - if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Field not filled in. This could be an optional field or - // a required field that wasn't filled in. Either way, there - // isn't anything we can show for it. - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - // Repeated field that is empty, or a bytes field that is unused. - continue - } - - if props.Repeated && fv.Kind() == reflect.Slice { - // Repeated field. - for j := 0; j < fv.Len(); j++ { - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - v := fv.Index(j) - if v.Kind() == reflect.Ptr && v.IsNil() { - // A nil message in a repeated field is not valid, - // but we can handle that more gracefully than panicking. - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - continue - } - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, v, props); err != nil { - return err - } - } else if err := tm.writeAny(w, v, props); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Map { - // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := fv.MapIndex(key) - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - // open struct - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - // key - if _, err := w.WriteString("key:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - // nil values aren't legal, but we can avoid panicking because of them. - if val.Kind() != reflect.Ptr || !val.IsNil() { - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, val, props.MapValProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - // close struct - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { - // empty bytes field - continue - } - if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { - // proto3 non-repeated scalar field; skip if zero value - if isProto3Zero(fv) { - continue - } - } - - if fv.Kind() == reflect.Interface { - // Check if it is a oneof. - if st.Field(i).Tag.Get("protobuf_oneof") != "" { - // fv is nil, or holds a pointer to generated struct. - // That generated struct has exactly one field, - // which has a protobuf struct tag. - if fv.IsNil() { - continue - } - inner := fv.Elem().Elem() // interface -> *T -> T - tag := inner.Type().Field(0).Tag.Get("protobuf") - props = new(Properties) // Overwrite the outer props var, but not its pointee. - props.Parse(tag) - // Write the value in the oneof, not the oneof itself. - fv = inner.Field(0) - - // Special case to cope with malformed messages gracefully: - // If the value in the oneof is a nil pointer, don't panic - // in writeAny. - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Use errors.New so writeAny won't render quotes. - msg := errors.New("/* nil */") - fv = reflect.ValueOf(&msg).Elem() - } - } - } - - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - - if len(props.Enum) > 0 { - if err := tm.writeEnum(w, fv, props); err != nil { - return err - } - } else if err := tm.writeAny(w, fv, props); err != nil { - return err - } - - if err := w.WriteByte('\n'); err != nil { - return err - } - } - - // Extensions (the XXX_extensions field). - pv := sv - if pv.CanAddr() { - pv = sv.Addr() - } else { - pv = reflect.New(sv.Type()) - pv.Elem().Set(sv) - } - if _, err := extendable(pv.Interface()); err == nil { - if err := tm.writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - -// writeAny writes an arbitrary field. -func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { - v = reflect.Indirect(v) - - if props != nil { - if len(props.CustomType) > 0 { - custom, ok := v.Interface().(Marshaler) - if ok { - data, err := custom.Marshal() - if err != nil { - return err - } - if err := writeString(w, string(data)); err != nil { - return err - } - return nil - } - } else if len(props.CastType) > 0 { - if _, ok := v.Interface().(interface { - String() string - }); ok { - switch v.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - _, err := fmt.Fprintf(w, "%d", v.Interface()) - return err - } - } - } else if props.StdTime { - t, ok := v.Interface().(time.Time) - if !ok { - return fmt.Errorf("stdtime is not time.Time, but %T", v.Interface()) - } - tproto, err := timestampProto(t) - if err != nil { - return err - } - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdTime = false - err = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy) - return err - } else if props.StdDuration { - d, ok := v.Interface().(time.Duration) - if !ok { - return fmt.Errorf("stdtime is not time.Duration, but %T", v.Interface()) - } - dproto := durationProto(d) - propsCopy := *props // Make a copy so that this is goroutine-safe - propsCopy.StdDuration = false - err := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy) - return err - } - } - - // Floats have special cases. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - x := v.Float() - var b []byte - switch { - case math.IsInf(x, 1): - b = posInf - case math.IsInf(x, -1): - b = negInf - case math.IsNaN(x): - b = nan - } - if b != nil { - _, err := w.Write(b) - return err - } - // Other values are handled below. - } - - // We don't attempt to serialise every possible value type; only those - // that can occur in protocol buffers. - switch v.Kind() { - case reflect.Slice: - // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Bytes())); err != nil { - return err - } - case reflect.String: - if err := writeString(w, v.String()); err != nil { - return err - } - case reflect.Struct: - // Required/optional group/message. - var bra, ket byte = '<', '>' - if props != nil && props.Wire == "group" { - bra, ket = '{', '}' - } - if err := w.WriteByte(bra); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if v.CanAddr() { - // Calling v.Interface on a struct causes the reflect package to - // copy the entire struct. This is racy with the new Marshaler - // since we atomically update the XXX_sizecache. - // - // Thus, we retrieve a pointer to the struct if possible to avoid - // a race since v.Interface on the pointer doesn't copy the struct. - // - // If v is not addressable, then we are not worried about a race - // since it implies that the binary Marshaler cannot possibly be - // mutating this value. - v = v.Addr() - } - if v.Type().Implements(textMarshalerType) { - text, err := v.Interface().(encoding.TextMarshaler).MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if err := tm.writeStruct(w, v); err != nil { - return err - } - } - w.unindent() - if err := w.WriteByte(ket); err != nil { - return err - } - default: - _, err := fmt.Fprint(w, v.Interface()) - return err - } - return nil -} - -// equivalent to C's isprint. -func isprint(c byte) bool { - return c >= 0x20 && c < 0x7f -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(w *textWriter, s string) error { - // use WriteByte here to get any needed indent - if err := w.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = w.w.Write(backslashN) - case '\r': - _, err = w.w.Write(backslashR) - case '\t': - _, err = w.w.Write(backslashT) - case '"': - _, err = w.w.Write(backslashDQ) - case '\\': - _, err = w.w.Write(backslashBS) - default: - if isprint(c) { - err = w.w.WriteByte(c) - } else { - _, err = fmt.Fprintf(w.w, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return w.WriteByte('"') -} - -func writeUnknownStruct(w *textWriter, data []byte) (err error) { - if !w.compact { - if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { - return err - } - } - b := NewBuffer(data) - for b.index < len(b.buf) { - x, err := b.DecodeVarint() - if err != nil { - _, ferr := fmt.Fprintf(w, "/* %v */\n", err) - return ferr - } - wire, tag := x&7, x>>3 - if wire == WireEndGroup { - w.unindent() - if _, werr := w.Write(endBraceNewline); werr != nil { - return werr - } - continue - } - if _, ferr := fmt.Fprint(w, tag); ferr != nil { - return ferr - } - if wire != WireStartGroup { - if err = w.WriteByte(':'); err != nil { - return err - } - } - if !w.compact || wire == WireStartGroup { - if err = w.WriteByte(' '); err != nil { - return err - } - } - switch wire { - case WireBytes: - buf, e := b.DecodeRawBytes(false) - if e == nil { - _, err = fmt.Fprintf(w, "%q", buf) - } else { - _, err = fmt.Fprintf(w, "/* %v */", e) - } - case WireFixed32: - x, err = b.DecodeFixed32() - err = writeUnknownInt(w, x, err) - case WireFixed64: - x, err = b.DecodeFixed64() - err = writeUnknownInt(w, x, err) - case WireStartGroup: - err = w.WriteByte('{') - w.indent() - case WireVarint: - x, err = b.DecodeVarint() - err = writeUnknownInt(w, x, err) - default: - _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) - } - if err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - return nil -} - -func writeUnknownInt(w *textWriter, x uint64, err error) error { - if err == nil { - _, err = fmt.Fprint(w, x) - } else { - _, err = fmt.Fprintf(w, "/* %v */", err) - } - return err -} - -type int32Slice []int32 - -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// writeExtensions writes all the extensions in pv. -// pv is assumed to be a pointer to a protocol message struct that is extendable. -func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - e := pv.Interface().(Message) - - var m map[int32]Extension - var mu sync.Locker - if em, ok := e.(extensionsBytes); ok { - eb := em.GetExtensions() - var err error - m, err = BytesToExtensionsMap(*eb) - if err != nil { - return err - } - mu = notLocker{} - } else if _, ok := e.(extendableProto); ok { - ep, _ := extendable(e) - m, mu = ep.extensionsRead() - if m == nil { - return nil - } - } - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - - mu.Lock() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - mu.Unlock() - - for _, extNum := range ids { - ext := m[extNum] - var desc *ExtensionDesc - if emap != nil { - desc = emap[extNum] - } - if desc == nil { - // Unknown extension. - if err := writeUnknownStruct(w, ext.enc); err != nil { - return err - } - continue - } - - pb, err := GetExtension(e, desc) - if err != nil { - return fmt.Errorf("failed getting extension: %v", err) - } - - // Repeated extensions will appear as a slice. - if !desc.repeated() { - if err := tm.writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { - if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - remain := w.ind * 2 - for remain > 0 { - n := remain - if n > len(spaces) { - n = len(spaces) - } - w.w.Write(spaces[:n]) - remain -= n - } - w.complete = false -} - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line). - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes a given protocol buffer in text format. -// The only errors returned are from w. -func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { - val := reflect.ValueOf(pb) - if pb == nil || val.IsNil() { - w.Write([]byte("")) - return nil - } - var bw *bufio.Writer - ww, ok := w.(writer) - if !ok { - bw = bufio.NewWriter(w) - ww = bw - } - aw := &textWriter{ - w: ww, - complete: true, - compact: tm.Compact, - } - - if etm, ok := pb.(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = aw.Write(text); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil - } - // Dereference the received pointer so we don't have outer < and >. - v := reflect.Indirect(val) - if err := tm.writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// Text is the same as Marshal, but returns the string directly. -func (tm *TextMarshaler) Text(pb Message) string { - var buf bytes.Buffer - tm.Marshal(&buf, pb) - return buf.String() -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// TODO: consider removing some of the Marshal functions below. - -// MarshalText writes a given protocol buffer in text format. -// The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/gogo/protobuf/proto/text_gogo.go b/vendor/github.com/gogo/protobuf/proto/text_gogo.go deleted file mode 100644 index 1d6c6aa0e4..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/text_gogo.go +++ /dev/null @@ -1,57 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" -) - -func (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error { - m, ok := enumStringMaps[props.Enum] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - key := int32(0) - if v.Kind() == reflect.Ptr { - key = int32(v.Elem().Int()) - } else { - key = int32(v.Int()) - } - s, ok := m[key] - if !ok { - if err := tm.writeAny(w, v, props); err != nil { - return err - } - } - _, err := fmt.Fprint(w, s) - return err -} diff --git a/vendor/github.com/gogo/protobuf/proto/text_parser.go b/vendor/github.com/gogo/protobuf/proto/text_parser.go deleted file mode 100644 index f85c0cc81a..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/text_parser.go +++ /dev/null @@ -1,1018 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for parsing the Text protocol buffer format. -// TODO: message sets. - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "time" - "unicode/utf8" -) - -// Error string emitted when deserializing Any and fields are already set -const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" - -type ParseError struct { - Message string - Line int // 1-based line number - Offset int // 0-based byte offset from start of input -} - -func (p *ParseError) Error() string { - if p.Line == 1 { - // show offset only for first line - return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) - } - return fmt.Sprintf("line %d: %v", p.Line, p.Message) -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func (t *token) String() string { - if t.err == nil { - return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) - } - return fmt.Sprintf("parse error: %v", t.err) -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -// Numbers and identifiers are matched by [-+._A-Za-z0-9] -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -var ( - errBadUTF8 = errors.New("proto: bad UTF-8") -) - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - ss := string(r) + s[:2] - s = s[2:] - i, err := strconv.ParseUint(ss, 8, 8) - if err != nil { - return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) - } - return string([]byte{byte(i)}), s, nil - case 'x', 'X', 'u', 'U': - var n int - switch r { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) - } - ss := s[:n] - s = s[n:] - i, err := strconv.ParseUint(ss, 16, 64) - if err != nil { - return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) - } - if r == 'x' || r == 'X' { - return string([]byte{byte(i)}), s, nil - } - if i > utf8.MaxRune { - return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) - } - return string(rune(i)), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -// Return a RequiredNotSetError indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < st.NumField(); i++ { - if !isNil(sv.Field(i)) { - continue - } - - props := sprops.Prop[i] - if props.Required { - return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} - } - } - return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen -} - -// Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { - i, ok := sprops.decoderOrigNames[name] - if ok { - return i, sprops.Prop[i], true - } - return -1, nil, false -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - // Colon is optional when the field is a group or message. - needColon := true - switch props.Wire { - case "group": - needColon = false - case "bytes": - // A "bytes" field is either a message, a string, or a repeated field; - // those three become *T, *string and []T respectively, so we can check for - // this field being a pointer to a non-string. - if typ.Kind() == reflect.Ptr { - // *T or *string - if typ.Elem().Kind() == reflect.String { - break - } - } else if typ.Kind() == reflect.Slice { - // []T or []*T - if typ.Elem().Kind() != reflect.Ptr { - break - } - } else if typ.Kind() == reflect.String { - // The proto3 exception is for a string field, - // which requires a colon. - break - } - needColon = false - } - if needColon { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -func (p *textParser) readStruct(sv reflect.Value, terminator string) error { - st := sv.Type() - sprops := GetProperties(st) - reqCount := sprops.reqCount - var reqFieldErr error - fieldSet := make(map[string]bool) - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension or an Any. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - extName, err := p.consumeExtName() - if err != nil { - return err - } - - if s := strings.LastIndex(extName, "/"); s >= 0 { - // If it contains a slash, it's an Any type URL. - messageName := extName[s+1:] - mt := MessageType(messageName) - if mt == nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) - } - tok = p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - v := reflect.New(mt.Elem()) - if pe := p.readStruct(v.Elem(), terminator); pe != nil { - return pe - } - b, err := Marshal(v.Interface().(Message)) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", messageName, err) - } - if fieldSet["type_url"] { - return p.errorf(anyRepeatedlyUnpacked, "type_url") - } - if fieldSet["value"] { - return p.errorf(anyRepeatedlyUnpacked, "value") - } - sv.FieldByName("TypeUrl").SetString(extName) - sv.FieldByName("Value").SetBytes(b) - fieldSet["type_url"] = true - fieldSet["value"] = true - continue - } - - var desc *ExtensionDesc - // This could be faster, but it's functional. - // TODO: Do something smarter than a linear scan. - for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == extName { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", extName) - } - - props := &Properties{} - props.Parse(desc.Tag) - - typ := reflect.TypeOf(desc.ExtensionType) - if err := p.checkForColon(props, typ); err != nil { - return err - } - - rep := desc.repeated() - - // Read the extension structure, and set it in - // the value we're constructing. - var ext reflect.Value - if !rep { - ext = reflect.New(typ).Elem() - } else { - ext = reflect.New(typ.Elem()).Elem() - } - if err := p.readAny(ext, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - ep := sv.Addr().Interface().(Message) - if !rep { - SetExtension(ep, desc, ext.Interface()) - } else { - old, err := GetExtension(ep, desc) - var sl reflect.Value - if err == nil { - sl = reflect.ValueOf(old) // existing slice - } else { - sl = reflect.MakeSlice(typ, 0, 1) - } - sl = reflect.Append(sl, ext) - SetExtension(ep, desc, sl.Interface()) - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := tok.value - var dst reflect.Value - fi, props, ok := structFieldByName(sprops, name) - if ok { - dst = sv.Field(fi) - } else if oop, ok := sprops.OneofTypes[name]; ok { - // It is a oneof. - props = oop.Prop - nv := reflect.New(oop.Type.Elem()) - dst = nv.Elem().Field(0) - field := sv.Field(oop.Field) - if !field.IsNil() { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) - } - field.Set(nv) - } - if !dst.IsValid() { - return p.errorf("unknown field name %q in %v", name, st) - } - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. See b/28924776 for a time - // this went wrong. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.MapKeyProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - case "value": - if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.MapValProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - default: - p.back() - return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - if props.Required { - reqCount-- - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// consumeExtName consumes extension name or expanded Any type URL and the -// following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - if p.done && tok.value != "]" { - return "", p.errorf("unclosed type_url or extension name") - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in readStruct to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) readAny(v reflect.Value, props *Properties) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "" { - return p.errorf("unexpected EOF") - } - if len(props.CustomType) > 0 { - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - tc := reflect.TypeOf(new(Marshaler)) - ok := t.Elem().Implements(tc.Elem()) - if ok { - fv := v - flen := fv.Len() - if flen == fv.Cap() { - nav := reflect.MakeSlice(v.Type(), flen, 2*flen+1) - reflect.Copy(nav, fv) - fv.Set(nav) - } - fv.SetLen(flen + 1) - - // Read one. - p.back() - return p.readAny(fv.Index(flen), props) - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - custom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.ValueOf(custom)) - } else { - custom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler) - err := custom.Unmarshal([]byte(tok.unquoted)) - if err != nil { - return p.errorf("%v %v: %v", err, v.Type(), tok.value) - } - v.Set(reflect.Indirect(reflect.ValueOf(custom))) - } - return nil - } - if props.StdTime { - fv := v - p.back() - props.StdTime = false - tproto := ×tamp{} - err := p.readAny(reflect.ValueOf(tproto).Elem(), props) - props.StdTime = true - if err != nil { - return err - } - tim, err := timestampFromProto(tproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ts := fv.Interface().([]*time.Time) - ts = append(ts, &tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } else { - ts := fv.Interface().([]time.Time) - ts = append(ts, tim) - fv.Set(reflect.ValueOf(ts)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&tim)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&tim))) - } - return nil - } - if props.StdDuration { - fv := v - p.back() - props.StdDuration = false - dproto := &duration{} - err := p.readAny(reflect.ValueOf(dproto).Elem(), props) - props.StdDuration = true - if err != nil { - return err - } - dur, err := durationFromProto(dproto) - if err != nil { - return err - } - if props.Repeated { - t := reflect.TypeOf(v.Interface()) - if t.Kind() == reflect.Slice { - if t.Elem().Kind() == reflect.Ptr { - ds := fv.Interface().([]*time.Duration) - ds = append(ds, &dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } else { - ds := fv.Interface().([]time.Duration) - ds = append(ds, dur) - fv.Set(reflect.ValueOf(ds)) - return nil - } - } - } - if reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr { - v.Set(reflect.ValueOf(&dur)) - } else { - v.Set(reflect.Indirect(reflect.ValueOf(&dur))) - } - return nil - } - switch fv := v; fv.Kind() { - case reflect.Slice: - at := v.Type() - if at.Elem().Kind() == reflect.Uint8 { - // Special case for []byte - if tok.value[0] != '"' && tok.value[0] != '\'' { - // Deliberately written out here, as the error after - // this switch statement would write "invalid []byte: ...", - // which is not as user-friendly. - return p.errorf("invalid string: %v", tok.value) - } - bytes := []byte(tok.unquoted) - fv.Set(reflect.ValueOf(bytes)) - return nil - } - // Repeated field. - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - err := p.readAny(fv.Index(fv.Len()-1), props) - if err != nil { - return err - } - ntok := p.next() - if ntok.err != nil { - return ntok.err - } - if ntok.value == "]" { - break - } - if ntok.value != "," { - return p.errorf("Expected ']' or ',' found %q", ntok.value) - } - } - return nil - } - // One value of the repeated field. - p.back() - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - return p.readAny(fv.Index(fv.Len()-1), props) - case reflect.Bool: - // true/1/t/True or false/f/0/False. - switch tok.value { - case "true", "1", "t", "True": - fv.SetBool(true) - return nil - case "false", "0", "f", "False": - fv.SetBool(false) - return nil - } - case reflect.Float32, reflect.Float64: - v := tok.value - // Ignore 'f' for compatibility with output generated by C++, but don't - // remove 'f' when the value is "-inf" or "inf". - if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { - v = v[:len(v)-1] - } - if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { - fv.SetFloat(f) - return nil - } - case reflect.Int8: - if x, err := strconv.ParseInt(tok.value, 0, 8); err == nil { - fv.SetInt(x) - return nil - } - case reflect.Int16: - if x, err := strconv.ParseInt(tok.value, 0, 16); err == nil { - fv.SetInt(x) - return nil - } - case reflect.Int32: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - fv.SetInt(x) - return nil - } - - if len(props.Enum) == 0 { - break - } - m, ok := enumValueMaps[props.Enum] - if !ok { - break - } - x, ok := m[tok.value] - if !ok { - break - } - fv.SetInt(int64(x)) - return nil - case reflect.Int64: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - fv.SetInt(x) - return nil - } - - case reflect.Ptr: - // A basic field (indirected through pointer), or a repeated message/group - p.back() - fv.Set(reflect.New(fv.Type().Elem())) - return p.readAny(fv.Elem(), props) - case reflect.String: - if tok.value[0] == '"' || tok.value[0] == '\'' { - fv.SetString(tok.unquoted) - return nil - } - case reflect.Struct: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - // TODO: Handle nested messages which implement encoding.TextUnmarshaler. - return p.readStruct(fv, terminator) - case reflect.Uint8: - if x, err := strconv.ParseUint(tok.value, 0, 8); err == nil { - fv.SetUint(x) - return nil - } - case reflect.Uint16: - if x, err := strconv.ParseUint(tok.value, 0, 16); err == nil { - fv.SetUint(x) - return nil - } - case reflect.Uint32: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - fv.SetUint(uint64(x)) - return nil - } - case reflect.Uint64: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - fv.SetUint(x) - return nil - } - } - return p.errorf("invalid %v: %v", v.Type(), tok.value) -} - -// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb -// before starting to unmarshal, so any existing data in pb is always removed. -// If a required field is not set and no other error occurs, -// UnmarshalText returns *RequiredNotSetError. -func UnmarshalText(s string, pb Message) error { - if um, ok := pb.(encoding.TextUnmarshaler); ok { - return um.UnmarshalText([]byte(s)) - } - pb.Reset() - v := reflect.ValueOf(pb) - return newTextParser(s).readStruct(v.Elem(), "") -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp.go b/vendor/github.com/gogo/protobuf/proto/timestamp.go deleted file mode 100644 index 9324f6542b..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp.go +++ /dev/null @@ -1,113 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// This file implements operations on google.protobuf.Timestamp. - -import ( - "errors" - "fmt" - "time" -) - -const ( - // Seconds field of the earliest valid Timestamp. - // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - minValidSeconds = -62135596800 - // Seconds field just after the latest valid Timestamp. - // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). - maxValidSeconds = 253402300800 -) - -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range -// [0001-01-01, 10000-01-01) and has a Nanos field -// in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes -// the problem. -// -// Every valid Timestamp can be represented by a time.Time, but the converse is not true. -func validateTimestamp(ts *timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %#v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %#v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %#v: nanos not in range [0, 1e9)", ts) - } - return nil -} - -// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time. -// It returns an error if the argument is invalid. -// -// Unlike most Go functions, if Timestamp returns an error, the first return value -// is not the zero time.Time. Instead, it is the value obtained from the -// time.Unix function when passed the contents of the Timestamp, in the UTC -// locale. This may or may not be a meaningful time; many invalid Timestamps -// do map to valid time.Times. -// -// A nil Timestamp returns an error. The first return value in that case is -// undefined. -func timestampFromProto(ts *timestamp) (time.Time, error) { - // Don't return the zero value on error, because corresponds to a valid - // timestamp. Instead return whatever time.Unix gives us. - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t, validateTimestamp(ts) -} - -// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. -// It returns an error if the resulting Timestamp is invalid. -func timestampProto(t time.Time) (*timestamp, error) { - seconds := t.Unix() - nanos := int32(t.Sub(time.Unix(seconds, 0))) - ts := ×tamp{ - Seconds: seconds, - Nanos: nanos, - } - if err := validateTimestamp(ts); err != nil { - return nil, err - } - return ts, nil -} diff --git a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go b/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go deleted file mode 100644 index 38439fa990..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go +++ /dev/null @@ -1,49 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2016, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "reflect" - "time" -) - -var timeType = reflect.TypeOf((*time.Time)(nil)).Elem() - -type timestamp struct { - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` -} - -func (m *timestamp) Reset() { *m = timestamp{} } -func (*timestamp) ProtoMessage() {} -func (*timestamp) String() string { return "timestamp" } - -func init() { - RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp") -} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers.go b/vendor/github.com/gogo/protobuf/proto/wrappers.go deleted file mode 100644 index b175d1b642..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/wrappers.go +++ /dev/null @@ -1,1888 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "io" - "reflect" -) - -func makeStdDoubleValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*float64) - v := &float64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdDoubleValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64) - v := &float64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdDoubleValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float64) - v := &float64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float64) - v := &float64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdDoubleValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float64) - v := &float64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdDoubleValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdDoubleValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdDoubleValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdDoubleValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdFloatValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*float32) - v := &float32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdFloatValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32) - v := &float32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdFloatValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float32) - v := &float32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(float32) - v := &float32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdFloatValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*float32) - v := &float32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdFloatValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdFloatValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdFloatValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdFloatValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &float32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*int64) - v := &int64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64) - v := &int64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int64) - v := &int64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int64) - v := &int64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int64) - v := &int64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*uint64) - v := &uint64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64) - v := &uint64Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint64) - v := &uint64Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint64) - v := &uint64Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint64) - v := &uint64Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdUInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdUInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint64Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*int32) - v := &int32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32) - v := &int32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int32) - v := &int32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(int32) - v := &int32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*int32) - v := &int32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &int32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*uint32) - v := &uint32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32) - v := &uint32Value{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdUInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint32) - v := &uint32Value{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(uint32) - v := &uint32Value{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*uint32) - v := &uint32Value{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdUInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdUInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdUInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdUInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &uint32Value{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBoolValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*bool) - v := &boolValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBoolValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool) - v := &boolValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBoolValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(bool) - v := &boolValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(bool) - v := &boolValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBoolValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*bool) - v := &boolValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBoolValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdBoolValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdBoolValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBoolValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &boolValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdStringValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*string) - v := &stringValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdStringValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string) - v := &stringValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdStringValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(string) - v := &stringValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(string) - v := &stringValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdStringValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*string) - v := &stringValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdStringValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdStringValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdStringValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdStringValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &stringValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBytesValueMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - t := ptr.asPointerTo(u.typ).Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - t := ptr.asPointerTo(u.typ).Interface().(*[]byte) - v := &bytesValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBytesValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - if ptr.isNil() { - return 0 - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - return tagsize + SizeVarint(uint64(siz)) + siz - }, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - if ptr.isNil() { - return b, nil - } - t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte) - v := &bytesValue{*t} - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(buf))) - b = append(b, buf...) - return b, nil - } -} - -func makeStdBytesValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(u.typ) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().([]byte) - v := &bytesValue{t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(u.typ) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().([]byte) - v := &bytesValue{t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBytesValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - n := 0 - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getSlice(reflect.PtrTo(u.typ)) - for i := 0; i < s.Len(); i++ { - elem := s.Index(i) - t := elem.Interface().(*[]byte) - v := &bytesValue{*t} - siz := Size(v) - buf, err := Marshal(v) - if err != nil { - return nil, err - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(siz)) - b = append(b, buf...) - } - - return b, nil - } -} - -func makeStdBytesValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(sub.typ).Elem() - s.Set(reflect.ValueOf(m.Value)) - return b[x:], nil - } -} - -func makeStdBytesValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem() - s.Set(reflect.ValueOf(&m.Value)) - return b[x:], nil - } -} - -func makeStdBytesValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(reflect.PtrTo(sub.typ)) - newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} - -func makeStdBytesValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return nil, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - m := &bytesValue{} - if err := Unmarshal(b[:x], m); err != nil { - return nil, err - } - slice := f.getSlice(sub.typ) - newSlice := reflect.Append(slice, reflect.ValueOf(m.Value)) - slice.Set(newSlice) - return b[x:], nil - } -} diff --git a/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go b/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go deleted file mode 100644 index c1cf7bf85e..0000000000 --- a/vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go +++ /dev/null @@ -1,113 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2018, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -type float64Value struct { - Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *float64Value) Reset() { *m = float64Value{} } -func (*float64Value) ProtoMessage() {} -func (*float64Value) String() string { return "float64" } - -type float32Value struct { - Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *float32Value) Reset() { *m = float32Value{} } -func (*float32Value) ProtoMessage() {} -func (*float32Value) String() string { return "float32" } - -type int64Value struct { - Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *int64Value) Reset() { *m = int64Value{} } -func (*int64Value) ProtoMessage() {} -func (*int64Value) String() string { return "int64" } - -type uint64Value struct { - Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *uint64Value) Reset() { *m = uint64Value{} } -func (*uint64Value) ProtoMessage() {} -func (*uint64Value) String() string { return "uint64" } - -type int32Value struct { - Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *int32Value) Reset() { *m = int32Value{} } -func (*int32Value) ProtoMessage() {} -func (*int32Value) String() string { return "int32" } - -type uint32Value struct { - Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *uint32Value) Reset() { *m = uint32Value{} } -func (*uint32Value) ProtoMessage() {} -func (*uint32Value) String() string { return "uint32" } - -type boolValue struct { - Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *boolValue) Reset() { *m = boolValue{} } -func (*boolValue) ProtoMessage() {} -func (*boolValue) String() string { return "bool" } - -type stringValue struct { - Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *stringValue) Reset() { *m = stringValue{} } -func (*stringValue) ProtoMessage() {} -func (*stringValue) String() string { return "string" } - -type bytesValue struct { - Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` -} - -func (m *bytesValue) Reset() { *m = bytesValue{} } -func (*bytesValue) ProtoMessage() {} -func (*bytesValue) String() string { return "[]byte" } - -func init() { - RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue") - RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue") - RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value") - RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value") - RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value") - RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value") - RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue") - RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue") - RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue") -} diff --git a/vendor/github.com/google/certificate-transparency-go/.gitignore b/vendor/github.com/google/certificate-transparency-go/.gitignore index c06f34d46a..26073b0df9 100644 --- a/vendor/github.com/google/certificate-transparency-go/.gitignore +++ b/vendor/github.com/google/certificate-transparency-go/.gitignore @@ -16,9 +16,14 @@ /data /dumpscts /etcdiscover +/findlog +/goshawk +/gosmin /gossip_server /preloader /scanlog +/sctcheck +/sctscan /trillian_log_server /trillian_log_signer /trillian.json diff --git a/vendor/github.com/google/certificate-transparency-go/.travis.yml b/vendor/github.com/google/certificate-transparency-go/.travis.yml index 9826dd698f..535ff63c0d 100644 --- a/vendor/github.com/google/certificate-transparency-go/.travis.yml +++ b/vendor/github.com/google/certificate-transparency-go/.travis.yml @@ -1,29 +1,42 @@ -sudo: false +sudo: true # required for CI push into Kubernetes. language: go os: linux -go: 1.9 +go: "1.10" + +go_import_path: github.com/google/certificate-transparency-go env: - - GOFLAGS= + - GCE_CI=${ENABLE_GCE_CI} GOFLAGS= - GOFLAGS=-race - - GOFLAGS= WITH_ETCD=true + - GOFLAGS= WITH_ETCD=true WITH_COVERAGE=true - GOFLAGS=-race WITH_ETCD=true matrix: fast_finish: true +addons: + apt: + sources: + - mysql-5.7-trusty + packages: + - mysql-server + - mysql-client + +services: + - docker + +before_install: + - sudo mysql -e "use mysql; update user set authentication_string=PASSWORD('') where User='root'; update user set plugin='mysql_native_password';FLUSH PRIVILEGES;" + - sudo mysql_upgrade + - sudo service mysql restart + install: - - | - if [ ! -d $HOME/gopath/src/github.com/google ]; then - mkdir -p $HOME/gopath/src/github.com/google - ln -s $TRAVIS_BUILD_DIR $HOME/gopath/src/github.com/google/certificate-transparency-go - fi - mkdir ../protoc - | ( cd ../protoc - wget https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-${TRAVIS_OS_NAME}-x86_64.zip - unzip protoc-3.2.0-${TRAVIS_OS_NAME}-x86_64.zip + wget https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-${TRAVIS_OS_NAME}-x86_64.zip + unzip protoc-3.5.1-${TRAVIS_OS_NAME}-x86_64.zip ) - export PATH=$(pwd)/../protoc/bin:$PATH - go get -d -t ./... @@ -41,9 +54,8 @@ install: script: - set -e - - export TRILLIAN_SQL_DRIVER=mysql - cd $HOME/gopath/src/github.com/google/certificate-transparency-go - - ./scripts/presubmit.sh ${PRESUBMIT_OPTS} + - ./scripts/presubmit.sh ${PRESUBMIT_OPTS} ${WITH_COVERAGE:+--coverage} - | # Check re-generation didn't change anything status=$(git status --porcelain | grep -v coverage) || : @@ -64,3 +76,12 @@ script: after_success: - cp /tmp/coverage.txt . - bash <(curl -s https://codecov.io/bash) + - | + # Push up to GCE CI instance if we're running after a merge to master + if [[ "${GCE_CI}" == "true" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $TRAVIS_BRANCH == "master" ]]; then + . scripts/install_cloud.sh + echo ${GCLOUD_SERVICE_KEY_CI} | base64 --decode -i > ${HOME}/gcloud-service-key.json + gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json + rm ${HOME}/gcloud-service-key.json + . scripts/deploy_gce_ci.sh + fi diff --git a/vendor/github.com/google/certificate-transparency-go/CHANGELOG.md b/vendor/github.com/google/certificate-transparency-go/CHANGELOG.md new file mode 100644 index 0000000000..73d111dd8f --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/CHANGELOG.md @@ -0,0 +1,208 @@ +# CERTIFICATE-TRANSPARENCY-GO Changelog + +## v1.0.20 - Minimal Gossip / Go 1.11 Fix / Utility Improvements + +Published 2018-07-05 09:21:34 +0000 UTC + +Enhancements have been made to various utilities including `scanner`, `sctcheck`, `loglist` and `x509util`. + +The `allow_verification_with_non_compliant_keys` flag has been removed from `signatures.go`. + +An implementation of Gossip has been added. See the `gossip/minimal` package for more information. + +An X.509 compatibility issue for Go 1.11 has been fixed. This should be backwards compatible with 1.10. + +Commit [37a384cd035e722ea46e55029093e26687138edf](https://api.github.com/repos/google/certificate-transparency-go/commits/37a384cd035e722ea46e55029093e26687138edf) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.20) + +## v1.0.19 - CTFE User Quota + +Published 2018-06-01 13:51:52 +0000 UTC + +CTFE now supports Trillian Log's explicit quota API; quota can be requested based on the remote user's IP, as well as per-issuing certificate in submitted chains. + +Commit [8736a411b4ff214ea20687e46c2b67d66ebd83fc](https://api.github.com/repos/google/certificate-transparency-go/commits/8736a411b4ff214ea20687e46c2b67d66ebd83fc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.19) + +## v1.0.18 - Adding Migration Tool / Client Additions / K8 Config + +Published 2018-06-01 14:28:20 +0000 UTC + +Work on a log migration tool (Migrillian) is in progress. This is not yet ready for production use but will provide features for mirroring and migrating logs. + +The `RequestLog` API allows for logging of SCTs when they are issued by CTFE. + +The CT Go client now supports `GetEntryAndProof`. Utilities have been switched over to use the `glog` package. + +Commit [77abf2dac5410a62c04ac1c662c6d0fa54afc2dc](https://api.github.com/repos/google/certificate-transparency-go/commits/77abf2dac5410a62c04ac1c662c6d0fa54afc2dc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.18) + +## v1.0.17 - Merkle verification / Tracing / Demo script / CORS + +Published 2018-06-01 14:25:16 +0000 UTC + +Now uses Merkle Tree verification from Trillian. + +The CT server now supports CORS. + +Request tracing added using OpenCensus. For GCE / K8 it just requires the flag to be enabled to export traces to Stackdriver. Other environments may differ. + +A demo script was added that goes through setting up a simple deployment suitable for development / demo purposes. This may be useful for those new to the project. + +Commit [3c3d22ce946447d047a03228ebb4a41e3e4eb15b](https://api.github.com/repos/google/certificate-transparency-go/commits/3c3d22ce946447d047a03228ebb4a41e3e4eb15b) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.17) + +## v1.0.16 - Lifecycle test / Go 1.10.1 + +Published 2018-06-01 14:22:23 +0000 UTC + +An integration test was added that goes through a create / drain queue / freeze lifecycle for a log. + +Changes to `x509` were merged from Go 1.10.1. + +Commit [a72423d09b410b80673fd1135ba1022d04bac6cd](https://api.github.com/repos/google/certificate-transparency-go/commits/a72423d09b410b80673fd1135ba1022d04bac6cd) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.16) + +## v1.0.15 - More control of verification, grpclb, stackdriver metrics + +Published 2018-06-01 14:20:32 +0000 UTC + +Facilities were added to the `x509` package to control whether verification checks are applied. + +Log server requests are now balanced using `gRPClb`. + +For Kubernetes, metrics can be published to Stackdriver monitoring. + +Commit [684d6eee6092774e54d301ccad0ed61bc8d010c1](https://api.github.com/repos/google/certificate-transparency-go/commits/684d6eee6092774e54d301ccad0ed61bc8d010c1) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.15) + +## v1.0.14 - SQLite Removed, LeafHashForLeaf + +Published 2018-06-01 14:15:37 +0000 UTC + +Support for SQLlite was removed. This motivation was ongoing test flakiness caused by multi-user access. This database may work for an embedded scenario but is not suitable for use in a server environment. + +A `LeafHashForLeaf` client API was added and is now used by the CT client and integration tests. + +Commit [698cd6a661196db4b2e71437422178ffe8705006](https://api.github.com/repos/google/certificate-transparency-go/commits/698cd6a661196db4b2e71437422178ffe8705006) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.14) + +## v1.0.13 - Crypto changes, util updates, sync with trillian repo, loglist verification + +Published 2018-06-01 14:15:21 +0000 UTC + +Some of our custom crypto package that were wrapping calls to the standard package have been removed and the base features used directly. + +Updates were made to GCE ingress and health checks. + +The log list utility can verify signatures. + +Commit [480c3654a70c5383b9543ec784203030aedbd3a5](https://api.github.com/repos/google/certificate-transparency-go/commits/480c3654a70c5383b9543ec784203030aedbd3a5) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.13) + +## v1.0.12 - Client / util updates & CTFE fixes + +Published 2018-06-01 14:13:42 +0000 UTC + +The CT client can now use a JSON loglist to find logs. + +CTFE had a fix applied for preissued precerts. + +A DNS client was added and CT client was extended to support DNS retrieval. + +Commit [74c06c95e0b304a050a1c33764c8a01d653a16e3](https://api.github.com/repos/google/certificate-transparency-go/commits/74c06c95e0b304a050a1c33764c8a01d653a16e3) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.12) + +## v1.0.11 - Kubernetes CI / Integration fixes + +Published 2018-06-01 14:12:18 +0000 UTC + +Updates to Kubernetes configs, mostly related to running a CI instance. + +Commit [0856acca7e0ab7f082ae83a1fbb5d21160962efc](https://api.github.com/repos/google/certificate-transparency-go/commits/0856acca7e0ab7f082ae83a1fbb5d21160962efc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.11) + +## v1.0.10 - More scanner, x509, utility and client fixes. CTFE updates + +Published 2018-06-01 14:09:47 +0000 UTC + +The CT client was using the wrong protobuffer library package. To guard against this in future a check has been added to our lint config. + +The `x509` and `asn1` packages have had upstream fixes applied from Go 1.10rc1. + +Commit [1bec4527572c443752ad4f2830bef88be0533236](https://api.github.com/repos/google/certificate-transparency-go/commits/1bec4527572c443752ad4f2830bef88be0533236) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.10) + +## v1.0.9 - Scanner, x509, utility and client fixes + +Published 2018-06-01 14:11:13 +0000 UTC + +The `scanner` utility now displays throughput stats. + +Build instructions and README files were updated. + +The `certcheck` utility can be told to ignore unknown critical X.509 extensions. + +Commit [c06833528d04a94eed0c775104d1107bab9ae17c](https://api.github.com/repos/google/certificate-transparency-go/commits/c06833528d04a94eed0c775104d1107bab9ae17c) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.9) + +## v1.0.8 - Client fixes, align with trillian repo + +Published 2018-06-01 14:06:44 +0000 UTC + + + +Commit [e8b02c60f294b503dbb67de0868143f5d4935e56](https://api.github.com/repos/google/certificate-transparency-go/commits/e8b02c60f294b503dbb67de0868143f5d4935e56) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.8) + +## v1.0.7 - CTFE fixes + +Published 2018-06-01 14:06:13 +0000 UTC + +An issue was fixed with CTFE signature caching. In an unlikely set of circumstances this could lead to log mis-operation. While the chances of this are small, we recommend that versions prior to this one are not deployed. + +Commit [52c0590bd3b4b80c5497005b0f47e10557425eeb](https://api.github.com/repos/google/certificate-transparency-go/commits/52c0590bd3b4b80c5497005b0f47e10557425eeb) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.7) + +## v1.0.6 - crlcheck improvements / other fixes + +Published 2018-06-01 14:04:22 +0000 UTC + +The `crlcheck` utility has had several fixes and enhancements. Additionally the `hammer` now supports temporal logs. + +Commit [3955e4a00c42e83ff17ce25003976159c5d0f0f9](https://api.github.com/repos/google/certificate-transparency-go/commits/3955e4a00c42e83ff17ce25003976159c5d0f0f9) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.6) + +## v1.0.5 - X509 and asn1 fixes + +Published 2018-06-01 14:02:58 +0000 UTC + +This release is mostly fixes to the `x509` and `asn1` packages. Some command line utilties were also updated. + +Commit [ae40d07cce12f1227c6e658e61c9dddb7646f97b](https://api.github.com/repos/google/certificate-transparency-go/commits/ae40d07cce12f1227c6e658e61c9dddb7646f97b) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.5) + +## v1.0.4 - Multi log backend configs + +Published 2018-06-01 14:02:07 +0000 UTC + +Support was added to allow CTFE to use multiple backends, each serving a distinct set of logs. It allows for e.g. regional backend deployment with common frontend servers. + +Commit [62023ed90b41fa40854957b5dec7d9d73594723f](https://api.github.com/repos/google/certificate-transparency-go/commits/62023ed90b41fa40854957b5dec7d9d73594723f) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.4) + +## v1.0.3 - Hammer updates, use standard context + +Published 2018-06-01 14:01:11 +0000 UTC + +After the Go 1.9 migration references to anything other than the standard `context` package have been removed. This is the only one that should be used from now on. + +Commit [b28beed8b9aceacc705e0ff4a11d435a310e3d97](https://api.github.com/repos/google/certificate-transparency-go/commits/b28beed8b9aceacc705e0ff4a11d435a310e3d97) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.3) + +## v1.0.2 - Go 1.9 + +Published 2018-06-01 14:00:00 +0000 UTC + +Go 1.9 is now required to build the code. + +Commit [3aed33d672ee43f04b1e8a00b25ca3e2e2e74309](https://api.github.com/repos/google/certificate-transparency-go/commits/3aed33d672ee43f04b1e8a00b25ca3e2e2e74309) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.2) + +## v1.0.1 - Hammer and client improvements + +Published 2018-06-01 13:59:29 +0000 UTC + + + +Commit [c28796cc21776667fb05d6300e32d9517be96515](https://api.github.com/repos/google/certificate-transparency-go/commits/c28796cc21776667fb05d6300e32d9517be96515) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.1) + +## v1.0 - First Trillian CT Release + +Published 2018-06-01 13:59:00 +0000 UTC + +This is the point that corresponds to the 1.0 release in the trillian repo. + +Commit [abb79e468b6f3bbd48d1ab0c9e68febf80d52c4d](https://api.github.com/repos/google/certificate-transparency-go/commits/abb79e468b6f3bbd48d1ab0c9e68febf80d52c4d) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0) + diff --git a/vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go b/vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go index 889fbe2593..2e55408452 100644 --- a/vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go +++ b/vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go @@ -1,22 +1,12 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: multilog.proto -/* -Package configpb is a generated protocol buffer package. - -It is generated from these files: - multilog.proto - -It has these top-level messages: - TemporalLogConfig - LogShardConfig -*/ package configpb import proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" +import timestamp "github.com/golang/protobuf/ptypes/timestamp" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -32,13 +22,35 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // TemporalLogConfig is a set of LogShardConfig messages, whose // time limits should be contiguous. type TemporalLogConfig struct { - Shard []*LogShardConfig `protobuf:"bytes,1,rep,name=shard" json:"shard,omitempty"` + Shard []*LogShardConfig `protobuf:"bytes,1,rep,name=shard,proto3" json:"shard,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TemporalLogConfig) Reset() { *m = TemporalLogConfig{} } +func (m *TemporalLogConfig) String() string { return proto.CompactTextString(m) } +func (*TemporalLogConfig) ProtoMessage() {} +func (*TemporalLogConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_multilog_3c9b797b88da6f07, []int{0} +} +func (m *TemporalLogConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TemporalLogConfig.Unmarshal(m, b) +} +func (m *TemporalLogConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TemporalLogConfig.Marshal(b, m, deterministic) +} +func (dst *TemporalLogConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_TemporalLogConfig.Merge(dst, src) +} +func (m *TemporalLogConfig) XXX_Size() int { + return xxx_messageInfo_TemporalLogConfig.Size(m) +} +func (m *TemporalLogConfig) XXX_DiscardUnknown() { + xxx_messageInfo_TemporalLogConfig.DiscardUnknown(m) } -func (m *TemporalLogConfig) Reset() { *m = TemporalLogConfig{} } -func (m *TemporalLogConfig) String() string { return proto.CompactTextString(m) } -func (*TemporalLogConfig) ProtoMessage() {} -func (*TemporalLogConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +var xxx_messageInfo_TemporalLogConfig proto.InternalMessageInfo func (m *TemporalLogConfig) GetShard() []*LogShardConfig { if m != nil { @@ -50,23 +62,45 @@ func (m *TemporalLogConfig) GetShard() []*LogShardConfig { // LogShardConfig describes the acceptable date range for a single shard of a temporal // log. type LogShardConfig struct { - Uri string `protobuf:"bytes,1,opt,name=uri" json:"uri,omitempty"` + Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"` // The log's public key in DER-encoded PKIX form. PublicKeyDer []byte `protobuf:"bytes,2,opt,name=public_key_der,json=publicKeyDer,proto3" json:"public_key_der,omitempty"` // not_after_start defines the start of the range of acceptable NotAfter // values, inclusive. // Leaving this unset implies no lower bound to the range. - NotAfterStart *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=not_after_start,json=notAfterStart" json:"not_after_start,omitempty"` + NotAfterStart *timestamp.Timestamp `protobuf:"bytes,3,opt,name=not_after_start,json=notAfterStart,proto3" json:"not_after_start,omitempty"` // not_after_limit defines the end of the range of acceptable NotAfter values, // exclusive. // Leaving this unset implies no upper bound to the range. - NotAfterLimit *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=not_after_limit,json=notAfterLimit" json:"not_after_limit,omitempty"` + NotAfterLimit *timestamp.Timestamp `protobuf:"bytes,4,opt,name=not_after_limit,json=notAfterLimit,proto3" json:"not_after_limit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LogShardConfig) Reset() { *m = LogShardConfig{} } +func (m *LogShardConfig) String() string { return proto.CompactTextString(m) } +func (*LogShardConfig) ProtoMessage() {} +func (*LogShardConfig) Descriptor() ([]byte, []int) { + return fileDescriptor_multilog_3c9b797b88da6f07, []int{1} +} +func (m *LogShardConfig) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LogShardConfig.Unmarshal(m, b) +} +func (m *LogShardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LogShardConfig.Marshal(b, m, deterministic) +} +func (dst *LogShardConfig) XXX_Merge(src proto.Message) { + xxx_messageInfo_LogShardConfig.Merge(dst, src) +} +func (m *LogShardConfig) XXX_Size() int { + return xxx_messageInfo_LogShardConfig.Size(m) +} +func (m *LogShardConfig) XXX_DiscardUnknown() { + xxx_messageInfo_LogShardConfig.DiscardUnknown(m) } -func (m *LogShardConfig) Reset() { *m = LogShardConfig{} } -func (m *LogShardConfig) String() string { return proto.CompactTextString(m) } -func (*LogShardConfig) ProtoMessage() {} -func (*LogShardConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +var xxx_messageInfo_LogShardConfig proto.InternalMessageInfo func (m *LogShardConfig) GetUri() string { if m != nil { @@ -82,14 +116,14 @@ func (m *LogShardConfig) GetPublicKeyDer() []byte { return nil } -func (m *LogShardConfig) GetNotAfterStart() *google_protobuf.Timestamp { +func (m *LogShardConfig) GetNotAfterStart() *timestamp.Timestamp { if m != nil { return m.NotAfterStart } return nil } -func (m *LogShardConfig) GetNotAfterLimit() *google_protobuf.Timestamp { +func (m *LogShardConfig) GetNotAfterLimit() *timestamp.Timestamp { if m != nil { return m.NotAfterLimit } @@ -101,9 +135,9 @@ func init() { proto.RegisterType((*LogShardConfig)(nil), "configpb.LogShardConfig") } -func init() { proto.RegisterFile("multilog.proto", fileDescriptor0) } +func init() { proto.RegisterFile("multilog.proto", fileDescriptor_multilog_3c9b797b88da6f07) } -var fileDescriptor0 = []byte{ +var fileDescriptor_multilog_3c9b797b88da6f07 = []byte{ // 241 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x8f, 0xb1, 0x4e, 0xc3, 0x30, 0x14, 0x45, 0x65, 0x02, 0x08, 0xdc, 0x12, 0xc0, 0x93, 0xd5, 0x85, 0xa8, 0x62, 0xc8, 0xe4, 0x4a, diff --git a/vendor/github.com/google/certificate-transparency-go/client/getentries.go b/vendor/github.com/google/certificate-transparency-go/client/getentries.go index e2cde55c22..1194c51609 100644 --- a/vendor/github.com/google/certificate-transparency-go/client/getentries.go +++ b/vendor/github.com/google/certificate-transparency-go/client/getentries.go @@ -66,7 +66,7 @@ func (c *LogClient) GetEntries(ctx context.Context, start, end int64) ([]ct.LogE for i, entry := range resp.Entries { index := start + int64(i) logEntry, err := ct.LogEntryFromLeaf(index, &entry) - if _, ok := err.(x509.NonFatalErrors); !ok && err != nil { + if x509.IsFatal(err) { return nil, err } entries[i] = *logEntry diff --git a/vendor/github.com/google/certificate-transparency-go/client/logclient.go b/vendor/github.com/google/certificate-transparency-go/client/logclient.go index b1031cf8a2..a79ef3083c 100644 --- a/vendor/github.com/google/certificate-transparency-go/client/logclient.go +++ b/vendor/github.com/google/certificate-transparency-go/client/logclient.go @@ -19,7 +19,6 @@ package client import ( "context" - "crypto/sha256" "encoding/base64" "fmt" "net/http" @@ -35,11 +34,19 @@ type LogClient struct { jsonclient.JSONClient } +// CheckLogClient is an interface that allows (just) checking of various log contents. +type CheckLogClient interface { + BaseURI() string + GetSTH(context.Context) (*ct.SignedTreeHead, error) + GetSTHConsistency(ctx context.Context, first, second uint64) ([][]byte, error) + GetProofByHash(ctx context.Context, hash []byte, treeSize uint64) (*ct.GetProofByHashResponse, error) +} + // New constructs a new LogClient instance. // |uri| is the base URI of the CT log instance to interact with, e.g. -// http://ct.googleapis.com/pilot +// https://ct.googleapis.com/pilot // |hc| is the underlying client to be used for HTTP requests to the CT log. -// |opts| can be used to provide a customer logger interface and a public key +// |opts| can be used to provide a custom logger interface and a public key // for signature verification. func New(uri string, hc *http.Client, opts jsonclient.Options) (*LogClient, error) { logClient, err := jsonclient.New(uri, hc, opts) @@ -169,35 +176,16 @@ func (c *LogClient) GetSTH(ctx context.Context) (*ct.SignedTreeHead, error) { } return nil, err } - sth := ct.SignedTreeHead{ - TreeSize: resp.TreeSize, - Timestamp: resp.Timestamp, - } - if len(resp.SHA256RootHash) != sha256.Size { - return nil, RspError{ - Err: fmt.Errorf("sha256_root_hash is invalid length, expected %d got %d", sha256.Size, len(resp.SHA256RootHash)), - StatusCode: httpRsp.StatusCode, - Body: body, - } - } - copy(sth.SHA256RootHash[:], resp.SHA256RootHash) - - var ds ct.DigitallySigned - if rest, err := tls.Unmarshal(resp.TreeHeadSignature, &ds); err != nil { + sth, err := resp.ToSignedTreeHead() + if err != nil { return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body} - } else if len(rest) > 0 { - return nil, RspError{ - Err: fmt.Errorf("trailing data (%d bytes) after DigitallySigned", len(rest)), - StatusCode: httpRsp.StatusCode, - Body: body, - } } - sth.TreeHeadSignature = ds - if err := c.VerifySTHSignature(sth); err != nil { + + if err := c.VerifySTHSignature(*sth); err != nil { return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body} } - return &sth, nil + return sth, nil } // VerifySTHSignature checks the signature in sth, returning any error encountered or nil if verification is @@ -281,3 +269,21 @@ func (c *LogClient) GetAcceptedRoots(ctx context.Context) ([]ct.ASN1Cert, error) } return roots, nil } + +// GetEntryAndProof returns a log entry and audit path for the index of a leaf. +func (c *LogClient) GetEntryAndProof(ctx context.Context, index, treeSize uint64) (*ct.GetEntryAndProofResponse, error) { + base10 := 10 + params := map[string]string{ + "leaf_index": strconv.FormatUint(index, base10), + "tree_size": strconv.FormatUint(treeSize, base10), + } + var resp ct.GetEntryAndProofResponse + httpRsp, body, err := c.GetAndParse(ctx, ct.GetEntryAndProofPath, params, &resp) + if err != nil { + if httpRsp != nil { + return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body} + } + return nil, err + } + return &resp, nil +} diff --git a/vendor/github.com/google/certificate-transparency-go/client/multilog.go b/vendor/github.com/google/certificate-transparency-go/client/multilog.go index b345d380a3..a4860b6d20 100644 --- a/vendor/github.com/google/certificate-transparency-go/client/multilog.go +++ b/vendor/github.com/google/certificate-transparency-go/client/multilog.go @@ -23,7 +23,7 @@ import ( "net/http" "time" - "github.com/gogo/protobuf/proto" + "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" ct "github.com/google/certificate-transparency-go" "github.com/google/certificate-transparency-go/client/configpb" diff --git a/vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml b/vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml new file mode 100644 index 0000000000..8c8c5ab6f8 --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/cloudbuild_tag.yaml @@ -0,0 +1,10 @@ +steps: +- id: build_ctfe + name: gcr.io/cloud-builders/docker + args: + - build + - --file=trillian/examples/deployment/docker/ctfe/Dockerfile + - --tag=gcr.io/${PROJECT_ID}/ctfe:${TAG_NAME} + - . +images: +- gcr.io/${PROJECT_ID}/ctfe:${TAG_NAME} diff --git a/vendor/github.com/google/certificate-transparency-go/gometalinter.json b/vendor/github.com/google/certificate-transparency-go/gometalinter.json index 57d8af0b28..4eba1b63c8 100644 --- a/vendor/github.com/google/certificate-transparency-go/gometalinter.json +++ b/vendor/github.com/google/certificate-transparency-go/gometalinter.json @@ -1,7 +1,9 @@ { + "Deadline": "60s", "Linters": { "license": "./scripts/check_license.sh:PATH:LINE:MESSAGE", - "forked": "./scripts/check_forked.sh:PATH:LINE:MESSAGE" + "forked": "./scripts/check_forked.sh:PATH:LINE:MESSAGE", + "unforked": "./scripts/check_unforked.sh:PATH:LINE:MESSAGE" }, "Enable": [ "forked", @@ -11,6 +13,7 @@ "golint", "license", "misspell", + "unforked", "vet" ], "Exclude": [ diff --git a/vendor/github.com/google/certificate-transparency-go/jsonclient/client.go b/vendor/github.com/google/certificate-transparency-go/jsonclient/client.go index 45638fc69b..c34fa833d5 100644 --- a/vendor/github.com/google/certificate-transparency-go/jsonclient/client.go +++ b/vendor/github.com/google/certificate-transparency-go/jsonclient/client.go @@ -53,7 +53,7 @@ type backoffer interface { // JSONClient provides common functionality for interacting with a JSON server // that uses cryptographic signatures. type JSONClient struct { - uri string // the base URI of the server. e.g. http://ct.googleapis/pilot + uri string // the base URI of the server. e.g. https://ct.googleapis/pilot httpClient *http.Client // used to interact with the server via HTTP Verifier *ct.SignatureVerifier // nil for no verification (e.g. no public key available) logger Logger // interface to use for logging warnings and errors @@ -139,6 +139,11 @@ func New(uri string, hc *http.Client, opts Options) (*JSONClient, error) { }, nil } +// BaseURI returns the base URI that the JSONClient makes queries to. +func (c *JSONClient) BaseURI() string { + return c.uri +} + // GetAndParse makes a HTTP GET call to the given path, and attempta to parse // the response as a JSON representation of the rsp structure. Returns the // http.Response, the body of the response, and an error. Note that the diff --git a/vendor/github.com/google/certificate-transparency-go/serialization.go b/vendor/github.com/google/certificate-transparency-go/serialization.go index 00b51c1c97..a1b558d14b 100644 --- a/vendor/github.com/google/certificate-transparency-go/serialization.go +++ b/vendor/github.com/google/certificate-transparency-go/serialization.go @@ -20,6 +20,7 @@ import ( "encoding/json" "fmt" "strings" + "time" "github.com/google/certificate-transparency-go/tls" "github.com/google/certificate-transparency-go/x509" @@ -127,7 +128,7 @@ func MerkleTreeLeafFromRawChain(rawChain []ASN1Cert, etype LogEntryType, timesta chain := make([]*x509.Certificate, count) for i := range chain { cert, err := x509.ParseCertificate(rawChain[i].Data) - if err != nil { + if x509.IsFatal(err) { return nil, fmt.Errorf("failed to parse chain[%d] cert: %v", i, err) } chain[i] = cert @@ -189,6 +190,53 @@ func MerkleTreeLeafFromChain(chain []*x509.Certificate, etype LogEntryType, time return &leaf, nil } +// MerkleTreeLeafForEmbeddedSCT generates a MerkleTreeLeaf from a chain and an +// SCT timestamp, where the leaf certificate at chain[0] is a certificate that +// contains embedded SCTs. It is assumed that the timestamp provided is from +// one of the SCTs embedded within the leaf certificate. +func MerkleTreeLeafForEmbeddedSCT(chain []*x509.Certificate, timestamp uint64) (*MerkleTreeLeaf, error) { + // For building the leaf for a certificate and SCT where the SCT is embedded + // in the certificate, we need to build the original precertificate TBS + // data. First, parse the leaf cert and its issuer. + if len(chain) < 2 { + return nil, fmt.Errorf("no issuer cert available for precert leaf building") + } + issuer := chain[1] + cert := chain[0] + + // Next, post-process the DER-encoded TBSCertificate, to remove the SCTList + // extension. + tbs, err := x509.RemoveSCTList(cert.RawTBSCertificate) + if err != nil { + return nil, fmt.Errorf("failed to remove SCT List extension: %v", err) + } + + return &MerkleTreeLeaf{ + Version: V1, + LeafType: TimestampedEntryLeafType, + TimestampedEntry: &TimestampedEntry{ + EntryType: PrecertLogEntryType, + Timestamp: timestamp, + PrecertEntry: &PreCert{ + IssuerKeyHash: sha256.Sum256(issuer.RawSubjectPublicKeyInfo), + TBSCertificate: tbs, + }, + }, + }, nil +} + +// LeafHashForLeaf returns the leaf hash for a Merkle tree leaf. +func LeafHashForLeaf(leaf *MerkleTreeLeaf) ([sha256.Size]byte, error) { + leafData, err := tls.Marshal(*leaf) + if err != nil { + return [sha256.Size]byte{}, fmt.Errorf("failed to tls-encode MerkleTreeLeaf: %s", err) + } + + data := append([]byte{TreeLeafPrefix}, leafData...) + leafHash := sha256.Sum256(data) + return leafHash, nil +} + // IsPreIssuer indicates whether a certificate is a pre-cert issuer with the specific // certificate transparency extended key usage. func IsPreIssuer(issuer *x509.Certificate) bool { @@ -200,56 +248,100 @@ func IsPreIssuer(issuer *x509.Certificate) bool { return false } -// LogEntryFromLeaf converts a LeafEntry object (which has the raw leaf data after JSON parsing) -// into a LogEntry object (which includes x509.Certificate objects, after TLS and ASN.1 parsing). -// Note that this function may return a valid LogEntry object and a non-nil error value, when -// the error indicates a non-fatal parsing error (of type x509.NonFatalErrors). -func LogEntryFromLeaf(index int64, leafEntry *LeafEntry) (*LogEntry, error) { - var leaf MerkleTreeLeaf - if rest, err := tls.Unmarshal(leafEntry.LeafInput, &leaf); err != nil { - return nil, fmt.Errorf("failed to unmarshal MerkleTreeLeaf for index %d: %v", index, err) +// RawLogEntryFromLeaf converts a LeafEntry object (which has the raw leaf data +// after JSON parsing) into a RawLogEntry object (i.e. a TLS-parsed structure). +func RawLogEntryFromLeaf(index int64, entry *LeafEntry) (*RawLogEntry, error) { + ret := RawLogEntry{Index: index} + if rest, err := tls.Unmarshal(entry.LeafInput, &ret.Leaf); err != nil { + return nil, fmt.Errorf("failed to unmarshal MerkleTreeLeaf: %v", err) } else if len(rest) > 0 { - return nil, fmt.Errorf("trailing data (%d bytes) after MerkleTreeLeaf for index %d", len(rest), index) + return nil, fmt.Errorf("MerkleTreeLeaf: trailing data %d bytes", len(rest)) } - var err error - entry := LogEntry{Index: index, Leaf: leaf} - switch leaf.TimestampedEntry.EntryType { + switch eType := ret.Leaf.TimestampedEntry.EntryType; eType { case X509LogEntryType: var certChain CertificateChain - if rest, err := tls.Unmarshal(leafEntry.ExtraData, &certChain); err != nil { - return nil, fmt.Errorf("failed to unmarshal ExtraData for index %d: %v", index, err) + if rest, err := tls.Unmarshal(entry.ExtraData, &certChain); err != nil { + return nil, fmt.Errorf("failed to unmarshal CertificateChain: %v", err) } else if len(rest) > 0 { - return nil, fmt.Errorf("trailing data (%d bytes) after CertificateChain for index %d", len(rest), index) - } - entry.Chain = certChain.Entries - entry.X509Cert, err = leaf.X509Certificate() - if _, ok := err.(x509.NonFatalErrors); !ok && err != nil { - return nil, fmt.Errorf("failed to parse certificate in MerkleTreeLeaf for index %d: %v", index, err) + return nil, fmt.Errorf("CertificateChain: trailing data %d bytes", len(rest)) } + ret.Cert = *ret.Leaf.TimestampedEntry.X509Entry + ret.Chain = certChain.Entries case PrecertLogEntryType: var precertChain PrecertChainEntry - if rest, err := tls.Unmarshal(leafEntry.ExtraData, &precertChain); err != nil { - return nil, fmt.Errorf("failed to unmarshal PrecertChainEntry for index %d: %v", index, err) + if rest, err := tls.Unmarshal(entry.ExtraData, &precertChain); err != nil { + return nil, fmt.Errorf("failed to unmarshal PrecertChainEntry: %v", err) } else if len(rest) > 0 { - return nil, fmt.Errorf("trailing data (%d bytes) after PrecertChainEntry for index %d", len(rest), index) + return nil, fmt.Errorf("PrecertChainEntry: trailing data %d bytes", len(rest)) + } + ret.Cert = precertChain.PreCertificate + ret.Chain = precertChain.CertificateChain + + default: + // TODO(pavelkalinnikov): Section 4.6 of RFC6962 implies that unknown types + // are not errors. We should revisit how we process this case. + return nil, fmt.Errorf("unknown entry type: %v", eType) + } + + return &ret, nil +} + +// ToLogEntry converts RawLogEntry to a LogEntry, which includes an x509-parsed +// (pre-)certificate. +// +// Note that this function may return a valid LogEntry object and a non-nil +// error value, when the error indicates a non-fatal parsing error. +func (rle *RawLogEntry) ToLogEntry() (*LogEntry, error) { + var err error + entry := LogEntry{Index: rle.Index, Leaf: rle.Leaf, Chain: rle.Chain} + + switch eType := rle.Leaf.TimestampedEntry.EntryType; eType { + case X509LogEntryType: + entry.X509Cert, err = rle.Leaf.X509Certificate() + if x509.IsFatal(err) { + return nil, fmt.Errorf("failed to parse certificate: %v", err) } - entry.Chain = precertChain.CertificateChain + + case PrecertLogEntryType: var tbsCert *x509.Certificate - tbsCert, err = leaf.Precertificate() - if _, ok := err.(x509.NonFatalErrors); !ok && err != nil { - return nil, fmt.Errorf("failed to parse precertificate in MerkleTreeLeaf for index %d: %v", index, err) + tbsCert, err = rle.Leaf.Precertificate() + if x509.IsFatal(err) { + return nil, fmt.Errorf("failed to parse precertificate: %v", err) } entry.Precert = &Precertificate{ - Submitted: precertChain.PreCertificate, - IssuerKeyHash: leaf.TimestampedEntry.PrecertEntry.IssuerKeyHash, + Submitted: rle.Cert, + IssuerKeyHash: rle.Leaf.TimestampedEntry.PrecertEntry.IssuerKeyHash, TBSCertificate: tbsCert, } default: - return nil, fmt.Errorf("saw unknown entry type at index %d: %v", index, leaf.TimestampedEntry.EntryType) + return nil, fmt.Errorf("unknown entry type: %v", eType) } - // err may hold a x509.NonFatalErrors object. + + // err may be non-nil for a non-fatal error. return &entry, err } + +// LogEntryFromLeaf converts a LeafEntry object (which has the raw leaf data +// after JSON parsing) into a LogEntry object (which includes x509.Certificate +// objects, after TLS and ASN.1 parsing). +// +// Note that this function may return a valid LogEntry object and a non-nil +// error value, when the error indicates a non-fatal parsing error. +func LogEntryFromLeaf(index int64, leaf *LeafEntry) (*LogEntry, error) { + rle, err := RawLogEntryFromLeaf(index, leaf) + if err != nil { + return nil, err + } + return rle.ToLogEntry() +} + +// TimestampToTime converts a timestamp in the style of RFC 6962 (milliseconds +// since UNIX epoch) to a Go Time. +func TimestampToTime(ts uint64) time.Time { + secs := int64(ts / 1000) + msecs := int64(ts % 1000) + return time.Unix(secs, msecs*1000000) +} diff --git a/vendor/github.com/google/certificate-transparency-go/signatures.go b/vendor/github.com/google/certificate-transparency-go/signatures.go index 5129de5572..b1000ba464 100644 --- a/vendor/github.com/google/certificate-transparency-go/signatures.go +++ b/vendor/github.com/google/certificate-transparency-go/signatures.go @@ -20,8 +20,8 @@ import ( "crypto/elliptic" "crypto/rsa" "crypto/sha256" + "encoding/base64" "encoding/pem" - "flag" "fmt" "log" @@ -29,8 +29,10 @@ import ( "github.com/google/certificate-transparency-go/x509" ) -var allowVerificationWithNonCompliantKeys = flag.Bool("allow_verification_with_non_compliant_keys", false, - "Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.") +// AllowVerificationWithNonCompliantKeys may be set to true in order to allow +// SignatureVerifier to use keys which are technically non-compliant with +// RFC6962. +var AllowVerificationWithNonCompliantKeys = false // PublicKeyFromPEM parses a PEM formatted block and returns the public key contained within and any remaining unread bytes, or an error. func PublicKeyFromPEM(b []byte) (crypto.PublicKey, SHA256Hash, []byte, error) { @@ -42,6 +44,15 @@ func PublicKeyFromPEM(b []byte) (crypto.PublicKey, SHA256Hash, []byte, error) { return k, sha256.Sum256(p.Bytes), rest, err } +// PublicKeyFromB64 parses a base64-encoded public key. +func PublicKeyFromB64(b64PubKey string) (crypto.PublicKey, error) { + der, err := base64.StdEncoding.DecodeString(b64PubKey) + if err != nil { + return nil, fmt.Errorf("error decoding public key: %s", err) + } + return x509.ParsePKIXPublicKey(der) +} + // SignatureVerifier can verify signatures on SCTs and STHs type SignatureVerifier struct { pubKey crypto.PublicKey @@ -53,7 +64,7 @@ func NewSignatureVerifier(pk crypto.PublicKey) (*SignatureVerifier, error) { case *rsa.PublicKey: if pkType.N.BitLen() < 2048 { e := fmt.Errorf("public key is RSA with < 2048 bits (size:%d)", pkType.N.BitLen()) - if !(*allowVerificationWithNonCompliantKeys) { + if !AllowVerificationWithNonCompliantKeys { return nil, e } log.Printf("WARNING: %v", e) @@ -62,7 +73,7 @@ func NewSignatureVerifier(pk crypto.PublicKey) (*SignatureVerifier, error) { params := *(pkType.Params()) if params != *elliptic.P256().Params() { e := fmt.Errorf("public is ECDSA, but not on the P256 curve") - if !(*allowVerificationWithNonCompliantKeys) { + if !AllowVerificationWithNonCompliantKeys { return nil, e } log.Printf("WARNING: %v", e) diff --git a/vendor/github.com/google/certificate-transparency-go/tls/types.go b/vendor/github.com/google/certificate-transparency-go/tls/types.go index 53d8ec7aa7..14471ad264 100644 --- a/vendor/github.com/google/certificate-transparency-go/tls/types.go +++ b/vendor/github.com/google/certificate-transparency-go/tls/types.go @@ -14,7 +14,13 @@ package tls -import "fmt" +import ( + "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/rsa" + "fmt" +) // DigitallySigned gives information about a signature, including the algorithm used // and the signature value. Defined in RFC 5246 s4.7. @@ -94,3 +100,18 @@ func (s SignatureAlgorithm) String() string { return fmt.Sprintf("UNKNOWN(%d)", s) } } + +// SignatureAlgorithmFromPubKey returns the algorithm used for this public key. +// ECDSA, RSA, and DSA keys are supported. Other key types will return Anonymous. +func SignatureAlgorithmFromPubKey(k crypto.PublicKey) SignatureAlgorithm { + switch k.(type) { + case *ecdsa.PublicKey: + return ECDSA + case *rsa.PublicKey: + return RSA + case *dsa.PublicKey: + return DSA + default: + return Anonymous + } +} diff --git a/vendor/github.com/google/certificate-transparency-go/types.go b/vendor/github.com/google/certificate-transparency-go/types.go index c172ce03a7..156b5c64de 100644 --- a/vendor/github.com/google/certificate-transparency-go/types.go +++ b/vendor/github.com/google/certificate-transparency-go/types.go @@ -54,6 +54,12 @@ func (e LogEntryType) String() string { } } +// RFC6962 section 2.1 requires a prefix byte on hash inputs for second preimage resistance. +const ( + TreeLeafPrefix = byte(0x00) + TreeNodePrefix = byte(0x01) +) + // MerkleLeafType represents the MerkleLeafType enum from section 3.4: // enum { timestamped_entry(0), (255) } MerkleLeafType; type MerkleLeafType tls.Enum // tls:"maxval:255" @@ -193,6 +199,25 @@ func (d *DigitallySigned) UnmarshalJSON(b []byte) error { return d.FromBase64String(content) } +// RawLogEntry represents the (TLS-parsed) contents of an entry in a CT log. +type RawLogEntry struct { + // Index is a position of the entry in the log. + Index int64 + // Leaf is a parsed Merkle leaf hash input. + Leaf MerkleTreeLeaf + // Cert is: + // - A certificate if Leaf.TimestampedEntry.EntryType is X509LogEntryType. + // - A precertificate if Leaf.TimestampedEntry.EntryType is + // PrecertLogEntryType, in the form of a DER-encoded Certificate as + // originally added (which includes the poison extension and a signature + // generated over the pre-cert by the pre-cert issuer). + // - Empty otherwise. + Cert ASN1Cert + // Chain is the issuing certificate chain starting with the issuer of Cert, + // or an empty slice if Cert is empty. + Chain []ASN1Cert +} + // LogEntry represents the (parsed) contents of an entry in a CT log. This is described // in section 3.1, but note that this structure does *not* match the TLS structure // defined there (the TLS structure is never used directly in RFC6962). @@ -368,7 +393,27 @@ func (m *MerkleTreeLeaf) Precertificate() (*x509.Certificate, error) { return x509.ParseTBSCertificate(m.TimestampedEntry.PrecertEntry.TBSCertificate) } +// APIEndpoint is a string that represents one of the Certificate Transparency +// Log API endpoints. +type APIEndpoint string + +// Certificate Transparency Log API endpoints; see section 4. +// WARNING: Should match the URI paths without the "/ct/v1/" prefix. If +// changing these constants, may need to change those too. +const ( + AddChainStr APIEndpoint = "add-chain" + AddPreChainStr APIEndpoint = "add-pre-chain" + GetSTHStr APIEndpoint = "get-sth" + GetEntriesStr APIEndpoint = "get-entries" + GetProofByHashStr APIEndpoint = "get-proof-by-hash" + GetSTHConsistencyStr APIEndpoint = "get-sth-consistency" + GetRootsStr APIEndpoint = "get-roots" + GetEntryAndProofStr APIEndpoint = "get-entry-and-proof" +) + // URI paths for Log requests; see section 4. +// WARNING: Should match the API endpoints, with the "/ct/v1/" prefix. If +// changing these constants, may need to change those too. const ( AddChainPath = "/ct/v1/add-chain" AddPreChainPath = "/ct/v1/add-pre-chain" @@ -415,6 +460,29 @@ type GetSTHResponse struct { TreeHeadSignature []byte `json:"tree_head_signature"` // Log signature for this STH } +// ToSignedTreeHead creates a SignedTreeHead from the GetSTHResponse. +func (r *GetSTHResponse) ToSignedTreeHead() (*SignedTreeHead, error) { + sth := SignedTreeHead{ + TreeSize: r.TreeSize, + Timestamp: r.Timestamp, + } + + if len(r.SHA256RootHash) != sha256.Size { + return nil, fmt.Errorf("sha256_root_hash is invalid length, expected %d got %d", sha256.Size, len(r.SHA256RootHash)) + } + copy(sth.SHA256RootHash[:], r.SHA256RootHash) + + var ds DigitallySigned + if rest, err := tls.Unmarshal(r.TreeHeadSignature, &ds); err != nil { + return nil, fmt.Errorf("tls.Unmarshal(): %s", err) + } else if len(rest) > 0 { + return nil, fmt.Errorf("trailing data (%d bytes) after DigitallySigned", len(rest)) + } + sth.TreeHeadSignature = ds + + return &sth, nil +} + // GetSTHConsistencyResponse represents the JSON response to the get-sth-consistency // GET method from section 4.4. (The corresponding GET request has parameters 'first' and // 'second'.) diff --git a/vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go b/vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go index 71ffbdf0e0..1196479a0c 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/cert_pool.go @@ -121,7 +121,7 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) { } cert, err := ParseCertificate(block.Bytes) - if err != nil { + if IsFatal(err) { continue } diff --git a/vendor/github.com/google/certificate-transparency-go/x509/curves.go b/vendor/github.com/google/certificate-transparency-go/x509/curves.go new file mode 100644 index 0000000000..0e2778cb35 --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/x509/curves.go @@ -0,0 +1,37 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "crypto/elliptic" + "math/big" + "sync" +) + +// This file holds ECC curves that are not supported by the main Go crypto/elliptic +// library, but which have been observed in certificates in the wild. + +var initonce sync.Once +var p192r1 *elliptic.CurveParams + +func initAllCurves() { + initSECP192R1() +} + +func initSECP192R1() { + // See SEC-2, section 2.2.2 + p192r1 = &elliptic.CurveParams{Name: "P-192"} + p192r1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16) + p192r1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 16) + p192r1.B, _ = new(big.Int).SetString("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 16) + p192r1.Gx, _ = new(big.Int).SetString("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", 16) + p192r1.Gy, _ = new(big.Int).SetString("07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", 16) + p192r1.BitSize = 192 +} + +func secp192r1() elliptic.Curve { + initonce.Do(initAllCurves) + return p192r1 +} diff --git a/vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go b/vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go new file mode 100644 index 0000000000..3543e3042c --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/x509/ptr_sysptr_windows.go @@ -0,0 +1,20 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.11 + +package x509 + +import ( + "syscall" + "unsafe" +) + +// For Go versions >= 1.11, the ExtraPolicyPara field in +// syscall.CertChainPolicyPara is of type syscall.Pointer. See: +// https://github.com/golang/go/commit/4869ec00e87ef + +func convertToPolicyParaType(p unsafe.Pointer) syscall.Pointer { + return (syscall.Pointer)(p) +} diff --git a/vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go b/vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go new file mode 100644 index 0000000000..3908833a89 --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/x509/ptr_uint_windows.go @@ -0,0 +1,17 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.11 + +package x509 + +import "unsafe" + +// For Go versions before 1.11, the ExtraPolicyPara field in +// syscall.CertChainPolicyPara was of type uintptr. See: +// https://github.com/golang/go/commit/4869ec00e87ef + +func convertToPolicyParaType(p unsafe.Pointer) uintptr { + return uintptr(p) +} diff --git a/vendor/github.com/google/certificate-transparency-go/x509/revoked.go b/vendor/github.com/google/certificate-transparency-go/x509/revoked.go index e704441639..fde74b942a 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/revoked.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/revoked.go @@ -14,12 +14,15 @@ import ( "github.com/google/certificate-transparency-go/x509/pkix" ) +// OID values for CRL extensions (TBSCertList.Extensions), RFC 5280 s5.2. var ( - // OID values for CRL extensions (TBSCertList.Extensions), RFC 5280 s5.2. OIDExtensionCRLNumber = asn1.ObjectIdentifier{2, 5, 29, 20} OIDExtensionDeltaCRLIndicator = asn1.ObjectIdentifier{2, 5, 29, 27} OIDExtensionIssuingDistributionPoint = asn1.ObjectIdentifier{2, 5, 29, 28} - // OID values for CRL entry extensions (RevokedCertificate.Extensions), RFC 5280 s5.3 +) + +// OID values for CRL entry extensions (RevokedCertificate.Extensions), RFC 5280 s5.3 +var ( OIDExtensionCRLReasons = asn1.ObjectIdentifier{2, 5, 29, 21} OIDExtensionInvalidityDate = asn1.ObjectIdentifier{2, 5, 29, 24} OIDExtensionCertificateIssuer = asn1.ObjectIdentifier{2, 5, 29, 29} @@ -238,7 +241,7 @@ func ParseCertificateListDER(derBytes []byte) (*CertificateList, error) { } case e.Id.Equal(OIDExtensionAuthorityInfoAccess): // RFC 5280 s5.2.7 - var aia []authorityInfoAccess + var aia []accessDescription if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil { errs.AddID(ErrInvalidCertListAuthInfoAccess, err) } else if len(rest) != 0 { diff --git a/vendor/github.com/google/certificate-transparency-go/x509/root_windows.go b/vendor/github.com/google/certificate-transparency-go/x509/root_windows.go index 92cc71692d..304ad3a679 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/root_windows.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/root_windows.go @@ -109,7 +109,7 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex sslPara.Size = uint32(unsafe.Sizeof(*sslPara)) para := &syscall.CertChainPolicyPara{ - ExtraPolicyPara: uintptr(unsafe.Pointer(sslPara)), + ExtraPolicyPara: convertToPolicyParaType(unsafe.Pointer(sslPara)), } para.Size = uint32(unsafe.Sizeof(*para)) diff --git a/vendor/github.com/google/certificate-transparency-go/x509/rpki.go b/vendor/github.com/google/certificate-transparency-go/x509/rpki.go new file mode 100644 index 0000000000..520d6dc3ab --- /dev/null +++ b/vendor/github.com/google/certificate-transparency-go/x509/rpki.go @@ -0,0 +1,242 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + + "github.com/google/certificate-transparency-go/asn1" +) + +// IPAddressPrefix describes an IP address prefix as an ASN.1 bit string, +// where the BitLength field holds the prefix length. +type IPAddressPrefix asn1.BitString + +// IPAddressRange describes an (inclusive) IP address range. +type IPAddressRange struct { + Min IPAddressPrefix + Max IPAddressPrefix +} + +// Most relevant values for AFI from: +// http://www.iana.org/assignments/address-family-numbers. +const ( + IPv4AddressFamilyIndicator = uint16(1) + IPv6AddressFamilyIndicator = uint16(2) +) + +// IPAddressFamilyBlocks describes a set of ranges of IP addresses. +type IPAddressFamilyBlocks struct { + // AFI holds an address family indicator from + // http://www.iana.org/assignments/address-family-numbers. + AFI uint16 + // SAFI holds a subsequent address family indicator from + // http://www.iana.org/assignments/safi-namespace. + SAFI byte + // InheritFromIssuer indicates that the set of addresses should + // be taken from the issuer's certificate. + InheritFromIssuer bool + // AddressPrefixes holds prefixes if InheritFromIssuer is false. + AddressPrefixes []IPAddressPrefix + // AddressRanges holds ranges if InheritFromIssuer is false. + AddressRanges []IPAddressRange +} + +// Internal types for asn1 unmarshalling. +type ipAddressFamily struct { + AddressFamily []byte // 2-byte AFI plus optional 1 byte SAFI + Choice asn1.RawValue +} + +// Internally, use raw asn1.BitString rather than the IPAddressPrefix +// type alias (so that asn1.Unmarshal() decodes properly). +type ipAddressRange struct { + Min asn1.BitString + Max asn1.BitString +} + +func parseRPKIAddrBlocks(data []byte, nfe *NonFatalErrors) []*IPAddressFamilyBlocks { + // RFC 3779 2.2.3 + // IPAddrBlocks ::= SEQUENCE OF IPAddressFamily + // + // IPAddressFamily ::= SEQUENCE { -- AFI & optional SAFI -- + // addressFamily OCTET STRING (SIZE (2..3)), + // ipAddressChoice IPAddressChoice } + // + // IPAddressChoice ::= CHOICE { + // inherit NULL, -- inherit from issuer -- + // addressesOrRanges SEQUENCE OF IPAddressOrRange } + // + // IPAddressOrRange ::= CHOICE { + // addressPrefix IPAddress, + // addressRange IPAddressRange } + // + // IPAddressRange ::= SEQUENCE { + // min IPAddress, + // max IPAddress } + // + // IPAddress ::= BIT STRING + + var addrBlocks []ipAddressFamily + if rest, err := asn1.Unmarshal(data, &addrBlocks); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks extension: %v", err)) + return nil + } else if len(rest) != 0 { + nfe.AddError(errors.New("trailing data after ipAddrBlocks extension")) + return nil + } + + var results []*IPAddressFamilyBlocks + for i, block := range addrBlocks { + var fam IPAddressFamilyBlocks + if l := len(block.AddressFamily); l < 2 || l > 3 { + nfe.AddError(fmt.Errorf("invalid address family length (%d) for ipAddrBlock.addressFamily", l)) + continue + } + fam.AFI = binary.BigEndian.Uint16(block.AddressFamily[0:2]) + if len(block.AddressFamily) > 2 { + fam.SAFI = block.AddressFamily[2] + } + // IPAddressChoice is an ASN.1 CHOICE where the chosen alternative is indicated by (implicit) + // tagging of the alternatives -- here, either NULL or SEQUENCE OF. + if bytes.Equal(block.Choice.FullBytes, asn1.NullBytes) { + fam.InheritFromIssuer = true + results = append(results, &fam) + continue + } + + var addrRanges []asn1.RawValue + if _, err := asn1.Unmarshal(block.Choice.FullBytes, &addrRanges); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges: %v", i, err)) + continue + } + for j, ar := range addrRanges { + // Each IPAddressOrRange is a CHOICE where the alternatives have distinct (implicit) + // tags -- here, either BIT STRING or SEQUENCE. + switch ar.Tag { + case asn1.TagBitString: + // BIT STRING for single prefix IPAddress + var val asn1.BitString + if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressPrefix: %v", i, j, err)) + continue + } + fam.AddressPrefixes = append(fam.AddressPrefixes, IPAddressPrefix(val)) + + case asn1.TagSequence: + var val ipAddressRange + if _, err := asn1.Unmarshal(ar.FullBytes, &val); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d].addressRange: %v", i, j, err)) + continue + } + fam.AddressRanges = append(fam.AddressRanges, IPAddressRange{Min: IPAddressPrefix(val.Min), Max: IPAddressPrefix(val.Max)}) + + default: + nfe.AddError(fmt.Errorf("unexpected ASN.1 type in ipAddrBlocks[%d].ipAddressChoice.addressesOrRanges[%d]: %+v", i, j, ar)) + } + } + results = append(results, &fam) + } + return results +} + +// ASIDRange describes an inclusive range of AS Identifiers (AS numbers or routing +// domain identifiers). +type ASIDRange struct { + Min int + Max int +} + +// ASIdentifiers describes a collection of AS Identifiers (AS numbers or routing +// domain identifiers). +type ASIdentifiers struct { + // InheritFromIssuer indicates that the set of AS identifiers should + // be taken from the issuer's certificate. + InheritFromIssuer bool + // ASIDs holds AS identifiers if InheritFromIssuer is false. + ASIDs []int + // ASIDs holds AS identifier ranges (inclusive) if InheritFromIssuer is false. + ASIDRanges []ASIDRange +} + +type asIdentifiers struct { + ASNum asn1.RawValue `asn1:"optional,tag:0"` + RDI asn1.RawValue `asn1:"optional,tag:1"` +} + +func parseASIDChoice(val asn1.RawValue, nfe *NonFatalErrors) *ASIdentifiers { + // RFC 3779 2.3.2 + // ASIdentifierChoice ::= CHOICE { + // inherit NULL, -- inherit from issuer -- + // asIdsOrRanges SEQUENCE OF ASIdOrRange } + // ASIdOrRange ::= CHOICE { + // id ASId, + // range ASRange } + // ASRange ::= SEQUENCE { + // min ASId, + // max ASId } + // ASId ::= INTEGER + if len(val.FullBytes) == 0 { // OPTIONAL + return nil + } + // ASIdentifierChoice is an ASN.1 CHOICE where the chosen alternative is indicated by (implicit) + // tagging of the alternatives -- here, either NULL or SEQUENCE OF. + if bytes.Equal(val.Bytes, asn1.NullBytes) { + return &ASIdentifiers{InheritFromIssuer: true} + } + var ids []asn1.RawValue + if rest, err := asn1.Unmarshal(val.Bytes, &ids); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges: %v", err)) + return nil + } else if len(rest) != 0 { + nfe.AddError(errors.New("trailing data after ASIdentifiers.asIdsOrRanges")) + return nil + } + var asID ASIdentifiers + for i, id := range ids { + // Each ASIdOrRange is a CHOICE where the alternatives have distinct (implicit) + // tags -- here, either INTEGER or SEQUENCE. + switch id.Tag { + case asn1.TagInteger: + var val int + if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].id: %v", i, err)) + continue + } + asID.ASIDs = append(asID.ASIDs, val) + + case asn1.TagSequence: + var val ASIDRange + if _, err := asn1.Unmarshal(id.FullBytes, &val); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers.asIdsOrRanges[%d].range: %v", i, err)) + continue + } + asID.ASIDRanges = append(asID.ASIDRanges, val) + + default: + nfe.AddError(fmt.Errorf("unexpected value in ASIdentifiers.asIdsOrRanges[%d]: %+v", i, id)) + } + } + return &asID +} + +func parseRPKIASIdentifiers(data []byte, nfe *NonFatalErrors) (*ASIdentifiers, *ASIdentifiers) { + // RFC 3779 2.3.2 + // ASIdentifiers ::= SEQUENCE { + // asnum [0] EXPLICIT ASIdentifierChoice OPTIONAL, + // rdi [1] EXPLICIT ASIdentifierChoice OPTIONAL} + var asIDs asIdentifiers + if rest, err := asn1.Unmarshal(data, &asIDs); err != nil { + nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal ASIdentifiers extension: %v", err)) + return nil, nil + } else if len(rest) != 0 { + nfe.AddError(errors.New("trailing data after ASIdentifiers extension")) + return nil, nil + } + return parseASIDChoice(asIDs.ASNum, nfe), parseASIDChoice(asIDs.RDI, nfe) +} diff --git a/vendor/github.com/google/certificate-transparency-go/x509/sec1.go b/vendor/github.com/google/certificate-transparency-go/x509/sec1.go index ae4f81e560..7c51e15c44 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/sec1.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/sec1.go @@ -72,11 +72,12 @@ func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *e return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) } + var nfe NonFatalErrors var curve elliptic.Curve if namedCurveOID != nil { - curve = namedCurveFromOID(*namedCurveOID) + curve = namedCurveFromOID(*namedCurveOID, &nfe) } else { - curve = namedCurveFromOID(privKey.NamedCurveOID) + curve = namedCurveFromOID(privKey.NamedCurveOID, &nfe) } if curve == nil { return nil, errors.New("x509: unknown elliptic curve") diff --git a/vendor/github.com/google/certificate-transparency-go/x509/verify.go b/vendor/github.com/google/certificate-transparency-go/x509/verify.go index ee4c97bfb9..beafc3b000 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/verify.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/verify.go @@ -12,9 +12,12 @@ import ( "net/url" "reflect" "runtime" + "strconv" "strings" "time" "unicode/utf8" + + "github.com/google/certificate-transparency-go/asn1" ) type InvalidReason int @@ -174,19 +177,29 @@ var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificat // VerifyOptions contains parameters for Certificate.Verify. It's a structure // because other PKIX verification APIs have ended up needing many options. type VerifyOptions struct { - DNSName string - Intermediates *CertPool - Roots *CertPool // if nil, the system roots are used - CurrentTime time.Time // if zero, the current time is used - DisableTimeChecks bool - // KeyUsage specifies which Extended Key Usage values are acceptable. - // An empty list means ExtKeyUsageServerAuth. Key usage is considered a - // constraint down the chain which mirrors Windows CryptoAPI behavior, - // but not the spec. To accept any key usage, include ExtKeyUsageAny. + DNSName string + Intermediates *CertPool + Roots *CertPool // if nil, the system roots are used + CurrentTime time.Time // if zero, the current time is used + // Options to disable various verification checks. + DisableTimeChecks bool + DisableCriticalExtensionChecks bool + DisableNameChecks bool + DisableEKUChecks bool + DisablePathLenChecks bool + DisableNameConstraintChecks bool + // KeyUsage specifies which Extended Key Usage values are acceptable. A leaf + // certificate is accepted if it contains any of the listed values. An empty + // list means ExtKeyUsageServerAuth. To accept any key usage, include + // ExtKeyUsageAny. + // + // Certificate chains are required to nest extended key usage values, + // irrespective of this value. This matches the Windows CryptoAPI behavior, + // but not the spec. KeyUsages []ExtKeyUsage // MaxConstraintComparisions is the maximum number of comparisons to // perform when checking a given certificate's name constraints. If - // zero, a sensible default is used. This limit prevents pathalogical + // zero, a sensible default is used. This limit prevents pathological // certificates from consuming excessive amounts of CPU time when // validating. MaxConstraintComparisions int @@ -544,11 +557,16 @@ func (c *Certificate) checkNameConstraints(count *int, return nil } +const ( + checkingAgainstIssuerCert = iota + checkingAgainstLeafCert +) + // ekuPermittedBy returns true iff the given extended key usage is permitted by // the given EKU from a certificate. Normally, this would be a simple // comparison plus a special case for the “any” EKU. But, in order to support // existing certificates, some exceptions are made. -func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool { +func ekuPermittedBy(eku, certEKU ExtKeyUsage, context int) bool { if certEKU == ExtKeyUsageAny || eku == certEKU { return true } @@ -565,28 +583,33 @@ func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool { eku = mapServerAuthEKUs(eku) certEKU = mapServerAuthEKUs(certEKU) - if eku == certEKU || - // ServerAuth in a CA permits ClientAuth in the leaf. - (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) || + if eku == certEKU { + return true + } + + // If checking a requested EKU against the list in a leaf certificate there + // are fewer exceptions. + if context == checkingAgainstLeafCert { + return false + } + + // ServerAuth in a CA permits ClientAuth in the leaf. + return (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) || // Any CA may issue an OCSP responder certificate. eku == ExtKeyUsageOCSPSigning || // Code-signing CAs can use Microsoft's commercial and // kernel-mode EKUs. - ((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) { - return true - } - - return false + (eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning } // isValid performs validity checks on c given that it is a candidate to append // to the chain in currentChain. func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error { - if len(c.UnhandledCriticalExtensions) > 0 { + if !opts.DisableCriticalExtensionChecks && len(c.UnhandledCriticalExtensions) > 0 { return UnhandledCriticalExtension{ID: c.UnhandledCriticalExtensions[0]} } - if len(currentChain) > 0 { + if !opts.DisableNameChecks && len(currentChain) > 0 { child := currentChain[len(currentChain)-1] if !bytes.Equal(child.RawIssuer, c.RawSubject) { return CertificateInvalidError{c, NameMismatch, ""} @@ -617,7 +640,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V leaf = currentChain[0] } - if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() { + if !opts.DisableNameConstraintChecks && (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() { sanExtension, ok := leaf.getSANExtension() if !ok { // This is the deprecated, legacy case of depending on @@ -633,8 +656,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V name := string(data) mailbox, ok := parseRFC2821Mailbox(name) if !ok { - // This certificate should not have parsed. - return errors.New("x509: internal error: rfc822Name SAN failed to parse") + return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox) } if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox, @@ -646,6 +668,10 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V case nameTypeDNS: name := string(data) + if _, ok := domainToReverseLabels(name); !ok { + return fmt.Errorf("x509: cannot parse dnsName %q", name) + } + if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name, func(parsedName, constraint interface{}) (bool, error) { return matchDomainConstraint(parsedName.(string), constraint.(string)) @@ -692,7 +718,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V } } - checkEKUs := certType == intermediateCertificate + checkEKUs := !opts.DisableEKUChecks && certType == intermediateCertificate // If no extended key usages are specified, then all are acceptable. if checkEKUs && (len(c.ExtKeyUsage) == 0 && len(c.UnknownExtKeyUsage) == 0) { @@ -719,7 +745,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V for _, caEKU := range c.ExtKeyUsage { comparisonCount++ - if ekuPermittedBy(eku, caEKU) { + if ekuPermittedBy(eku, caEKU, checkingAgainstIssuerCert) { continue NextEKU } } @@ -766,7 +792,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V return CertificateInvalidError{c, NotAuthorizedToSign, ""} } - if c.BasicConstraintsValid && c.MaxPathLen >= 0 { + if !opts.DisablePathLenChecks && c.BasicConstraintsValid && c.MaxPathLen >= 0 { numIntermediates := len(currentChain) - 1 if numIntermediates > c.MaxPathLen { return CertificateInvalidError{c, TooManyIntermediates, ""} @@ -776,6 +802,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V return nil } +// formatOID formats an ASN.1 OBJECT IDENTIFER in the common, dotted style. +func formatOID(oid asn1.ObjectIdentifier) string { + ret := "" + for i, v := range oid { + if i > 0 { + ret += "." + } + ret += strconv.Itoa(v) + } + return ret +} + // Verify attempts to verify c by building one or more chains from c to a // certificate in opts.Roots, using certificates in opts.Intermediates if // needed. If successful, it returns one or more chains where the first @@ -840,7 +878,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e } // If no key usages are specified, then any are acceptable. - checkEKU := len(c.ExtKeyUsage) > 0 + checkEKU := !opts.DisableEKUChecks && len(c.ExtKeyUsage) > 0 for _, eku := range requestedKeyUsages { if eku == ExtKeyUsageAny { @@ -850,16 +888,33 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e } if checkEKU { + foundMatch := false NextUsage: for _, eku := range requestedKeyUsages { for _, leafEKU := range c.ExtKeyUsage { - if ekuPermittedBy(eku, leafEKU) { - continue NextUsage + if ekuPermittedBy(eku, leafEKU, checkingAgainstLeafCert) { + foundMatch = true + break NextUsage } } + } - oid, _ := oidFromExtKeyUsage(eku) - return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)} + if !foundMatch { + msg := "leaf contains the following, recognized EKUs: " + + for i, leafEKU := range c.ExtKeyUsage { + oid, ok := oidFromExtKeyUsage(leafEKU) + if !ok { + continue + } + + if i > 0 { + msg += ", " + } + msg += formatOID(oid) + } + + return nil, CertificateInvalidError{c, IncompatibleUsage, msg} } } diff --git a/vendor/github.com/google/certificate-transparency-go/x509/x509.go b/vendor/github.com/google/certificate-transparency-go/x509/x509.go index 33d1ed684e..387bc432bf 100644 --- a/vendor/github.com/google/certificate-transparency-go/x509/x509.go +++ b/vendor/github.com/google/certificate-transparency-go/x509/x509.go @@ -8,9 +8,39 @@ // can be used to override the system default locations for the SSL certificate // file and SSL certificate files directory, respectively. // -// This is a fork of the go library crypto/x509 package, it's more relaxed -// about certificates that it'll accept, and exports the TBSCertificate -// structure. +// This is a fork of the Go library crypto/x509 package, primarily adapted for +// use with Certificate Transparency. Main areas of difference are: +// +// - Life as a fork: +// - Rename OS-specific cgo code so it doesn't clash with main Go library. +// - Use local library imports (asn1, pkix) throughout. +// - Add version-specific wrappers for Go version-incompatible code (in +// nilref_*_darwin.go, ptr_*_windows.go). +// - Laxer certificate parsing: +// - Add options to disable various validation checks (times, EKUs etc). +// - Use NonFatalErrors type for some errors and continue parsing; this +// can be checked with IsFatal(err). +// - Support for short bitlength ECDSA curves (in curves.go). +// - Certificate Transparency specific function: +// - Parsing and marshaling of SCTList extension. +// - RemoveSCTList() function for rebuilding CT leaf entry. +// - Pre-certificate processing (RemoveCTPoison(), BuildPrecertTBS(), +// ParseTBSCertificate(), IsPrecertificate()). +// - Revocation list processing: +// - Detailed CRL parsing (in revoked.go) +// - Detailed error recording mechanism (in error.go, errors.go) +// - Factor out parseDistributionPoints() for reuse. +// - Factor out and generalize GeneralNames parsing (in names.go) +// - Fix CRL commenting. +// - RPKI support: +// - Support for SubjectInfoAccess extension +// - Support for RFC3779 extensions (in rpki.go) +// - General improvements: +// - Export and use OID values throughout. +// - Export OIDFromNamedCurve(). +// - Export SignatureAlgorithmFromAI(). +// - Add OID value to UnhandledCriticalExtension error. +// - Minor typo/lint fixes. package x509 import ( @@ -69,7 +99,16 @@ func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) { if algo == UnknownPublicKeyAlgorithm { return nil, errors.New("x509: unknown public key algorithm") } - return parsePublicKey(algo, &pki) + var nfe NonFatalErrors + pub, err = parsePublicKey(algo, &pki, &nfe) + if err != nil { + return pub, err + } + // Treat non-fatal errors as fatal for this entrypoint. + if len(nfe.Errors) > 0 { + return nil, nfe.Errors[0] + } + return pub, nil } func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { @@ -500,15 +539,21 @@ func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm // secp521r1 OBJECT IDENTIFIER ::= { // iso(1) identified-organization(3) certicom(132) curve(0) 35 } // -// NB: secp256r1 is equivalent to prime256v1 +// secp192r1 OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) +// prime(1) 1 } +// +// NB: secp256r1 is equivalent to prime256v1, +// secp192r1 is equivalent to ansix9p192r and prime192v1 var ( OIDNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} OIDNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} OIDNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} OIDNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} + OIDNamedCurveP192 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 1} ) -func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { +func namedCurveFromOID(oid asn1.ObjectIdentifier, nfe *NonFatalErrors) elliptic.Curve { switch { case oid.Equal(OIDNamedCurveP224): return elliptic.P224() @@ -518,6 +563,9 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { return elliptic.P384() case oid.Equal(OIDNamedCurveP521): return elliptic.P521() + case oid.Equal(OIDNamedCurveP192): + nfe.AddError(errors.New("insecure curve (secp192r1) specified")) + return secp192r1() } return nil } @@ -534,6 +582,8 @@ func OIDFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { return OIDNamedCurveP384, true case elliptic.P521(): return OIDNamedCurveP521, true + case secp192r1(): + return OIDNamedCurveP192, true } return nil, false @@ -737,7 +787,13 @@ type Certificate struct { OCSPServer []string IssuingCertificateURL []string - // Subject Alternate Name values + // Subject Information Access + SubjectTimestamps []string + SubjectCARepositories []string + + // Subject Alternate Name values. (Note that these values may not be valid + // if invalid values were contained within a parsed certificate. For + // example, an element of DNSNames may not be a valid DNS domain name.) DNSNames []string EmailAddresses []string IPAddresses []net.IP @@ -759,6 +815,9 @@ type Certificate struct { PolicyIdentifiers []asn1.ObjectIdentifier + RPKIAddressRanges []*IPAddressFamilyBlocks + RPKIASNumbers, RPKIRoutingDomainIDs *ASIdentifiers + // Certificate Transparency SCT extension contents; this is a TLS-encoded // SignedCertificateTimestampList (RFC 6962 s3.3). RawSCT []byte @@ -792,6 +851,20 @@ func (c *Certificate) Equal(other *Certificate) bool { return bytes.Equal(c.Raw, other.Raw) } +// IsPrecertificate checks whether the certificate is a precertificate, by +// checking for the presence of the CT Poison extension. +func (c *Certificate) IsPrecertificate() bool { + if c == nil { + return false + } + for _, ext := range c.Extensions { + if ext.Id.Equal(OIDExtensionCTPoison) { + return true + } + } + return false +} + func (c *Certificate) hasSANExtension() bool { return oidInExtensions(OIDExtensionSubjectAltName, c.Extensions) } @@ -995,6 +1068,50 @@ func (h UnhandledCriticalExtension) Error() string { return fmt.Sprintf("x509: unhandled critical extension (%v)", h.ID) } +// removeExtension takes a DER-encoded TBSCertificate, removes the extension +// specified by oid (preserving the order of other extensions), and returns the +// result still as a DER-encoded TBSCertificate. This function will fail if +// there is not exactly 1 extension of the type specified by the oid present. +func removeExtension(tbsData []byte, oid asn1.ObjectIdentifier) ([]byte, error) { + var tbs tbsCertificate + rest, err := asn1.Unmarshal(tbsData, &tbs) + if err != nil { + return nil, fmt.Errorf("failed to parse TBSCertificate: %v", err) + } else if rLen := len(rest); rLen > 0 { + return nil, fmt.Errorf("trailing data (%d bytes) after TBSCertificate", rLen) + } + extAt := -1 + for i, ext := range tbs.Extensions { + if ext.Id.Equal(oid) { + if extAt != -1 { + return nil, errors.New("multiple extensions of specified type present") + } + extAt = i + } + } + if extAt == -1 { + return nil, errors.New("no extension of specified type present") + } + tbs.Extensions = append(tbs.Extensions[:extAt], tbs.Extensions[extAt+1:]...) + // Clear out the asn1.RawContent so the re-marshal operation sees the + // updated structure (rather than just copying the out-of-date DER data). + tbs.Raw = nil + + data, err := asn1.Marshal(tbs) + if err != nil { + return nil, fmt.Errorf("failed to re-marshal TBSCertificate: %v", err) + } + return data, nil +} + +// RemoveSCTList takes a DER-encoded TBSCertificate and removes the CT SCT +// extension that contains the SCT list (preserving the order of other +// extensions), and returns the result still as a DER-encoded TBSCertificate. +// This function will fail if there is not exactly 1 CT SCT extension present. +func RemoveSCTList(tbsData []byte) ([]byte, error) { + return removeExtension(tbsData, OIDExtensionCTSCT) +} + // RemoveCTPoison takes a DER-encoded TBSCertificate and removes the CT poison // extension (preserving the order of other extensions), and returns the result // still as a DER-encoded TBSCertificate. This function will fail if there is @@ -1019,27 +1136,18 @@ func RemoveCTPoison(tbsData []byte) ([]byte, error) { // - The precert's AuthorityKeyId is changed to the AuthorityKeyId of the // intermediate. func BuildPrecertTBS(tbsData []byte, preIssuer *Certificate) ([]byte, error) { + data, err := removeExtension(tbsData, OIDExtensionCTPoison) + if err != nil { + return nil, err + } + var tbs tbsCertificate - rest, err := asn1.Unmarshal(tbsData, &tbs) + rest, err := asn1.Unmarshal(data, &tbs) if err != nil { return nil, fmt.Errorf("failed to parse TBSCertificate: %v", err) } else if rLen := len(rest); rLen > 0 { return nil, fmt.Errorf("trailing data (%d bytes) after TBSCertificate", rLen) } - poisonAt := -1 - for i, ext := range tbs.Extensions { - if ext.Id.Equal(OIDExtensionCTPoison) { - if poisonAt != -1 { - return nil, errors.New("multiple CT poison extensions present") - } - poisonAt = i - } - } - if poisonAt == -1 { - return nil, errors.New("no CT poison extension present") - } - tbs.Extensions = append(tbs.Extensions[:poisonAt], tbs.Extensions[poisonAt+1:]...) - tbs.Raw = nil if preIssuer != nil { // Update the precert's Issuer field. Use the RawIssuer rather than the @@ -1092,9 +1200,13 @@ func BuildPrecertTBS(tbsData []byte, preIssuer *Certificate) ([]byte, error) { } tbs.Extensions = append(tbs.Extensions, authKeyIDExt) } + + // Clear out the asn1.RawContent so the re-marshal operation sees the + // updated structure (rather than just copying the out-of-date DER data). + tbs.Raw = nil } - data, err := asn1.Marshal(tbs) + data, err = asn1.Marshal(tbs) if err != nil { return nil, fmt.Errorf("failed to re-marshal TBSCertificate: %v", err) } @@ -1120,7 +1232,7 @@ const ( ) // RFC 5280, 4.2.2.1 -type authorityInfoAccess struct { +type accessDescription struct { Method asn1.ObjectIdentifier Location asn1.RawValue } @@ -1137,14 +1249,14 @@ type distributionPointName struct { RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` } -func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) { +func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo, nfe *NonFatalErrors) (interface{}, error) { asn1Data := keyData.PublicKey.RightAlign() switch algo { case RSA: // RSA public keys must have a NULL in the parameters // (https://tools.ietf.org/html/rfc3279#section-2.3.1). if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) { - return nil, errors.New("x509: RSA key missing NULL parameters") + nfe.AddError(errors.New("x509: RSA key missing NULL parameters")) } p := new(pkcs1PublicKey) @@ -1208,9 +1320,9 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{ if len(rest) != 0 { return nil, errors.New("x509: trailing data after ECDSA parameters") } - namedCurve := namedCurveFromOID(*namedCurveOID) + namedCurve := namedCurveFromOID(*namedCurveOID, nfe) if namedCurve == nil { - return nil, errors.New("x509: unsupported elliptic curve") + return nil, fmt.Errorf("x509: unsupported elliptic curve %v", namedCurveOID) } x, y := elliptic.Unmarshal(namedCurve, asn1Data) if x == nil { @@ -1235,7 +1347,7 @@ type NonFatalErrors struct { Errors []error } -// Adds an error to the list of errors contained by NonFatalErrors. +// AddError adds an error to the list of errors contained by NonFatalErrors. func (e *NonFatalErrors) AddError(err error) { e.Errors = append(e.Errors, err) } @@ -1250,11 +1362,25 @@ func (e NonFatalErrors) Error() string { return r } -// Returns true if |e| contains at least one error +// HasError returns true if |e| contains at least one error func (e *NonFatalErrors) HasError() bool { return len(e.Errors) > 0 } +// IsFatal indicates whether an error is fatal. +func IsFatal(err error) bool { + if err == nil { + return false + } + if _, ok := err.(NonFatalErrors); ok { + return false + } + if errs, ok := err.(*Errors); ok { + return errs.Fatal() + } + return true +} + func parseDistributionPoints(data []byte, crldp *[]string) error { // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint // @@ -1337,17 +1463,9 @@ func parseSANExtension(value []byte, nfe *NonFatalErrors) (dnsNames, emailAddres err = forEachSAN(value, func(tag int, data []byte) error { switch tag { case nameTypeEmail: - mailbox := string(data) - if _, ok := parseRFC2821Mailbox(mailbox); !ok { - return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox) - } - emailAddresses = append(emailAddresses, mailbox) + emailAddresses = append(emailAddresses, string(data)) case nameTypeDNS: - domain := string(data) - if _, ok := domainToReverseLabels(domain); !ok { - return fmt.Errorf("x509: cannot parse dnsName %q", string(data)) - } - dnsNames = append(dnsNames, domain) + dnsNames = append(dnsNames, string(data)) case nameTypeURI: uri, err := url.Parse(string(data)) if err != nil { @@ -1364,7 +1482,7 @@ func parseSANExtension(value []byte, nfe *NonFatalErrors) (dnsNames, emailAddres case net.IPv4len, net.IPv6len: ipAddresses = append(ipAddresses, data) default: - nfe.AddError(fmt.Errorf("x509: certificate contained IP address of length %d : %v", len(data), data)) + nfe.AddError(errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))) } } @@ -1399,7 +1517,7 @@ func isValidIPMask(mask []byte) bool { return true } -func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) { +func parseNameConstraintsExtension(out *Certificate, e pkix.Extension, nfe *NonFatalErrors) (unhandled bool, err error) { // RFC 5280, 4.2.1.10 // NameConstraints ::= SEQUENCE { @@ -1466,7 +1584,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle trimmedDomain = trimmedDomain[1:] } if _, ok := domainToReverseLabels(trimmedDomain); !ok { - return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain) + nfe.AddError(fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)) } dnsNames = append(dnsNames, domain) @@ -1503,7 +1621,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle // it specifies an exact mailbox name. if strings.Contains(constraint, "@") { if _, ok := parseRFC2821Mailbox(constraint); !ok { - return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint) + nfe.AddError(fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)) } } else { // Otherwise it's a domain name. @@ -1512,7 +1630,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle domain = domain[1:] } if _, ok := domainToReverseLabels(domain); !ok { - return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint) + nfe.AddError(fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)) } } emails = append(emails, constraint) @@ -1536,7 +1654,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle trimmedDomain = trimmedDomain[1:] } if _, ok := domainToReverseLabels(trimmedDomain); !ok { - return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain) + nfe.AddError(fmt.Errorf("x509: failed to parse URI constraint %q", domain)) } uriDomains = append(uriDomains, domain) @@ -1575,7 +1693,7 @@ func parseCertificate(in *certificate) (*Certificate, error) { out.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm) var err error - out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey) + out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey, &nfe) if err != nil { return nil, err } @@ -1651,7 +1769,7 @@ func parseCertificate(in *certificate) (*Certificate, error) { } case OIDExtensionNameConstraints[3]: - unhandled, err = parseNameConstraintsExtension(out, e) + unhandled, err = parseNameConstraintsExtension(out, e, &nfe) if err != nil { return nil, err } @@ -1682,10 +1800,14 @@ func parseCertificate(in *certificate) (*Certificate, error) { // KeyPurposeId ::= OBJECT IDENTIFIER var keyUsage []asn1.ObjectIdentifier - if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil { - return nil, err - } else if len(rest) != 0 { - return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage") + if len(e.Value) == 0 { + nfe.AddError(errors.New("x509: empty ExtendedKeyUsage")) + } else { + if rest, err := asn1.Unmarshal(e.Value, &keyUsage); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage") + } } for _, u := range keyUsage { @@ -1725,12 +1847,15 @@ func parseCertificate(in *certificate) (*Certificate, error) { } } else if e.Id.Equal(OIDExtensionAuthorityInfoAccess) { // RFC 5280 4.2.2.1: Authority Information Access - var aia []authorityInfoAccess + var aia []accessDescription if rest, err := asn1.Unmarshal(e.Value, &aia); err != nil { return nil, err } else if len(rest) != 0 { return nil, errors.New("x509: trailing data after X.509 authority information") } + if len(aia) == 0 { + nfe.AddError(errors.New("x509: empty AuthorityInfoAccess extension")) + } for _, v := range aia { // GeneralName: uniformResourceIdentifier [6] IA5String @@ -1743,6 +1868,34 @@ func parseCertificate(in *certificate) (*Certificate, error) { out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes)) } } + } else if e.Id.Equal(OIDExtensionSubjectInfoAccess) { + // RFC 5280 4.2.2.2: Subject Information Access + var sia []accessDescription + if rest, err := asn1.Unmarshal(e.Value, &sia); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after X.509 subject information") + } + if len(sia) == 0 { + nfe.AddError(errors.New("x509: empty SubjectInfoAccess extension")) + } + + for _, v := range sia { + // TODO(drysdale): cope with non-URI types of GeneralName + // GeneralName: uniformResourceIdentifier [6] IA5String + if v.Location.Tag != 6 { + continue + } + if v.Method.Equal(OIDSubjectInfoAccessTimestamp) { + out.SubjectTimestamps = append(out.SubjectTimestamps, string(v.Location.Bytes)) + } else if v.Method.Equal(OIDSubjectInfoAccessCARepo) { + out.SubjectCARepositories = append(out.SubjectCARepositories, string(v.Location.Bytes)) + } + } + } else if e.Id.Equal(OIDExtensionIPPrefixList) { + out.RPKIAddressRanges = parseRPKIAddrBlocks(e.Value, &nfe) + } else if e.Id.Equal(OIDExtensionASList) { + out.RPKIASNumbers, out.RPKIRoutingDomainIDs = parseRPKIASIdentifiers(e.Value, &nfe) } else if e.Id.Equal(OIDExtensionCTSCT) { if rest, err := asn1.Unmarshal(e.Value, &out.RawSCT); err != nil { nfe.AddError(fmt.Errorf("failed to asn1.Unmarshal SCT list extension: %v", err)) @@ -1787,6 +1940,8 @@ func ParseTBSCertificate(asn1Data []byte) (*Certificate, error) { } // ParseCertificate parses a single certificate from the given ASN.1 DER data. +// This function can return both a Certificate and an error (in which case the +// error will be of type NonFatalErrors). func ParseCertificate(asn1Data []byte) (*Certificate, error) { var cert certificate rest, err := asn1.Unmarshal(asn1Data, &cert) @@ -1802,6 +1957,8 @@ func ParseCertificate(asn1Data []byte) (*Certificate, error) { // ParseCertificates parses one or more certificates from the given ASN.1 DER // data. The certificates must be concatenated with no intermediate padding. +// This function can return both a slice of Certificate and an error (in which +// case the error will be of type NonFatalErrors). func ParseCertificates(asn1Data []byte) ([]*Certificate, error) { var v []*certificate @@ -1815,15 +1972,23 @@ func ParseCertificates(asn1Data []byte) ([]*Certificate, error) { v = append(v, cert) } + var nfe NonFatalErrors ret := make([]*Certificate, len(v)) for i, ci := range v { cert, err := parseCertificate(ci) if err != nil { - return nil, err + if errs, ok := err.(NonFatalErrors); !ok { + return nil, err + } else { + nfe.Errors = append(nfe.Errors, errs.Errors...) + } } ret[i] = cert } + if nfe.HasError() { + return ret, nfe + } return ret, nil } @@ -1875,15 +2040,23 @@ var ( OIDExtensionAuthorityInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1} OIDExtensionSubjectInfoAccess = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11} + // OIDExtensionCTPoison is defined in RFC 6962 s3.1. OIDExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // OIDExtensionCTSCT is defined in RFC 6962 s3.3. OIDExtensionCTSCT = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} + // OIDExtensionIPPrefixList is defined in RFC 3779 s2. + OIDExtensionIPPrefixList = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 7} + // OIDExtensionASList is defined in RFC 3779 s3. + OIDExtensionASList = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 8} ) var ( OIDAuthorityInfoAccessOCSP = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1} OIDAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2} + OIDSubjectInfoAccessTimestamp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 3} + OIDSubjectInfoAccessCARepo = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 5} + OIDAnyPolicy = asn1.ObjectIdentifier{2, 5, 29, 32, 0} ) // oidInExtensions returns whether an extension with the given oid exists in @@ -1932,7 +2105,7 @@ func isIA5String(s string) error { } func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte) (ret []pkix.Extension, err error) { - ret = make([]pkix.Extension, 11 /* maximum number of elements. */) + ret = make([]pkix.Extension, 12 /* maximum number of elements. */) n := 0 if template.KeyUsage != 0 && @@ -2017,15 +2190,15 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) && !oidInExtensions(OIDExtensionAuthorityInfoAccess, template.ExtraExtensions) { ret[n].Id = OIDExtensionAuthorityInfoAccess - var aiaValues []authorityInfoAccess + var aiaValues []accessDescription for _, name := range template.OCSPServer { - aiaValues = append(aiaValues, authorityInfoAccess{ + aiaValues = append(aiaValues, accessDescription{ Method: OIDAuthorityInfoAccessOCSP, Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(name)}, }) } for _, name := range template.IssuingCertificateURL { - aiaValues = append(aiaValues, authorityInfoAccess{ + aiaValues = append(aiaValues, accessDescription{ Method: OIDAuthorityInfoAccessIssuers, Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(name)}, }) @@ -2037,6 +2210,29 @@ func buildExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId n++ } + if len(template.SubjectTimestamps) > 0 || len(template.SubjectCARepositories) > 0 && + !oidInExtensions(OIDExtensionSubjectInfoAccess, template.ExtraExtensions) { + ret[n].Id = OIDExtensionSubjectInfoAccess + var siaValues []accessDescription + for _, ts := range template.SubjectTimestamps { + siaValues = append(siaValues, accessDescription{ + Method: OIDSubjectInfoAccessTimestamp, + Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(ts)}, + }) + } + for _, repo := range template.SubjectCARepositories { + siaValues = append(siaValues, accessDescription{ + Method: OIDSubjectInfoAccessCARepo, + Location: asn1.RawValue{Tag: 6, Class: asn1.ClassContextSpecific, Bytes: []byte(repo)}, + }) + } + ret[n].Value, err = asn1.Marshal(siaValues) + if err != nil { + return + } + n++ + } + if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) && !oidInExtensions(OIDExtensionSubjectAltName, template.ExtraExtensions) { ret[n].Id = OIDExtensionSubjectAltName @@ -2290,12 +2486,25 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori var emptyASN1Subject = []byte{0x30, 0} // CreateCertificate creates a new X.509v3 certificate based on a template. -// The following members of template are used: AuthorityKeyId, -// BasicConstraintsValid, DNSNames, ExcludedDNSDomains, ExtKeyUsage, -// IsCA, KeyUsage, MaxPathLen, MaxPathLenZero, NotAfter, NotBefore, -// PermittedDNSDomains, PermittedDNSDomainsCritical, SerialNumber, -// SignatureAlgorithm, Subject, SubjectKeyId, UnknownExtKeyUsage, -// and RawSCT. +// The following members of template are used: +// - SerialNumber +// - Subject +// - NotBefore, NotAfter +// - SignatureAlgorithm +// - For extensions: +// - KeyUsage +// - ExtKeyUsage +// - BasicConstraintsValid, IsCA, MaxPathLen, MaxPathLenZero +// - SubjectKeyId +// - AuthorityKeyId +// - OCSPServer, IssuingCertificateURL +// - SubjectTimestamps, SubjectCARepositories +// - DNSNames, EmailAddresses, IPAddresses, URIs +// - PolicyIdentifiers +// - ExcludedDNSDomains, ExcludedIPRanges, ExcludedEmailAddresses, ExcludedURIDomains, PermittedDNSDomainsCritical, +// PermittedDNSDomains, PermittedIPRanges, PermittedEmailAddresses, PermittedURIDomains +// - CRLDistributionPoints +// - RawSCT, SCTList // // The certificate is signed by parent. If parent is equal to template then the // certificate is self-signed. The parameter pub is the public key of the @@ -2804,10 +3013,15 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error } var err error - out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey) + var nfe NonFatalErrors + out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey, &nfe) if err != nil { return nil, err } + // Treat non-fatal errors as fatal here. + if len(nfe.Errors) > 0 { + return nil, nfe.Errors[0] + } var subject pkix.RDNSequence if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil { @@ -2822,7 +3036,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error return nil, err } - var nfe NonFatalErrors for _, extension := range out.Extensions { if extension.Id.Equal(OIDExtensionSubjectAltName) { out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value, &nfe) diff --git a/vendor/github.com/jmoiron/sqlx/LICENSE b/vendor/github.com/jmoiron/sqlx/LICENSE new file mode 100644 index 0000000000..0d31edfa73 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/LICENSE @@ -0,0 +1,23 @@ + Copyright (c) 2013, Jason Moiron + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/jmoiron/sqlx/types/README.md b/vendor/github.com/jmoiron/sqlx/types/README.md new file mode 100644 index 0000000000..713abe50d1 --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/types/README.md @@ -0,0 +1,5 @@ +# types + +The types package provides some useful types which implement the `sql.Scanner` +and `driver.Valuer` interfaces, suitable for use as scan and value targets with +database/sql. diff --git a/vendor/github.com/jmoiron/sqlx/types/types.go b/vendor/github.com/jmoiron/sqlx/types/types.go new file mode 100644 index 0000000000..7b014c1e1f --- /dev/null +++ b/vendor/github.com/jmoiron/sqlx/types/types.go @@ -0,0 +1,172 @@ +package types + +import ( + "bytes" + "compress/gzip" + "database/sql/driver" + "encoding/json" + "errors" + + "io/ioutil" +) + +// GzippedText is a []byte which transparently gzips data being submitted to +// a database and ungzips data being Scanned from a database. +type GzippedText []byte + +// Value implements the driver.Valuer interface, gzipping the raw value of +// this GzippedText. +func (g GzippedText) Value() (driver.Value, error) { + b := make([]byte, 0, len(g)) + buf := bytes.NewBuffer(b) + w := gzip.NewWriter(buf) + w.Write(g) + w.Close() + return buf.Bytes(), nil + +} + +// Scan implements the sql.Scanner interface, ungzipping the value coming off +// the wire and storing the raw result in the GzippedText. +func (g *GzippedText) Scan(src interface{}) error { + var source []byte + switch src.(type) { + case string: + source = []byte(src.(string)) + case []byte: + source = src.([]byte) + default: + return errors.New("Incompatible type for GzippedText") + } + reader, err := gzip.NewReader(bytes.NewReader(source)) + if err != nil { + return err + } + defer reader.Close() + b, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + *g = GzippedText(b) + return nil +} + +// JSONText is a json.RawMessage, which is a []byte underneath. +// Value() validates the json format in the source, and returns an error if +// the json is not valid. Scan does no validation. JSONText additionally +// implements `Unmarshal`, which unmarshals the json within to an interface{} +type JSONText json.RawMessage + +var emptyJSON = JSONText("{}") + +// MarshalJSON returns the *j as the JSON encoding of j. +func (j JSONText) MarshalJSON() ([]byte, error) { + if len(j) == 0 { + return emptyJSON, nil + } + return j, nil +} + +// UnmarshalJSON sets *j to a copy of data +func (j *JSONText) UnmarshalJSON(data []byte) error { + if j == nil { + return errors.New("JSONText: UnmarshalJSON on nil pointer") + } + *j = append((*j)[0:0], data...) + return nil +} + +// Value returns j as a value. This does a validating unmarshal into another +// RawMessage. If j is invalid json, it returns an error. +func (j JSONText) Value() (driver.Value, error) { + var m json.RawMessage + var err = j.Unmarshal(&m) + if err != nil { + return []byte{}, err + } + return []byte(j), nil +} + +// Scan stores the src in *j. No validation is done. +func (j *JSONText) Scan(src interface{}) error { + var source []byte + switch t := src.(type) { + case string: + source = []byte(t) + case []byte: + if len(t) == 0 { + source = emptyJSON + } else { + source = t + } + case nil: + *j = emptyJSON + default: + return errors.New("Incompatible type for JSONText") + } + *j = JSONText(append((*j)[0:0], source...)) + return nil +} + +// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal. +func (j *JSONText) Unmarshal(v interface{}) error { + if len(*j) == 0 { + *j = emptyJSON + } + return json.Unmarshal([]byte(*j), v) +} + +// String supports pretty printing for JSONText types. +func (j JSONText) String() string { + return string(j) +} + +// NullJSONText represents a JSONText that may be null. +// NullJSONText implements the scanner interface so +// it can be used as a scan destination, similar to NullString. +type NullJSONText struct { + JSONText + Valid bool // Valid is true if JSONText is not NULL +} + +// Scan implements the Scanner interface. +func (n *NullJSONText) Scan(value interface{}) error { + if value == nil { + n.JSONText, n.Valid = emptyJSON, false + return nil + } + n.Valid = true + return n.JSONText.Scan(value) +} + +// Value implements the driver Valuer interface. +func (n NullJSONText) Value() (driver.Value, error) { + if !n.Valid { + return nil, nil + } + return n.JSONText.Value() +} + +// BitBool is an implementation of a bool for the MySQL type BIT(1). +// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT. +type BitBool bool + +// Value implements the driver.Valuer interface, +// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage. +func (b BitBool) Value() (driver.Value, error) { + if b { + return []byte{1}, nil + } + return []byte{0}, nil +} + +// Scan implements the sql.Scanner interface, +// and turns the bitfield incoming from MySQL into a BitBool +func (b *BitBool) Scan(src interface{}) error { + v, ok := src.([]byte) + if !ok { + return errors.New("bad []byte type assertion") + } + *b = v[0] == 1 + return nil +} diff --git a/vendor/github.com/weppos/publicsuffix-go/LICENSE.txt b/vendor/github.com/weppos/publicsuffix-go/LICENSE.txt new file mode 100644 index 0000000000..079a934f9d --- /dev/null +++ b/vendor/github.com/weppos/publicsuffix-go/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-2020 Simone Carletti + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go b/vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go new file mode 100644 index 0000000000..c10e94270d --- /dev/null +++ b/vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go @@ -0,0 +1,544 @@ +//go:generate go run ../cmd/gen/gen.go + +// Package publicsuffix provides a domain name parser +// based on data from the public suffix list http://publicsuffix.org/. +// A public suffix is one under which Internet users can directly register names. +package publicsuffix + +import ( + "bufio" + "fmt" + "io" + "net/http/cookiejar" + "os" + "strings" + + "golang.org/x/net/idna" +) + +const ( + // Version identifies the current library version. + // This is a pro forma convention given that Go dependencies + // tends to be fetched directly from the repo. + Version = "0.13.0" + + // NormalType represents a normal rule such as "com" + NormalType = 1 + // WildcardType represents a wildcard rule such as "*.com" + WildcardType = 2 + // ExceptionType represents an exception to a wildard rule + ExceptionType = 3 + + listTokenPrivateDomains = "===BEGIN PRIVATE DOMAINS===" + listTokenComment = "//" +) + +// DefaultList is the default List and it is used by Parse and Domain. +var DefaultList = NewList() + +// DefaultRule is the default Rule that represents "*". +var DefaultRule = MustNewRule("*") + +// DefaultParserOptions are the default options used to parse a Public Suffix list. +var DefaultParserOptions = &ParserOption{PrivateDomains: true, ASCIIEncoded: false} + +// DefaultFindOptions are the default options used to perform the lookup of rules in the list. +var DefaultFindOptions = &FindOptions{IgnorePrivate: false, DefaultRule: DefaultRule} + +// Rule represents a single rule in a Public Suffix List. +type Rule struct { + Type int + Value string + Length int + Private bool +} + +// ParserOption are the options you can use to customize the way a List +// is parsed from a file or a string. +type ParserOption struct { + // Set to false to skip the private domains when parsing. + // Default to true, which means the private domains are included. + PrivateDomains bool + + // Set to false if the input is encoded in U-labels (Unicode) + // as opposite to A-labels. + // Default to false, which means the list is containing Unicode domains. + // This is the default because the original PSL currently contains Unicode. + ASCIIEncoded bool +} + +// FindOptions are the options you can use to customize the way a Rule +// is searched within the list. +type FindOptions struct { + // Set to true to ignore the rules within the "Private" section of the Public Suffix List. + IgnorePrivate bool + + // The default rule to use when no rule matches the input. + // The format Public Suffix algorithm states that the rule "*" should be used when no other rule matches, + // but some consumers may have different needs. + DefaultRule *Rule +} + +// List represents a Public Suffix List. +type List struct { + // rules is kept private because you should not access rules directly + rules map[string]*Rule +} + +// NewList creates a new empty list. +func NewList() *List { + return &List{ + rules: map[string]*Rule{}, + } +} + +// NewListFromString parses a string that represents a Public Suffix source +// and returns a List initialized with the rules in the source. +func NewListFromString(src string, options *ParserOption) (*List, error) { + l := NewList() + _, err := l.LoadString(src, options) + return l, err +} + +// NewListFromFile parses a string that represents a Public Suffix source +// and returns a List initialized with the rules in the source. +func NewListFromFile(path string, options *ParserOption) (*List, error) { + l := NewList() + _, err := l.LoadFile(path, options) + return l, err +} + +// Load parses and loads a set of rules from an io.Reader into the current list. +func (l *List) Load(r io.Reader, options *ParserOption) ([]Rule, error) { + return l.parse(r, options) +} + +// LoadString parses and loads a set of rules from a String into the current list. +func (l *List) LoadString(src string, options *ParserOption) ([]Rule, error) { + r := strings.NewReader(src) + return l.parse(r, options) +} + +// LoadFile parses and loads a set of rules from a File into the current list. +func (l *List) LoadFile(path string, options *ParserOption) ([]Rule, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + return l.parse(f, options) +} + +// AddRule adds a new rule to the list. +// +// The exact position of the rule into the list is unpredictable. +// The list may be optimized internally for lookups, therefore the algorithm +// will decide the best position for the new rule. +func (l *List) AddRule(r *Rule) error { + l.rules[r.Value] = r + return nil +} + +// Size returns the size of the list, which is the number of rules. +func (l *List) Size() int { + return len(l.rules) +} + +func (l *List) parse(r io.Reader, options *ParserOption) ([]Rule, error) { + if options == nil { + options = DefaultParserOptions + } + var rules []Rule + + scanner := bufio.NewScanner(r) + var section int // 1 == ICANN, 2 == PRIVATE + +Scanning: + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + switch { + + // skip blank lines + case line == "": + break + + // include private domains or stop scanner + case strings.Contains(line, listTokenPrivateDomains): + if !options.PrivateDomains { + break Scanning + } + section = 2 + + // skip comments + case strings.HasPrefix(line, listTokenComment): + break + + default: + var rule *Rule + var err error + + if options.ASCIIEncoded { + rule, err = NewRule(line) + } else { + rule, err = NewRuleUnicode(line) + } + if err != nil { + return []Rule{}, err + } + + rule.Private = (section == 2) + l.AddRule(rule) + rules = append(rules, *rule) + } + + } + + return rules, scanner.Err() +} + +// Find and returns the most appropriate rule for the domain name. +func (l *List) Find(name string, options *FindOptions) *Rule { + if options == nil { + options = DefaultFindOptions + } + + part := name + for { + rule, ok := l.rules[part] + + if ok && rule.Match(name) && !(options.IgnorePrivate && rule.Private) { + return rule + } + + i := strings.IndexRune(part, '.') + if i < 0 { + return options.DefaultRule + } + + part = part[i+1:] + } + +} + +// NewRule parses the rule content, creates and returns a Rule. +// +// The content of the rule MUST be encoded in ASCII (A-labels). +func NewRule(content string) (*Rule, error) { + var rule *Rule + var value string + + switch content[0:1] { + case "*": // wildcard + if content == "*" { + value = "" + } else { + value = content[2:] + } + rule = &Rule{Type: WildcardType, Value: value, Length: len(Labels(value)) + 1} + case "!": // exception + value = content[1:] + rule = &Rule{Type: ExceptionType, Value: value, Length: len(Labels(value))} + default: // normal + value = content + rule = &Rule{Type: NormalType, Value: value, Length: len(Labels(value))} + } + + return rule, nil +} + +// NewRuleUnicode is like NewRule, but expects the content to be encoded in Unicode (U-labels). +func NewRuleUnicode(content string) (*Rule, error) { + var err error + + content, err = ToASCII(content) + if err != nil { + return nil, err + } + + return NewRule(content) +} + +// MustNewRule is like NewRule, but panics if the content cannot be parsed. +func MustNewRule(content string) *Rule { + rule, err := NewRule(content) + if err != nil { + panic(err) + } + return rule +} + +// Match checks if the rule matches the name. +// +// A domain name is said to match a rule if and only if all of the following conditions are met: +// - When the domain and rule are split into corresponding labels, +// that the domain contains as many or more labels than the rule. +// - Beginning with the right-most labels of both the domain and the rule, +// and continuing for all labels in the rule, one finds that for every pair, +// either they are identical, or that the label from the rule is "*". +// +// See https://publicsuffix.org/list/ +func (r *Rule) Match(name string) bool { + left := strings.TrimSuffix(name, r.Value) + + // the name contains as many labels than the rule + // this is a match, unless it's a wildcard + // because the wildcard requires one more label + if left == "" { + return r.Type != WildcardType + } + + // if there is one more label, the rule match + // because either the rule is shorter than the domain + // or the rule is a wildcard and there is one more label + return left[len(left)-1:] == "." +} + +// Decompose takes a name as input and decomposes it into a tuple of , +// according to the rule definition and type. +func (r *Rule) Decompose(name string) (result [2]string) { + if r == DefaultRule { + i := strings.LastIndex(name, ".") + if i < 0 { + return + } + result[0], result[1] = name[:i], name[i+1:] + return + } + switch r.Type { + case NormalType: + name = strings.TrimSuffix(name, r.Value) + if len(name) == 0 { + return + } + result[0], result[1] = name[:len(name)-1], r.Value + case WildcardType: + name := strings.TrimSuffix(name, r.Value) + if len(name) == 0 { + return + } + name = name[:len(name)-1] + i := strings.LastIndex(name, ".") + if i < 0 { + return + } + result[0], result[1] = name[:i], name[i+1:]+"."+r.Value + case ExceptionType: + i := strings.IndexRune(r.Value, '.') + if i < 0 { + return + } + suffix := r.Value[i+1:] + name = strings.TrimSuffix(name, suffix) + if len(name) == 0 { + return + } + result[0], result[1] = name[:len(name)-1], suffix + } + return +} + +// Labels decomposes given domain name into labels, +// corresponding to the dot-separated tokens. +func Labels(name string) []string { + return strings.Split(name, ".") +} + +// DomainName represents a domain name. +type DomainName struct { + TLD string + SLD string + TRD string + Rule *Rule +} + +// String joins the components of the domain name into a single string. +// Empty labels are skipped. +// +// Examples: +// +// DomainName{"com", "example"}.String() +// // example.com +// DomainName{"com", "example", "www"}.String() +// // www.example.com +// +func (d *DomainName) String() string { + switch { + case d.TLD == "": + return "" + case d.SLD == "": + return d.TLD + case d.TRD == "": + return d.SLD + "." + d.TLD + default: + return d.TRD + "." + d.SLD + "." + d.TLD + } +} + +// Domain extract and return the domain name from the input +// using the default (Public Suffix) List. +// +// Examples: +// +// publicsuffix.Domain("example.com") +// // example.com +// publicsuffix.Domain("www.example.com") +// // example.com +// publicsuffix.Domain("www.example.co.uk") +// // example.co.uk +// +func Domain(name string) (string, error) { + return DomainFromListWithOptions(DefaultList, name, DefaultFindOptions) +} + +// Parse decomposes the name into TLD, SLD, TRD +// using the default (Public Suffix) List, +// and returns the result as a DomainName +// +// Examples: +// +// list := NewList() +// +// publicsuffix.Parse("example.com") +// // &DomainName{"com", "example"} +// publicsuffix.Parse("www.example.com") +// // &DomainName{"com", "example", "www"} +// publicsuffix.Parse("www.example.co.uk") +// // &DomainName{"co.uk", "example"} +// +func Parse(name string) (*DomainName, error) { + return ParseFromListWithOptions(DefaultList, name, DefaultFindOptions) +} + +// DomainFromListWithOptions extract and return the domain name from the input +// using the (Public Suffix) list passed as argument. +// +// Examples: +// +// list := NewList() +// +// publicsuffix.DomainFromListWithOptions(list, "example.com") +// // example.com +// publicsuffix.DomainFromListWithOptions(list, "www.example.com") +// // example.com +// publicsuffix.DomainFromListWithOptions(list, "www.example.co.uk") +// // example.co.uk +// +func DomainFromListWithOptions(l *List, name string, options *FindOptions) (string, error) { + dn, err := ParseFromListWithOptions(l, name, options) + if err != nil { + return "", err + } + return dn.SLD + "." + dn.TLD, nil +} + +// ParseFromListWithOptions decomposes the name into TLD, SLD, TRD +// using the (Public Suffix) list passed as argument, +// and returns the result as a DomainName +// +// Examples: +// +// list := NewList() +// +// publicsuffix.ParseFromListWithOptions(list, "example.com") +// // &DomainName{"com", "example"} +// publicsuffix.ParseFromListWithOptions(list, "www.example.com") +// // &DomainName{"com", "example", "www"} +// publicsuffix.ParseFromListWithOptions(list, "www.example.co.uk") +// // &DomainName{"co.uk", "example"} +// +func ParseFromListWithOptions(l *List, name string, options *FindOptions) (*DomainName, error) { + n, err := normalize(name) + if err != nil { + return nil, err + } + + r := l.Find(n, options) + if r == nil { + return nil, fmt.Errorf("no rule matching name %s", name) + } + + parts := r.Decompose(n) + left, tld := parts[0], parts[1] + if tld == "" { + return nil, fmt.Errorf("%s is a suffix", n) + } + + dn := &DomainName{ + Rule: r, + TLD: tld, + } + if i := strings.LastIndex(left, "."); i < 0 { + dn.SLD = left + } else { + dn.TRD = left[:i] + dn.SLD = left[i+1:] + } + return dn, nil +} + +func normalize(name string) (string, error) { + ret := strings.ToLower(name) + + if ret == "" { + return "", fmt.Errorf("name is blank") + } + if ret[0] == '.' { + return "", fmt.Errorf("name %s starts with a dot", ret) + } + + return ret, nil +} + +// ToASCII is a wrapper for idna.ToASCII. +// +// This wrapper exists because idna.ToASCII backward-compatibility was broken twice in few months +// and I can't call this package directly anymore. The wrapper performs some terrible-but-necessary +// before-after replacements to make sure an already ASCII input always results in the same output +// even if passed through ToASCII. +// +// See golang/net@67957fd0b1, golang/net@f2499483f9, golang/net@78ebe5c8b6, +// and weppos/publicsuffix-go#66. +func ToASCII(s string) (string, error) { + // .example.com should be .example.com + // ..example.com should be ..example.com + if strings.HasPrefix(s, ".") { + dotIndex := 0 + for i := 0; i < len(s); i++ { + if s[i] == '.' { + dotIndex = i + } else { + break + } + } + out, err := idna.ToASCII(s[dotIndex+1:]) + out = s[:dotIndex+1] + out + return out, err + } + + return idna.ToASCII(s) +} + +// ToUnicode is a wrapper for idna.ToUnicode. +// +// See ToASCII for more details about why this wrapper exists. +func ToUnicode(s string) (string, error) { + return idna.ToUnicode(s) +} + +// CookieJarList implements the cookiejar.PublicSuffixList interface. +var CookieJarList cookiejar.PublicSuffixList = cookiejarList{DefaultList} + +type cookiejarList struct { + List *List +} + +// PublicSuffix implements cookiejar.PublicSuffixList. +func (l cookiejarList) PublicSuffix(domain string) string { + rule := l.List.Find(domain, nil) + return rule.Decompose(domain)[1] +} + +// PublicSuffix implements cookiejar.String. +func (cookiejarList) String() string { + return defaultListVersion +} diff --git a/vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go b/vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go new file mode 100644 index 0000000000..bb20a8bab1 --- /dev/null +++ b/vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go @@ -0,0 +1,8847 @@ +// This file is automatically generated +// Run "go run cmd/gen/gen.go" to update the list. + +package publicsuffix + +const defaultListVersion = "PSL version e7e340 (Sat Feb 15 21:59:27 2020)" + +func DefaultRules() [8828]Rule { + return r +} + +var r = [8828]Rule{ + {1, "ac", 1, false}, + {1, "com.ac", 2, false}, + {1, "edu.ac", 2, false}, + {1, "gov.ac", 2, false}, + {1, "net.ac", 2, false}, + {1, "mil.ac", 2, false}, + {1, "org.ac", 2, false}, + {1, "ad", 1, false}, + {1, "nom.ad", 2, false}, + {1, "ae", 1, false}, + {1, "co.ae", 2, false}, + {1, "net.ae", 2, false}, + {1, "org.ae", 2, false}, + {1, "sch.ae", 2, false}, + {1, "ac.ae", 2, false}, + {1, "gov.ae", 2, false}, + {1, "mil.ae", 2, false}, + {1, "aero", 1, false}, + {1, "accident-investigation.aero", 2, false}, + {1, "accident-prevention.aero", 2, false}, + {1, "aerobatic.aero", 2, false}, + {1, "aeroclub.aero", 2, false}, + {1, "aerodrome.aero", 2, false}, + {1, "agents.aero", 2, false}, + {1, "aircraft.aero", 2, false}, + {1, "airline.aero", 2, false}, + {1, "airport.aero", 2, false}, + {1, "air-surveillance.aero", 2, false}, + {1, "airtraffic.aero", 2, false}, + {1, "air-traffic-control.aero", 2, false}, + {1, "ambulance.aero", 2, false}, + {1, "amusement.aero", 2, false}, + {1, "association.aero", 2, false}, + {1, "author.aero", 2, false}, + {1, "ballooning.aero", 2, false}, + {1, "broker.aero", 2, false}, + {1, "caa.aero", 2, false}, + {1, "cargo.aero", 2, false}, + {1, "catering.aero", 2, false}, + {1, "certification.aero", 2, false}, + {1, "championship.aero", 2, false}, + {1, "charter.aero", 2, false}, + {1, "civilaviation.aero", 2, false}, + {1, "club.aero", 2, false}, + {1, "conference.aero", 2, false}, + {1, "consultant.aero", 2, false}, + {1, "consulting.aero", 2, false}, + {1, "control.aero", 2, false}, + {1, "council.aero", 2, false}, + {1, "crew.aero", 2, false}, + {1, "design.aero", 2, false}, + {1, "dgca.aero", 2, false}, + {1, "educator.aero", 2, false}, + {1, "emergency.aero", 2, false}, + {1, "engine.aero", 2, false}, + {1, "engineer.aero", 2, false}, + {1, "entertainment.aero", 2, false}, + {1, "equipment.aero", 2, false}, + {1, "exchange.aero", 2, false}, + {1, "express.aero", 2, false}, + {1, "federation.aero", 2, false}, + {1, "flight.aero", 2, false}, + {1, "freight.aero", 2, false}, + {1, "fuel.aero", 2, false}, + {1, "gliding.aero", 2, false}, + {1, "government.aero", 2, false}, + {1, "groundhandling.aero", 2, false}, + {1, "group.aero", 2, false}, + {1, "hanggliding.aero", 2, false}, + {1, "homebuilt.aero", 2, false}, + {1, "insurance.aero", 2, false}, + {1, "journal.aero", 2, false}, + {1, "journalist.aero", 2, false}, + {1, "leasing.aero", 2, false}, + {1, "logistics.aero", 2, false}, + {1, "magazine.aero", 2, false}, + {1, "maintenance.aero", 2, false}, + {1, "media.aero", 2, false}, + {1, "microlight.aero", 2, false}, + {1, "modelling.aero", 2, false}, + {1, "navigation.aero", 2, false}, + {1, "parachuting.aero", 2, false}, + {1, "paragliding.aero", 2, false}, + {1, "passenger-association.aero", 2, false}, + {1, "pilot.aero", 2, false}, + {1, "press.aero", 2, false}, + {1, "production.aero", 2, false}, + {1, "recreation.aero", 2, false}, + {1, "repbody.aero", 2, false}, + {1, "res.aero", 2, false}, + {1, "research.aero", 2, false}, + {1, "rotorcraft.aero", 2, false}, + {1, "safety.aero", 2, false}, + {1, "scientist.aero", 2, false}, + {1, "services.aero", 2, false}, + {1, "show.aero", 2, false}, + {1, "skydiving.aero", 2, false}, + {1, "software.aero", 2, false}, + {1, "student.aero", 2, false}, + {1, "trader.aero", 2, false}, + {1, "trading.aero", 2, false}, + {1, "trainer.aero", 2, false}, + {1, "union.aero", 2, false}, + {1, "workinggroup.aero", 2, false}, + {1, "works.aero", 2, false}, + {1, "af", 1, false}, + {1, "gov.af", 2, false}, + {1, "com.af", 2, false}, + {1, "org.af", 2, false}, + {1, "net.af", 2, false}, + {1, "edu.af", 2, false}, + {1, "ag", 1, false}, + {1, "com.ag", 2, false}, + {1, "org.ag", 2, false}, + {1, "net.ag", 2, false}, + {1, "co.ag", 2, false}, + {1, "nom.ag", 2, false}, + {1, "ai", 1, false}, + {1, "off.ai", 2, false}, + {1, "com.ai", 2, false}, + {1, "net.ai", 2, false}, + {1, "org.ai", 2, false}, + {1, "al", 1, false}, + {1, "com.al", 2, false}, + {1, "edu.al", 2, false}, + {1, "gov.al", 2, false}, + {1, "mil.al", 2, false}, + {1, "net.al", 2, false}, + {1, "org.al", 2, false}, + {1, "am", 1, false}, + {1, "co.am", 2, false}, + {1, "com.am", 2, false}, + {1, "commune.am", 2, false}, + {1, "net.am", 2, false}, + {1, "org.am", 2, false}, + {1, "ao", 1, false}, + {1, "ed.ao", 2, false}, + {1, "gv.ao", 2, false}, + {1, "og.ao", 2, false}, + {1, "co.ao", 2, false}, + {1, "pb.ao", 2, false}, + {1, "it.ao", 2, false}, + {1, "aq", 1, false}, + {1, "ar", 1, false}, + {1, "com.ar", 2, false}, + {1, "edu.ar", 2, false}, + {1, "gob.ar", 2, false}, + {1, "gov.ar", 2, false}, + {1, "int.ar", 2, false}, + {1, "mil.ar", 2, false}, + {1, "musica.ar", 2, false}, + {1, "net.ar", 2, false}, + {1, "org.ar", 2, false}, + {1, "tur.ar", 2, false}, + {1, "arpa", 1, false}, + {1, "e164.arpa", 2, false}, + {1, "in-addr.arpa", 2, false}, + {1, "ip6.arpa", 2, false}, + {1, "iris.arpa", 2, false}, + {1, "uri.arpa", 2, false}, + {1, "urn.arpa", 2, false}, + {1, "as", 1, false}, + {1, "gov.as", 2, false}, + {1, "asia", 1, false}, + {1, "at", 1, false}, + {1, "ac.at", 2, false}, + {1, "co.at", 2, false}, + {1, "gv.at", 2, false}, + {1, "or.at", 2, false}, + {1, "au", 1, false}, + {1, "com.au", 2, false}, + {1, "net.au", 2, false}, + {1, "org.au", 2, false}, + {1, "edu.au", 2, false}, + {1, "gov.au", 2, false}, + {1, "asn.au", 2, false}, + {1, "id.au", 2, false}, + {1, "info.au", 2, false}, + {1, "conf.au", 2, false}, + {1, "oz.au", 2, false}, + {1, "act.au", 2, false}, + {1, "nsw.au", 2, false}, + {1, "nt.au", 2, false}, + {1, "qld.au", 2, false}, + {1, "sa.au", 2, false}, + {1, "tas.au", 2, false}, + {1, "vic.au", 2, false}, + {1, "wa.au", 2, false}, + {1, "act.edu.au", 3, false}, + {1, "catholic.edu.au", 3, false}, + {1, "nsw.edu.au", 3, false}, + {1, "nt.edu.au", 3, false}, + {1, "qld.edu.au", 3, false}, + {1, "sa.edu.au", 3, false}, + {1, "tas.edu.au", 3, false}, + {1, "vic.edu.au", 3, false}, + {1, "wa.edu.au", 3, false}, + {1, "qld.gov.au", 3, false}, + {1, "sa.gov.au", 3, false}, + {1, "tas.gov.au", 3, false}, + {1, "vic.gov.au", 3, false}, + {1, "wa.gov.au", 3, false}, + {1, "education.tas.edu.au", 4, false}, + {1, "schools.nsw.edu.au", 4, false}, + {1, "aw", 1, false}, + {1, "com.aw", 2, false}, + {1, "ax", 1, false}, + {1, "az", 1, false}, + {1, "com.az", 2, false}, + {1, "net.az", 2, false}, + {1, "int.az", 2, false}, + {1, "gov.az", 2, false}, + {1, "org.az", 2, false}, + {1, "edu.az", 2, false}, + {1, "info.az", 2, false}, + {1, "pp.az", 2, false}, + {1, "mil.az", 2, false}, + {1, "name.az", 2, false}, + {1, "pro.az", 2, false}, + {1, "biz.az", 2, false}, + {1, "ba", 1, false}, + {1, "com.ba", 2, false}, + {1, "edu.ba", 2, false}, + {1, "gov.ba", 2, false}, + {1, "mil.ba", 2, false}, + {1, "net.ba", 2, false}, + {1, "org.ba", 2, false}, + {1, "bb", 1, false}, + {1, "biz.bb", 2, false}, + {1, "co.bb", 2, false}, + {1, "com.bb", 2, false}, + {1, "edu.bb", 2, false}, + {1, "gov.bb", 2, false}, + {1, "info.bb", 2, false}, + {1, "net.bb", 2, false}, + {1, "org.bb", 2, false}, + {1, "store.bb", 2, false}, + {1, "tv.bb", 2, false}, + {2, "bd", 2, false}, + {1, "be", 1, false}, + {1, "ac.be", 2, false}, + {1, "bf", 1, false}, + {1, "gov.bf", 2, false}, + {1, "bg", 1, false}, + {1, "a.bg", 2, false}, + {1, "b.bg", 2, false}, + {1, "c.bg", 2, false}, + {1, "d.bg", 2, false}, + {1, "e.bg", 2, false}, + {1, "f.bg", 2, false}, + {1, "g.bg", 2, false}, + {1, "h.bg", 2, false}, + {1, "i.bg", 2, false}, + {1, "j.bg", 2, false}, + {1, "k.bg", 2, false}, + {1, "l.bg", 2, false}, + {1, "m.bg", 2, false}, + {1, "n.bg", 2, false}, + {1, "o.bg", 2, false}, + {1, "p.bg", 2, false}, + {1, "q.bg", 2, false}, + {1, "r.bg", 2, false}, + {1, "s.bg", 2, false}, + {1, "t.bg", 2, false}, + {1, "u.bg", 2, false}, + {1, "v.bg", 2, false}, + {1, "w.bg", 2, false}, + {1, "x.bg", 2, false}, + {1, "y.bg", 2, false}, + {1, "z.bg", 2, false}, + {1, "0.bg", 2, false}, + {1, "1.bg", 2, false}, + {1, "2.bg", 2, false}, + {1, "3.bg", 2, false}, + {1, "4.bg", 2, false}, + {1, "5.bg", 2, false}, + {1, "6.bg", 2, false}, + {1, "7.bg", 2, false}, + {1, "8.bg", 2, false}, + {1, "9.bg", 2, false}, + {1, "bh", 1, false}, + {1, "com.bh", 2, false}, + {1, "edu.bh", 2, false}, + {1, "net.bh", 2, false}, + {1, "org.bh", 2, false}, + {1, "gov.bh", 2, false}, + {1, "bi", 1, false}, + {1, "co.bi", 2, false}, + {1, "com.bi", 2, false}, + {1, "edu.bi", 2, false}, + {1, "or.bi", 2, false}, + {1, "org.bi", 2, false}, + {1, "biz", 1, false}, + {1, "bj", 1, false}, + {1, "asso.bj", 2, false}, + {1, "barreau.bj", 2, false}, + {1, "gouv.bj", 2, false}, + {1, "bm", 1, false}, + {1, "com.bm", 2, false}, + {1, "edu.bm", 2, false}, + {1, "gov.bm", 2, false}, + {1, "net.bm", 2, false}, + {1, "org.bm", 2, false}, + {1, "bn", 1, false}, + {1, "com.bn", 2, false}, + {1, "edu.bn", 2, false}, + {1, "gov.bn", 2, false}, + {1, "net.bn", 2, false}, + {1, "org.bn", 2, false}, + {1, "bo", 1, false}, + {1, "com.bo", 2, false}, + {1, "edu.bo", 2, false}, + {1, "gob.bo", 2, false}, + {1, "int.bo", 2, false}, + {1, "org.bo", 2, false}, + {1, "net.bo", 2, false}, + {1, "mil.bo", 2, false}, + {1, "tv.bo", 2, false}, + {1, "web.bo", 2, false}, + {1, "academia.bo", 2, false}, + {1, "agro.bo", 2, false}, + {1, "arte.bo", 2, false}, + {1, "blog.bo", 2, false}, + {1, "bolivia.bo", 2, false}, + {1, "ciencia.bo", 2, false}, + {1, "cooperativa.bo", 2, false}, + {1, "democracia.bo", 2, false}, + {1, "deporte.bo", 2, false}, + {1, "ecologia.bo", 2, false}, + {1, "economia.bo", 2, false}, + {1, "empresa.bo", 2, false}, + {1, "indigena.bo", 2, false}, + {1, "industria.bo", 2, false}, + {1, "info.bo", 2, false}, + {1, "medicina.bo", 2, false}, + {1, "movimiento.bo", 2, false}, + {1, "musica.bo", 2, false}, + {1, "natural.bo", 2, false}, + {1, "nombre.bo", 2, false}, + {1, "noticias.bo", 2, false}, + {1, "patria.bo", 2, false}, + {1, "politica.bo", 2, false}, + {1, "profesional.bo", 2, false}, + {1, "plurinacional.bo", 2, false}, + {1, "pueblo.bo", 2, false}, + {1, "revista.bo", 2, false}, + {1, "salud.bo", 2, false}, + {1, "tecnologia.bo", 2, false}, + {1, "tksat.bo", 2, false}, + {1, "transporte.bo", 2, false}, + {1, "wiki.bo", 2, false}, + {1, "br", 1, false}, + {1, "9guacu.br", 2, false}, + {1, "abc.br", 2, false}, + {1, "adm.br", 2, false}, + {1, "adv.br", 2, false}, + {1, "agr.br", 2, false}, + {1, "aju.br", 2, false}, + {1, "am.br", 2, false}, + {1, "anani.br", 2, false}, + {1, "aparecida.br", 2, false}, + {1, "arq.br", 2, false}, + {1, "art.br", 2, false}, + {1, "ato.br", 2, false}, + {1, "b.br", 2, false}, + {1, "barueri.br", 2, false}, + {1, "belem.br", 2, false}, + {1, "bhz.br", 2, false}, + {1, "bio.br", 2, false}, + {1, "blog.br", 2, false}, + {1, "bmd.br", 2, false}, + {1, "boavista.br", 2, false}, + {1, "bsb.br", 2, false}, + {1, "campinagrande.br", 2, false}, + {1, "campinas.br", 2, false}, + {1, "caxias.br", 2, false}, + {1, "cim.br", 2, false}, + {1, "cng.br", 2, false}, + {1, "cnt.br", 2, false}, + {1, "com.br", 2, false}, + {1, "contagem.br", 2, false}, + {1, "coop.br", 2, false}, + {1, "cri.br", 2, false}, + {1, "cuiaba.br", 2, false}, + {1, "curitiba.br", 2, false}, + {1, "def.br", 2, false}, + {1, "ecn.br", 2, false}, + {1, "eco.br", 2, false}, + {1, "edu.br", 2, false}, + {1, "emp.br", 2, false}, + {1, "eng.br", 2, false}, + {1, "esp.br", 2, false}, + {1, "etc.br", 2, false}, + {1, "eti.br", 2, false}, + {1, "far.br", 2, false}, + {1, "feira.br", 2, false}, + {1, "flog.br", 2, false}, + {1, "floripa.br", 2, false}, + {1, "fm.br", 2, false}, + {1, "fnd.br", 2, false}, + {1, "fortal.br", 2, false}, + {1, "fot.br", 2, false}, + {1, "foz.br", 2, false}, + {1, "fst.br", 2, false}, + {1, "g12.br", 2, false}, + {1, "ggf.br", 2, false}, + {1, "goiania.br", 2, false}, + {1, "gov.br", 2, false}, + {1, "ac.gov.br", 3, false}, + {1, "al.gov.br", 3, false}, + {1, "am.gov.br", 3, false}, + {1, "ap.gov.br", 3, false}, + {1, "ba.gov.br", 3, false}, + {1, "ce.gov.br", 3, false}, + {1, "df.gov.br", 3, false}, + {1, "es.gov.br", 3, false}, + {1, "go.gov.br", 3, false}, + {1, "ma.gov.br", 3, false}, + {1, "mg.gov.br", 3, false}, + {1, "ms.gov.br", 3, false}, + {1, "mt.gov.br", 3, false}, + {1, "pa.gov.br", 3, false}, + {1, "pb.gov.br", 3, false}, + {1, "pe.gov.br", 3, false}, + {1, "pi.gov.br", 3, false}, + {1, "pr.gov.br", 3, false}, + {1, "rj.gov.br", 3, false}, + {1, "rn.gov.br", 3, false}, + {1, "ro.gov.br", 3, false}, + {1, "rr.gov.br", 3, false}, + {1, "rs.gov.br", 3, false}, + {1, "sc.gov.br", 3, false}, + {1, "se.gov.br", 3, false}, + {1, "sp.gov.br", 3, false}, + {1, "to.gov.br", 3, false}, + {1, "gru.br", 2, false}, + {1, "imb.br", 2, false}, + {1, "ind.br", 2, false}, + {1, "inf.br", 2, false}, + {1, "jab.br", 2, false}, + {1, "jampa.br", 2, false}, + {1, "jdf.br", 2, false}, + {1, "joinville.br", 2, false}, + {1, "jor.br", 2, false}, + {1, "jus.br", 2, false}, + {1, "leg.br", 2, false}, + {1, "lel.br", 2, false}, + {1, "londrina.br", 2, false}, + {1, "macapa.br", 2, false}, + {1, "maceio.br", 2, false}, + {1, "manaus.br", 2, false}, + {1, "maringa.br", 2, false}, + {1, "mat.br", 2, false}, + {1, "med.br", 2, false}, + {1, "mil.br", 2, false}, + {1, "morena.br", 2, false}, + {1, "mp.br", 2, false}, + {1, "mus.br", 2, false}, + {1, "natal.br", 2, false}, + {1, "net.br", 2, false}, + {1, "niteroi.br", 2, false}, + {2, "nom.br", 3, false}, + {1, "not.br", 2, false}, + {1, "ntr.br", 2, false}, + {1, "odo.br", 2, false}, + {1, "ong.br", 2, false}, + {1, "org.br", 2, false}, + {1, "osasco.br", 2, false}, + {1, "palmas.br", 2, false}, + {1, "poa.br", 2, false}, + {1, "ppg.br", 2, false}, + {1, "pro.br", 2, false}, + {1, "psc.br", 2, false}, + {1, "psi.br", 2, false}, + {1, "pvh.br", 2, false}, + {1, "qsl.br", 2, false}, + {1, "radio.br", 2, false}, + {1, "rec.br", 2, false}, + {1, "recife.br", 2, false}, + {1, "ribeirao.br", 2, false}, + {1, "rio.br", 2, false}, + {1, "riobranco.br", 2, false}, + {1, "riopreto.br", 2, false}, + {1, "salvador.br", 2, false}, + {1, "sampa.br", 2, false}, + {1, "santamaria.br", 2, false}, + {1, "santoandre.br", 2, false}, + {1, "saobernardo.br", 2, false}, + {1, "saogonca.br", 2, false}, + {1, "sjc.br", 2, false}, + {1, "slg.br", 2, false}, + {1, "slz.br", 2, false}, + {1, "sorocaba.br", 2, false}, + {1, "srv.br", 2, false}, + {1, "taxi.br", 2, false}, + {1, "tc.br", 2, false}, + {1, "teo.br", 2, false}, + {1, "the.br", 2, false}, + {1, "tmp.br", 2, false}, + {1, "trd.br", 2, false}, + {1, "tur.br", 2, false}, + {1, "tv.br", 2, false}, + {1, "udi.br", 2, false}, + {1, "vet.br", 2, false}, + {1, "vix.br", 2, false}, + {1, "vlog.br", 2, false}, + {1, "wiki.br", 2, false}, + {1, "zlg.br", 2, false}, + {1, "bs", 1, false}, + {1, "com.bs", 2, false}, + {1, "net.bs", 2, false}, + {1, "org.bs", 2, false}, + {1, "edu.bs", 2, false}, + {1, "gov.bs", 2, false}, + {1, "bt", 1, false}, + {1, "com.bt", 2, false}, + {1, "edu.bt", 2, false}, + {1, "gov.bt", 2, false}, + {1, "net.bt", 2, false}, + {1, "org.bt", 2, false}, + {1, "bv", 1, false}, + {1, "bw", 1, false}, + {1, "co.bw", 2, false}, + {1, "org.bw", 2, false}, + {1, "by", 1, false}, + {1, "gov.by", 2, false}, + {1, "mil.by", 2, false}, + {1, "com.by", 2, false}, + {1, "of.by", 2, false}, + {1, "bz", 1, false}, + {1, "com.bz", 2, false}, + {1, "net.bz", 2, false}, + {1, "org.bz", 2, false}, + {1, "edu.bz", 2, false}, + {1, "gov.bz", 2, false}, + {1, "ca", 1, false}, + {1, "ab.ca", 2, false}, + {1, "bc.ca", 2, false}, + {1, "mb.ca", 2, false}, + {1, "nb.ca", 2, false}, + {1, "nf.ca", 2, false}, + {1, "nl.ca", 2, false}, + {1, "ns.ca", 2, false}, + {1, "nt.ca", 2, false}, + {1, "nu.ca", 2, false}, + {1, "on.ca", 2, false}, + {1, "pe.ca", 2, false}, + {1, "qc.ca", 2, false}, + {1, "sk.ca", 2, false}, + {1, "yk.ca", 2, false}, + {1, "gc.ca", 2, false}, + {1, "cat", 1, false}, + {1, "cc", 1, false}, + {1, "cd", 1, false}, + {1, "gov.cd", 2, false}, + {1, "cf", 1, false}, + {1, "cg", 1, false}, + {1, "ch", 1, false}, + {1, "ci", 1, false}, + {1, "org.ci", 2, false}, + {1, "or.ci", 2, false}, + {1, "com.ci", 2, false}, + {1, "co.ci", 2, false}, + {1, "edu.ci", 2, false}, + {1, "ed.ci", 2, false}, + {1, "ac.ci", 2, false}, + {1, "net.ci", 2, false}, + {1, "go.ci", 2, false}, + {1, "asso.ci", 2, false}, + {1, "xn--aroport-bya.ci", 2, false}, + {1, "int.ci", 2, false}, + {1, "presse.ci", 2, false}, + {1, "md.ci", 2, false}, + {1, "gouv.ci", 2, false}, + {2, "ck", 2, false}, + {3, "www.ck", 2, false}, + {1, "cl", 1, false}, + {1, "gov.cl", 2, false}, + {1, "gob.cl", 2, false}, + {1, "co.cl", 2, false}, + {1, "mil.cl", 2, false}, + {1, "cm", 1, false}, + {1, "co.cm", 2, false}, + {1, "com.cm", 2, false}, + {1, "gov.cm", 2, false}, + {1, "net.cm", 2, false}, + {1, "cn", 1, false}, + {1, "ac.cn", 2, false}, + {1, "com.cn", 2, false}, + {1, "edu.cn", 2, false}, + {1, "gov.cn", 2, false}, + {1, "net.cn", 2, false}, + {1, "org.cn", 2, false}, + {1, "mil.cn", 2, false}, + {1, "xn--55qx5d.cn", 2, false}, + {1, "xn--io0a7i.cn", 2, false}, + {1, "xn--od0alg.cn", 2, false}, + {1, "ah.cn", 2, false}, + {1, "bj.cn", 2, false}, + {1, "cq.cn", 2, false}, + {1, "fj.cn", 2, false}, + {1, "gd.cn", 2, false}, + {1, "gs.cn", 2, false}, + {1, "gz.cn", 2, false}, + {1, "gx.cn", 2, false}, + {1, "ha.cn", 2, false}, + {1, "hb.cn", 2, false}, + {1, "he.cn", 2, false}, + {1, "hi.cn", 2, false}, + {1, "hl.cn", 2, false}, + {1, "hn.cn", 2, false}, + {1, "jl.cn", 2, false}, + {1, "js.cn", 2, false}, + {1, "jx.cn", 2, false}, + {1, "ln.cn", 2, false}, + {1, "nm.cn", 2, false}, + {1, "nx.cn", 2, false}, + {1, "qh.cn", 2, false}, + {1, "sc.cn", 2, false}, + {1, "sd.cn", 2, false}, + {1, "sh.cn", 2, false}, + {1, "sn.cn", 2, false}, + {1, "sx.cn", 2, false}, + {1, "tj.cn", 2, false}, + {1, "xj.cn", 2, false}, + {1, "xz.cn", 2, false}, + {1, "yn.cn", 2, false}, + {1, "zj.cn", 2, false}, + {1, "hk.cn", 2, false}, + {1, "mo.cn", 2, false}, + {1, "tw.cn", 2, false}, + {1, "co", 1, false}, + {1, "arts.co", 2, false}, + {1, "com.co", 2, false}, + {1, "edu.co", 2, false}, + {1, "firm.co", 2, false}, + {1, "gov.co", 2, false}, + {1, "info.co", 2, false}, + {1, "int.co", 2, false}, + {1, "mil.co", 2, false}, + {1, "net.co", 2, false}, + {1, "nom.co", 2, false}, + {1, "org.co", 2, false}, + {1, "rec.co", 2, false}, + {1, "web.co", 2, false}, + {1, "com", 1, false}, + {1, "coop", 1, false}, + {1, "cr", 1, false}, + {1, "ac.cr", 2, false}, + {1, "co.cr", 2, false}, + {1, "ed.cr", 2, false}, + {1, "fi.cr", 2, false}, + {1, "go.cr", 2, false}, + {1, "or.cr", 2, false}, + {1, "sa.cr", 2, false}, + {1, "cu", 1, false}, + {1, "com.cu", 2, false}, + {1, "edu.cu", 2, false}, + {1, "org.cu", 2, false}, + {1, "net.cu", 2, false}, + {1, "gov.cu", 2, false}, + {1, "inf.cu", 2, false}, + {1, "cv", 1, false}, + {1, "cw", 1, false}, + {1, "com.cw", 2, false}, + {1, "edu.cw", 2, false}, + {1, "net.cw", 2, false}, + {1, "org.cw", 2, false}, + {1, "cx", 1, false}, + {1, "gov.cx", 2, false}, + {1, "cy", 1, false}, + {1, "ac.cy", 2, false}, + {1, "biz.cy", 2, false}, + {1, "com.cy", 2, false}, + {1, "ekloges.cy", 2, false}, + {1, "gov.cy", 2, false}, + {1, "ltd.cy", 2, false}, + {1, "name.cy", 2, false}, + {1, "net.cy", 2, false}, + {1, "org.cy", 2, false}, + {1, "parliament.cy", 2, false}, + {1, "press.cy", 2, false}, + {1, "pro.cy", 2, false}, + {1, "tm.cy", 2, false}, + {1, "cz", 1, false}, + {1, "de", 1, false}, + {1, "dj", 1, false}, + {1, "dk", 1, false}, + {1, "dm", 1, false}, + {1, "com.dm", 2, false}, + {1, "net.dm", 2, false}, + {1, "org.dm", 2, false}, + {1, "edu.dm", 2, false}, + {1, "gov.dm", 2, false}, + {1, "do", 1, false}, + {1, "art.do", 2, false}, + {1, "com.do", 2, false}, + {1, "edu.do", 2, false}, + {1, "gob.do", 2, false}, + {1, "gov.do", 2, false}, + {1, "mil.do", 2, false}, + {1, "net.do", 2, false}, + {1, "org.do", 2, false}, + {1, "sld.do", 2, false}, + {1, "web.do", 2, false}, + {1, "dz", 1, false}, + {1, "com.dz", 2, false}, + {1, "org.dz", 2, false}, + {1, "net.dz", 2, false}, + {1, "gov.dz", 2, false}, + {1, "edu.dz", 2, false}, + {1, "asso.dz", 2, false}, + {1, "pol.dz", 2, false}, + {1, "art.dz", 2, false}, + {1, "ec", 1, false}, + {1, "com.ec", 2, false}, + {1, "info.ec", 2, false}, + {1, "net.ec", 2, false}, + {1, "fin.ec", 2, false}, + {1, "k12.ec", 2, false}, + {1, "med.ec", 2, false}, + {1, "pro.ec", 2, false}, + {1, "org.ec", 2, false}, + {1, "edu.ec", 2, false}, + {1, "gov.ec", 2, false}, + {1, "gob.ec", 2, false}, + {1, "mil.ec", 2, false}, + {1, "edu", 1, false}, + {1, "ee", 1, false}, + {1, "edu.ee", 2, false}, + {1, "gov.ee", 2, false}, + {1, "riik.ee", 2, false}, + {1, "lib.ee", 2, false}, + {1, "med.ee", 2, false}, + {1, "com.ee", 2, false}, + {1, "pri.ee", 2, false}, + {1, "aip.ee", 2, false}, + {1, "org.ee", 2, false}, + {1, "fie.ee", 2, false}, + {1, "eg", 1, false}, + {1, "com.eg", 2, false}, + {1, "edu.eg", 2, false}, + {1, "eun.eg", 2, false}, + {1, "gov.eg", 2, false}, + {1, "mil.eg", 2, false}, + {1, "name.eg", 2, false}, + {1, "net.eg", 2, false}, + {1, "org.eg", 2, false}, + {1, "sci.eg", 2, false}, + {2, "er", 2, false}, + {1, "es", 1, false}, + {1, "com.es", 2, false}, + {1, "nom.es", 2, false}, + {1, "org.es", 2, false}, + {1, "gob.es", 2, false}, + {1, "edu.es", 2, false}, + {1, "et", 1, false}, + {1, "com.et", 2, false}, + {1, "gov.et", 2, false}, + {1, "org.et", 2, false}, + {1, "edu.et", 2, false}, + {1, "biz.et", 2, false}, + {1, "name.et", 2, false}, + {1, "info.et", 2, false}, + {1, "net.et", 2, false}, + {1, "eu", 1, false}, + {1, "fi", 1, false}, + {1, "aland.fi", 2, false}, + {1, "fj", 1, false}, + {1, "ac.fj", 2, false}, + {1, "biz.fj", 2, false}, + {1, "com.fj", 2, false}, + {1, "gov.fj", 2, false}, + {1, "info.fj", 2, false}, + {1, "mil.fj", 2, false}, + {1, "name.fj", 2, false}, + {1, "net.fj", 2, false}, + {1, "org.fj", 2, false}, + {1, "pro.fj", 2, false}, + {2, "fk", 2, false}, + {1, "fm", 1, false}, + {1, "fo", 1, false}, + {1, "fr", 1, false}, + {1, "asso.fr", 2, false}, + {1, "com.fr", 2, false}, + {1, "gouv.fr", 2, false}, + {1, "nom.fr", 2, false}, + {1, "prd.fr", 2, false}, + {1, "tm.fr", 2, false}, + {1, "aeroport.fr", 2, false}, + {1, "avocat.fr", 2, false}, + {1, "avoues.fr", 2, false}, + {1, "cci.fr", 2, false}, + {1, "chambagri.fr", 2, false}, + {1, "chirurgiens-dentistes.fr", 2, false}, + {1, "experts-comptables.fr", 2, false}, + {1, "geometre-expert.fr", 2, false}, + {1, "greta.fr", 2, false}, + {1, "huissier-justice.fr", 2, false}, + {1, "medecin.fr", 2, false}, + {1, "notaires.fr", 2, false}, + {1, "pharmacien.fr", 2, false}, + {1, "port.fr", 2, false}, + {1, "veterinaire.fr", 2, false}, + {1, "ga", 1, false}, + {1, "gb", 1, false}, + {1, "gd", 1, false}, + {1, "ge", 1, false}, + {1, "com.ge", 2, false}, + {1, "edu.ge", 2, false}, + {1, "gov.ge", 2, false}, + {1, "org.ge", 2, false}, + {1, "mil.ge", 2, false}, + {1, "net.ge", 2, false}, + {1, "pvt.ge", 2, false}, + {1, "gf", 1, false}, + {1, "gg", 1, false}, + {1, "co.gg", 2, false}, + {1, "net.gg", 2, false}, + {1, "org.gg", 2, false}, + {1, "gh", 1, false}, + {1, "com.gh", 2, false}, + {1, "edu.gh", 2, false}, + {1, "gov.gh", 2, false}, + {1, "org.gh", 2, false}, + {1, "mil.gh", 2, false}, + {1, "gi", 1, false}, + {1, "com.gi", 2, false}, + {1, "ltd.gi", 2, false}, + {1, "gov.gi", 2, false}, + {1, "mod.gi", 2, false}, + {1, "edu.gi", 2, false}, + {1, "org.gi", 2, false}, + {1, "gl", 1, false}, + {1, "co.gl", 2, false}, + {1, "com.gl", 2, false}, + {1, "edu.gl", 2, false}, + {1, "net.gl", 2, false}, + {1, "org.gl", 2, false}, + {1, "gm", 1, false}, + {1, "gn", 1, false}, + {1, "ac.gn", 2, false}, + {1, "com.gn", 2, false}, + {1, "edu.gn", 2, false}, + {1, "gov.gn", 2, false}, + {1, "org.gn", 2, false}, + {1, "net.gn", 2, false}, + {1, "gov", 1, false}, + {1, "gp", 1, false}, + {1, "com.gp", 2, false}, + {1, "net.gp", 2, false}, + {1, "mobi.gp", 2, false}, + {1, "edu.gp", 2, false}, + {1, "org.gp", 2, false}, + {1, "asso.gp", 2, false}, + {1, "gq", 1, false}, + {1, "gr", 1, false}, + {1, "com.gr", 2, false}, + {1, "edu.gr", 2, false}, + {1, "net.gr", 2, false}, + {1, "org.gr", 2, false}, + {1, "gov.gr", 2, false}, + {1, "gs", 1, false}, + {1, "gt", 1, false}, + {1, "com.gt", 2, false}, + {1, "edu.gt", 2, false}, + {1, "gob.gt", 2, false}, + {1, "ind.gt", 2, false}, + {1, "mil.gt", 2, false}, + {1, "net.gt", 2, false}, + {1, "org.gt", 2, false}, + {1, "gu", 1, false}, + {1, "com.gu", 2, false}, + {1, "edu.gu", 2, false}, + {1, "gov.gu", 2, false}, + {1, "guam.gu", 2, false}, + {1, "info.gu", 2, false}, + {1, "net.gu", 2, false}, + {1, "org.gu", 2, false}, + {1, "web.gu", 2, false}, + {1, "gw", 1, false}, + {1, "gy", 1, false}, + {1, "co.gy", 2, false}, + {1, "com.gy", 2, false}, + {1, "edu.gy", 2, false}, + {1, "gov.gy", 2, false}, + {1, "net.gy", 2, false}, + {1, "org.gy", 2, false}, + {1, "hk", 1, false}, + {1, "com.hk", 2, false}, + {1, "edu.hk", 2, false}, + {1, "gov.hk", 2, false}, + {1, "idv.hk", 2, false}, + {1, "net.hk", 2, false}, + {1, "org.hk", 2, false}, + {1, "xn--55qx5d.hk", 2, false}, + {1, "xn--wcvs22d.hk", 2, false}, + {1, "xn--lcvr32d.hk", 2, false}, + {1, "xn--mxtq1m.hk", 2, false}, + {1, "xn--gmqw5a.hk", 2, false}, + {1, "xn--ciqpn.hk", 2, false}, + {1, "xn--gmq050i.hk", 2, false}, + {1, "xn--zf0avx.hk", 2, false}, + {1, "xn--io0a7i.hk", 2, false}, + {1, "xn--mk0axi.hk", 2, false}, + {1, "xn--od0alg.hk", 2, false}, + {1, "xn--od0aq3b.hk", 2, false}, + {1, "xn--tn0ag.hk", 2, false}, + {1, "xn--uc0atv.hk", 2, false}, + {1, "xn--uc0ay4a.hk", 2, false}, + {1, "hm", 1, false}, + {1, "hn", 1, false}, + {1, "com.hn", 2, false}, + {1, "edu.hn", 2, false}, + {1, "org.hn", 2, false}, + {1, "net.hn", 2, false}, + {1, "mil.hn", 2, false}, + {1, "gob.hn", 2, false}, + {1, "hr", 1, false}, + {1, "iz.hr", 2, false}, + {1, "from.hr", 2, false}, + {1, "name.hr", 2, false}, + {1, "com.hr", 2, false}, + {1, "ht", 1, false}, + {1, "com.ht", 2, false}, + {1, "shop.ht", 2, false}, + {1, "firm.ht", 2, false}, + {1, "info.ht", 2, false}, + {1, "adult.ht", 2, false}, + {1, "net.ht", 2, false}, + {1, "pro.ht", 2, false}, + {1, "org.ht", 2, false}, + {1, "med.ht", 2, false}, + {1, "art.ht", 2, false}, + {1, "coop.ht", 2, false}, + {1, "pol.ht", 2, false}, + {1, "asso.ht", 2, false}, + {1, "edu.ht", 2, false}, + {1, "rel.ht", 2, false}, + {1, "gouv.ht", 2, false}, + {1, "perso.ht", 2, false}, + {1, "hu", 1, false}, + {1, "co.hu", 2, false}, + {1, "info.hu", 2, false}, + {1, "org.hu", 2, false}, + {1, "priv.hu", 2, false}, + {1, "sport.hu", 2, false}, + {1, "tm.hu", 2, false}, + {1, "2000.hu", 2, false}, + {1, "agrar.hu", 2, false}, + {1, "bolt.hu", 2, false}, + {1, "casino.hu", 2, false}, + {1, "city.hu", 2, false}, + {1, "erotica.hu", 2, false}, + {1, "erotika.hu", 2, false}, + {1, "film.hu", 2, false}, + {1, "forum.hu", 2, false}, + {1, "games.hu", 2, false}, + {1, "hotel.hu", 2, false}, + {1, "ingatlan.hu", 2, false}, + {1, "jogasz.hu", 2, false}, + {1, "konyvelo.hu", 2, false}, + {1, "lakas.hu", 2, false}, + {1, "media.hu", 2, false}, + {1, "news.hu", 2, false}, + {1, "reklam.hu", 2, false}, + {1, "sex.hu", 2, false}, + {1, "shop.hu", 2, false}, + {1, "suli.hu", 2, false}, + {1, "szex.hu", 2, false}, + {1, "tozsde.hu", 2, false}, + {1, "utazas.hu", 2, false}, + {1, "video.hu", 2, false}, + {1, "id", 1, false}, + {1, "ac.id", 2, false}, + {1, "biz.id", 2, false}, + {1, "co.id", 2, false}, + {1, "desa.id", 2, false}, + {1, "go.id", 2, false}, + {1, "mil.id", 2, false}, + {1, "my.id", 2, false}, + {1, "net.id", 2, false}, + {1, "or.id", 2, false}, + {1, "ponpes.id", 2, false}, + {1, "sch.id", 2, false}, + {1, "web.id", 2, false}, + {1, "ie", 1, false}, + {1, "gov.ie", 2, false}, + {1, "il", 1, false}, + {1, "ac.il", 2, false}, + {1, "co.il", 2, false}, + {1, "gov.il", 2, false}, + {1, "idf.il", 2, false}, + {1, "k12.il", 2, false}, + {1, "muni.il", 2, false}, + {1, "net.il", 2, false}, + {1, "org.il", 2, false}, + {1, "im", 1, false}, + {1, "ac.im", 2, false}, + {1, "co.im", 2, false}, + {1, "com.im", 2, false}, + {1, "ltd.co.im", 3, false}, + {1, "net.im", 2, false}, + {1, "org.im", 2, false}, + {1, "plc.co.im", 3, false}, + {1, "tt.im", 2, false}, + {1, "tv.im", 2, false}, + {1, "in", 1, false}, + {1, "co.in", 2, false}, + {1, "firm.in", 2, false}, + {1, "net.in", 2, false}, + {1, "org.in", 2, false}, + {1, "gen.in", 2, false}, + {1, "ind.in", 2, false}, + {1, "nic.in", 2, false}, + {1, "ac.in", 2, false}, + {1, "edu.in", 2, false}, + {1, "res.in", 2, false}, + {1, "gov.in", 2, false}, + {1, "mil.in", 2, false}, + {1, "info", 1, false}, + {1, "int", 1, false}, + {1, "eu.int", 2, false}, + {1, "io", 1, false}, + {1, "com.io", 2, false}, + {1, "iq", 1, false}, + {1, "gov.iq", 2, false}, + {1, "edu.iq", 2, false}, + {1, "mil.iq", 2, false}, + {1, "com.iq", 2, false}, + {1, "org.iq", 2, false}, + {1, "net.iq", 2, false}, + {1, "ir", 1, false}, + {1, "ac.ir", 2, false}, + {1, "co.ir", 2, false}, + {1, "gov.ir", 2, false}, + {1, "id.ir", 2, false}, + {1, "net.ir", 2, false}, + {1, "org.ir", 2, false}, + {1, "sch.ir", 2, false}, + {1, "xn--mgba3a4f16a.ir", 2, false}, + {1, "xn--mgba3a4fra.ir", 2, false}, + {1, "is", 1, false}, + {1, "net.is", 2, false}, + {1, "com.is", 2, false}, + {1, "edu.is", 2, false}, + {1, "gov.is", 2, false}, + {1, "org.is", 2, false}, + {1, "int.is", 2, false}, + {1, "it", 1, false}, + {1, "gov.it", 2, false}, + {1, "edu.it", 2, false}, + {1, "abr.it", 2, false}, + {1, "abruzzo.it", 2, false}, + {1, "aosta-valley.it", 2, false}, + {1, "aostavalley.it", 2, false}, + {1, "bas.it", 2, false}, + {1, "basilicata.it", 2, false}, + {1, "cal.it", 2, false}, + {1, "calabria.it", 2, false}, + {1, "cam.it", 2, false}, + {1, "campania.it", 2, false}, + {1, "emilia-romagna.it", 2, false}, + {1, "emiliaromagna.it", 2, false}, + {1, "emr.it", 2, false}, + {1, "friuli-v-giulia.it", 2, false}, + {1, "friuli-ve-giulia.it", 2, false}, + {1, "friuli-vegiulia.it", 2, false}, + {1, "friuli-venezia-giulia.it", 2, false}, + {1, "friuli-veneziagiulia.it", 2, false}, + {1, "friuli-vgiulia.it", 2, false}, + {1, "friuliv-giulia.it", 2, false}, + {1, "friulive-giulia.it", 2, false}, + {1, "friulivegiulia.it", 2, false}, + {1, "friulivenezia-giulia.it", 2, false}, + {1, "friuliveneziagiulia.it", 2, false}, + {1, "friulivgiulia.it", 2, false}, + {1, "fvg.it", 2, false}, + {1, "laz.it", 2, false}, + {1, "lazio.it", 2, false}, + {1, "lig.it", 2, false}, + {1, "liguria.it", 2, false}, + {1, "lom.it", 2, false}, + {1, "lombardia.it", 2, false}, + {1, "lombardy.it", 2, false}, + {1, "lucania.it", 2, false}, + {1, "mar.it", 2, false}, + {1, "marche.it", 2, false}, + {1, "mol.it", 2, false}, + {1, "molise.it", 2, false}, + {1, "piedmont.it", 2, false}, + {1, "piemonte.it", 2, false}, + {1, "pmn.it", 2, false}, + {1, "pug.it", 2, false}, + {1, "puglia.it", 2, false}, + {1, "sar.it", 2, false}, + {1, "sardegna.it", 2, false}, + {1, "sardinia.it", 2, false}, + {1, "sic.it", 2, false}, + {1, "sicilia.it", 2, false}, + {1, "sicily.it", 2, false}, + {1, "taa.it", 2, false}, + {1, "tos.it", 2, false}, + {1, "toscana.it", 2, false}, + {1, "trentin-sud-tirol.it", 2, false}, + {1, "xn--trentin-sd-tirol-rzb.it", 2, false}, + {1, "trentin-sudtirol.it", 2, false}, + {1, "xn--trentin-sdtirol-7vb.it", 2, false}, + {1, "trentin-sued-tirol.it", 2, false}, + {1, "trentin-suedtirol.it", 2, false}, + {1, "trentino-a-adige.it", 2, false}, + {1, "trentino-aadige.it", 2, false}, + {1, "trentino-alto-adige.it", 2, false}, + {1, "trentino-altoadige.it", 2, false}, + {1, "trentino-s-tirol.it", 2, false}, + {1, "trentino-stirol.it", 2, false}, + {1, "trentino-sud-tirol.it", 2, false}, + {1, "xn--trentino-sd-tirol-c3b.it", 2, false}, + {1, "trentino-sudtirol.it", 2, false}, + {1, "xn--trentino-sdtirol-szb.it", 2, false}, + {1, "trentino-sued-tirol.it", 2, false}, + {1, "trentino-suedtirol.it", 2, false}, + {1, "trentino.it", 2, false}, + {1, "trentinoa-adige.it", 2, false}, + {1, "trentinoaadige.it", 2, false}, + {1, "trentinoalto-adige.it", 2, false}, + {1, "trentinoaltoadige.it", 2, false}, + {1, "trentinos-tirol.it", 2, false}, + {1, "trentinostirol.it", 2, false}, + {1, "trentinosud-tirol.it", 2, false}, + {1, "xn--trentinosd-tirol-rzb.it", 2, false}, + {1, "trentinosudtirol.it", 2, false}, + {1, "xn--trentinosdtirol-7vb.it", 2, false}, + {1, "trentinosued-tirol.it", 2, false}, + {1, "trentinosuedtirol.it", 2, false}, + {1, "trentinsud-tirol.it", 2, false}, + {1, "xn--trentinsd-tirol-6vb.it", 2, false}, + {1, "trentinsudtirol.it", 2, false}, + {1, "xn--trentinsdtirol-nsb.it", 2, false}, + {1, "trentinsued-tirol.it", 2, false}, + {1, "trentinsuedtirol.it", 2, false}, + {1, "tuscany.it", 2, false}, + {1, "umb.it", 2, false}, + {1, "umbria.it", 2, false}, + {1, "val-d-aosta.it", 2, false}, + {1, "val-daosta.it", 2, false}, + {1, "vald-aosta.it", 2, false}, + {1, "valdaosta.it", 2, false}, + {1, "valle-aosta.it", 2, false}, + {1, "valle-d-aosta.it", 2, false}, + {1, "valle-daosta.it", 2, false}, + {1, "valleaosta.it", 2, false}, + {1, "valled-aosta.it", 2, false}, + {1, "valledaosta.it", 2, false}, + {1, "vallee-aoste.it", 2, false}, + {1, "xn--valle-aoste-ebb.it", 2, false}, + {1, "vallee-d-aoste.it", 2, false}, + {1, "xn--valle-d-aoste-ehb.it", 2, false}, + {1, "valleeaoste.it", 2, false}, + {1, "xn--valleaoste-e7a.it", 2, false}, + {1, "valleedaoste.it", 2, false}, + {1, "xn--valledaoste-ebb.it", 2, false}, + {1, "vao.it", 2, false}, + {1, "vda.it", 2, false}, + {1, "ven.it", 2, false}, + {1, "veneto.it", 2, false}, + {1, "ag.it", 2, false}, + {1, "agrigento.it", 2, false}, + {1, "al.it", 2, false}, + {1, "alessandria.it", 2, false}, + {1, "alto-adige.it", 2, false}, + {1, "altoadige.it", 2, false}, + {1, "an.it", 2, false}, + {1, "ancona.it", 2, false}, + {1, "andria-barletta-trani.it", 2, false}, + {1, "andria-trani-barletta.it", 2, false}, + {1, "andriabarlettatrani.it", 2, false}, + {1, "andriatranibarletta.it", 2, false}, + {1, "ao.it", 2, false}, + {1, "aosta.it", 2, false}, + {1, "aoste.it", 2, false}, + {1, "ap.it", 2, false}, + {1, "aq.it", 2, false}, + {1, "aquila.it", 2, false}, + {1, "ar.it", 2, false}, + {1, "arezzo.it", 2, false}, + {1, "ascoli-piceno.it", 2, false}, + {1, "ascolipiceno.it", 2, false}, + {1, "asti.it", 2, false}, + {1, "at.it", 2, false}, + {1, "av.it", 2, false}, + {1, "avellino.it", 2, false}, + {1, "ba.it", 2, false}, + {1, "balsan-sudtirol.it", 2, false}, + {1, "xn--balsan-sdtirol-nsb.it", 2, false}, + {1, "balsan-suedtirol.it", 2, false}, + {1, "balsan.it", 2, false}, + {1, "bari.it", 2, false}, + {1, "barletta-trani-andria.it", 2, false}, + {1, "barlettatraniandria.it", 2, false}, + {1, "belluno.it", 2, false}, + {1, "benevento.it", 2, false}, + {1, "bergamo.it", 2, false}, + {1, "bg.it", 2, false}, + {1, "bi.it", 2, false}, + {1, "biella.it", 2, false}, + {1, "bl.it", 2, false}, + {1, "bn.it", 2, false}, + {1, "bo.it", 2, false}, + {1, "bologna.it", 2, false}, + {1, "bolzano-altoadige.it", 2, false}, + {1, "bolzano.it", 2, false}, + {1, "bozen-sudtirol.it", 2, false}, + {1, "xn--bozen-sdtirol-2ob.it", 2, false}, + {1, "bozen-suedtirol.it", 2, false}, + {1, "bozen.it", 2, false}, + {1, "br.it", 2, false}, + {1, "brescia.it", 2, false}, + {1, "brindisi.it", 2, false}, + {1, "bs.it", 2, false}, + {1, "bt.it", 2, false}, + {1, "bulsan-sudtirol.it", 2, false}, + {1, "xn--bulsan-sdtirol-nsb.it", 2, false}, + {1, "bulsan-suedtirol.it", 2, false}, + {1, "bulsan.it", 2, false}, + {1, "bz.it", 2, false}, + {1, "ca.it", 2, false}, + {1, "cagliari.it", 2, false}, + {1, "caltanissetta.it", 2, false}, + {1, "campidano-medio.it", 2, false}, + {1, "campidanomedio.it", 2, false}, + {1, "campobasso.it", 2, false}, + {1, "carbonia-iglesias.it", 2, false}, + {1, "carboniaiglesias.it", 2, false}, + {1, "carrara-massa.it", 2, false}, + {1, "carraramassa.it", 2, false}, + {1, "caserta.it", 2, false}, + {1, "catania.it", 2, false}, + {1, "catanzaro.it", 2, false}, + {1, "cb.it", 2, false}, + {1, "ce.it", 2, false}, + {1, "cesena-forli.it", 2, false}, + {1, "xn--cesena-forl-mcb.it", 2, false}, + {1, "cesenaforli.it", 2, false}, + {1, "xn--cesenaforl-i8a.it", 2, false}, + {1, "ch.it", 2, false}, + {1, "chieti.it", 2, false}, + {1, "ci.it", 2, false}, + {1, "cl.it", 2, false}, + {1, "cn.it", 2, false}, + {1, "co.it", 2, false}, + {1, "como.it", 2, false}, + {1, "cosenza.it", 2, false}, + {1, "cr.it", 2, false}, + {1, "cremona.it", 2, false}, + {1, "crotone.it", 2, false}, + {1, "cs.it", 2, false}, + {1, "ct.it", 2, false}, + {1, "cuneo.it", 2, false}, + {1, "cz.it", 2, false}, + {1, "dell-ogliastra.it", 2, false}, + {1, "dellogliastra.it", 2, false}, + {1, "en.it", 2, false}, + {1, "enna.it", 2, false}, + {1, "fc.it", 2, false}, + {1, "fe.it", 2, false}, + {1, "fermo.it", 2, false}, + {1, "ferrara.it", 2, false}, + {1, "fg.it", 2, false}, + {1, "fi.it", 2, false}, + {1, "firenze.it", 2, false}, + {1, "florence.it", 2, false}, + {1, "fm.it", 2, false}, + {1, "foggia.it", 2, false}, + {1, "forli-cesena.it", 2, false}, + {1, "xn--forl-cesena-fcb.it", 2, false}, + {1, "forlicesena.it", 2, false}, + {1, "xn--forlcesena-c8a.it", 2, false}, + {1, "fr.it", 2, false}, + {1, "frosinone.it", 2, false}, + {1, "ge.it", 2, false}, + {1, "genoa.it", 2, false}, + {1, "genova.it", 2, false}, + {1, "go.it", 2, false}, + {1, "gorizia.it", 2, false}, + {1, "gr.it", 2, false}, + {1, "grosseto.it", 2, false}, + {1, "iglesias-carbonia.it", 2, false}, + {1, "iglesiascarbonia.it", 2, false}, + {1, "im.it", 2, false}, + {1, "imperia.it", 2, false}, + {1, "is.it", 2, false}, + {1, "isernia.it", 2, false}, + {1, "kr.it", 2, false}, + {1, "la-spezia.it", 2, false}, + {1, "laquila.it", 2, false}, + {1, "laspezia.it", 2, false}, + {1, "latina.it", 2, false}, + {1, "lc.it", 2, false}, + {1, "le.it", 2, false}, + {1, "lecce.it", 2, false}, + {1, "lecco.it", 2, false}, + {1, "li.it", 2, false}, + {1, "livorno.it", 2, false}, + {1, "lo.it", 2, false}, + {1, "lodi.it", 2, false}, + {1, "lt.it", 2, false}, + {1, "lu.it", 2, false}, + {1, "lucca.it", 2, false}, + {1, "macerata.it", 2, false}, + {1, "mantova.it", 2, false}, + {1, "massa-carrara.it", 2, false}, + {1, "massacarrara.it", 2, false}, + {1, "matera.it", 2, false}, + {1, "mb.it", 2, false}, + {1, "mc.it", 2, false}, + {1, "me.it", 2, false}, + {1, "medio-campidano.it", 2, false}, + {1, "mediocampidano.it", 2, false}, + {1, "messina.it", 2, false}, + {1, "mi.it", 2, false}, + {1, "milan.it", 2, false}, + {1, "milano.it", 2, false}, + {1, "mn.it", 2, false}, + {1, "mo.it", 2, false}, + {1, "modena.it", 2, false}, + {1, "monza-brianza.it", 2, false}, + {1, "monza-e-della-brianza.it", 2, false}, + {1, "monza.it", 2, false}, + {1, "monzabrianza.it", 2, false}, + {1, "monzaebrianza.it", 2, false}, + {1, "monzaedellabrianza.it", 2, false}, + {1, "ms.it", 2, false}, + {1, "mt.it", 2, false}, + {1, "na.it", 2, false}, + {1, "naples.it", 2, false}, + {1, "napoli.it", 2, false}, + {1, "no.it", 2, false}, + {1, "novara.it", 2, false}, + {1, "nu.it", 2, false}, + {1, "nuoro.it", 2, false}, + {1, "og.it", 2, false}, + {1, "ogliastra.it", 2, false}, + {1, "olbia-tempio.it", 2, false}, + {1, "olbiatempio.it", 2, false}, + {1, "or.it", 2, false}, + {1, "oristano.it", 2, false}, + {1, "ot.it", 2, false}, + {1, "pa.it", 2, false}, + {1, "padova.it", 2, false}, + {1, "padua.it", 2, false}, + {1, "palermo.it", 2, false}, + {1, "parma.it", 2, false}, + {1, "pavia.it", 2, false}, + {1, "pc.it", 2, false}, + {1, "pd.it", 2, false}, + {1, "pe.it", 2, false}, + {1, "perugia.it", 2, false}, + {1, "pesaro-urbino.it", 2, false}, + {1, "pesarourbino.it", 2, false}, + {1, "pescara.it", 2, false}, + {1, "pg.it", 2, false}, + {1, "pi.it", 2, false}, + {1, "piacenza.it", 2, false}, + {1, "pisa.it", 2, false}, + {1, "pistoia.it", 2, false}, + {1, "pn.it", 2, false}, + {1, "po.it", 2, false}, + {1, "pordenone.it", 2, false}, + {1, "potenza.it", 2, false}, + {1, "pr.it", 2, false}, + {1, "prato.it", 2, false}, + {1, "pt.it", 2, false}, + {1, "pu.it", 2, false}, + {1, "pv.it", 2, false}, + {1, "pz.it", 2, false}, + {1, "ra.it", 2, false}, + {1, "ragusa.it", 2, false}, + {1, "ravenna.it", 2, false}, + {1, "rc.it", 2, false}, + {1, "re.it", 2, false}, + {1, "reggio-calabria.it", 2, false}, + {1, "reggio-emilia.it", 2, false}, + {1, "reggiocalabria.it", 2, false}, + {1, "reggioemilia.it", 2, false}, + {1, "rg.it", 2, false}, + {1, "ri.it", 2, false}, + {1, "rieti.it", 2, false}, + {1, "rimini.it", 2, false}, + {1, "rm.it", 2, false}, + {1, "rn.it", 2, false}, + {1, "ro.it", 2, false}, + {1, "roma.it", 2, false}, + {1, "rome.it", 2, false}, + {1, "rovigo.it", 2, false}, + {1, "sa.it", 2, false}, + {1, "salerno.it", 2, false}, + {1, "sassari.it", 2, false}, + {1, "savona.it", 2, false}, + {1, "si.it", 2, false}, + {1, "siena.it", 2, false}, + {1, "siracusa.it", 2, false}, + {1, "so.it", 2, false}, + {1, "sondrio.it", 2, false}, + {1, "sp.it", 2, false}, + {1, "sr.it", 2, false}, + {1, "ss.it", 2, false}, + {1, "suedtirol.it", 2, false}, + {1, "xn--sdtirol-n2a.it", 2, false}, + {1, "sv.it", 2, false}, + {1, "ta.it", 2, false}, + {1, "taranto.it", 2, false}, + {1, "te.it", 2, false}, + {1, "tempio-olbia.it", 2, false}, + {1, "tempioolbia.it", 2, false}, + {1, "teramo.it", 2, false}, + {1, "terni.it", 2, false}, + {1, "tn.it", 2, false}, + {1, "to.it", 2, false}, + {1, "torino.it", 2, false}, + {1, "tp.it", 2, false}, + {1, "tr.it", 2, false}, + {1, "trani-andria-barletta.it", 2, false}, + {1, "trani-barletta-andria.it", 2, false}, + {1, "traniandriabarletta.it", 2, false}, + {1, "tranibarlettaandria.it", 2, false}, + {1, "trapani.it", 2, false}, + {1, "trento.it", 2, false}, + {1, "treviso.it", 2, false}, + {1, "trieste.it", 2, false}, + {1, "ts.it", 2, false}, + {1, "turin.it", 2, false}, + {1, "tv.it", 2, false}, + {1, "ud.it", 2, false}, + {1, "udine.it", 2, false}, + {1, "urbino-pesaro.it", 2, false}, + {1, "urbinopesaro.it", 2, false}, + {1, "va.it", 2, false}, + {1, "varese.it", 2, false}, + {1, "vb.it", 2, false}, + {1, "vc.it", 2, false}, + {1, "ve.it", 2, false}, + {1, "venezia.it", 2, false}, + {1, "venice.it", 2, false}, + {1, "verbania.it", 2, false}, + {1, "vercelli.it", 2, false}, + {1, "verona.it", 2, false}, + {1, "vi.it", 2, false}, + {1, "vibo-valentia.it", 2, false}, + {1, "vibovalentia.it", 2, false}, + {1, "vicenza.it", 2, false}, + {1, "viterbo.it", 2, false}, + {1, "vr.it", 2, false}, + {1, "vs.it", 2, false}, + {1, "vt.it", 2, false}, + {1, "vv.it", 2, false}, + {1, "je", 1, false}, + {1, "co.je", 2, false}, + {1, "net.je", 2, false}, + {1, "org.je", 2, false}, + {2, "jm", 2, false}, + {1, "jo", 1, false}, + {1, "com.jo", 2, false}, + {1, "org.jo", 2, false}, + {1, "net.jo", 2, false}, + {1, "edu.jo", 2, false}, + {1, "sch.jo", 2, false}, + {1, "gov.jo", 2, false}, + {1, "mil.jo", 2, false}, + {1, "name.jo", 2, false}, + {1, "jobs", 1, false}, + {1, "jp", 1, false}, + {1, "ac.jp", 2, false}, + {1, "ad.jp", 2, false}, + {1, "co.jp", 2, false}, + {1, "ed.jp", 2, false}, + {1, "go.jp", 2, false}, + {1, "gr.jp", 2, false}, + {1, "lg.jp", 2, false}, + {1, "ne.jp", 2, false}, + {1, "or.jp", 2, false}, + {1, "aichi.jp", 2, false}, + {1, "akita.jp", 2, false}, + {1, "aomori.jp", 2, false}, + {1, "chiba.jp", 2, false}, + {1, "ehime.jp", 2, false}, + {1, "fukui.jp", 2, false}, + {1, "fukuoka.jp", 2, false}, + {1, "fukushima.jp", 2, false}, + {1, "gifu.jp", 2, false}, + {1, "gunma.jp", 2, false}, + {1, "hiroshima.jp", 2, false}, + {1, "hokkaido.jp", 2, false}, + {1, "hyogo.jp", 2, false}, + {1, "ibaraki.jp", 2, false}, + {1, "ishikawa.jp", 2, false}, + {1, "iwate.jp", 2, false}, + {1, "kagawa.jp", 2, false}, + {1, "kagoshima.jp", 2, false}, + {1, "kanagawa.jp", 2, false}, + {1, "kochi.jp", 2, false}, + {1, "kumamoto.jp", 2, false}, + {1, "kyoto.jp", 2, false}, + {1, "mie.jp", 2, false}, + {1, "miyagi.jp", 2, false}, + {1, "miyazaki.jp", 2, false}, + {1, "nagano.jp", 2, false}, + {1, "nagasaki.jp", 2, false}, + {1, "nara.jp", 2, false}, + {1, "niigata.jp", 2, false}, + {1, "oita.jp", 2, false}, + {1, "okayama.jp", 2, false}, + {1, "okinawa.jp", 2, false}, + {1, "osaka.jp", 2, false}, + {1, "saga.jp", 2, false}, + {1, "saitama.jp", 2, false}, + {1, "shiga.jp", 2, false}, + {1, "shimane.jp", 2, false}, + {1, "shizuoka.jp", 2, false}, + {1, "tochigi.jp", 2, false}, + {1, "tokushima.jp", 2, false}, + {1, "tokyo.jp", 2, false}, + {1, "tottori.jp", 2, false}, + {1, "toyama.jp", 2, false}, + {1, "wakayama.jp", 2, false}, + {1, "yamagata.jp", 2, false}, + {1, "yamaguchi.jp", 2, false}, + {1, "yamanashi.jp", 2, false}, + {1, "xn--4pvxs.jp", 2, false}, + {1, "xn--vgu402c.jp", 2, false}, + {1, "xn--c3s14m.jp", 2, false}, + {1, "xn--f6qx53a.jp", 2, false}, + {1, "xn--8pvr4u.jp", 2, false}, + {1, "xn--uist22h.jp", 2, false}, + {1, "xn--djrs72d6uy.jp", 2, false}, + {1, "xn--mkru45i.jp", 2, false}, + {1, "xn--0trq7p7nn.jp", 2, false}, + {1, "xn--8ltr62k.jp", 2, false}, + {1, "xn--2m4a15e.jp", 2, false}, + {1, "xn--efvn9s.jp", 2, false}, + {1, "xn--32vp30h.jp", 2, false}, + {1, "xn--4it797k.jp", 2, false}, + {1, "xn--1lqs71d.jp", 2, false}, + {1, "xn--5rtp49c.jp", 2, false}, + {1, "xn--5js045d.jp", 2, false}, + {1, "xn--ehqz56n.jp", 2, false}, + {1, "xn--1lqs03n.jp", 2, false}, + {1, "xn--qqqt11m.jp", 2, false}, + {1, "xn--kbrq7o.jp", 2, false}, + {1, "xn--pssu33l.jp", 2, false}, + {1, "xn--ntsq17g.jp", 2, false}, + {1, "xn--uisz3g.jp", 2, false}, + {1, "xn--6btw5a.jp", 2, false}, + {1, "xn--1ctwo.jp", 2, false}, + {1, "xn--6orx2r.jp", 2, false}, + {1, "xn--rht61e.jp", 2, false}, + {1, "xn--rht27z.jp", 2, false}, + {1, "xn--djty4k.jp", 2, false}, + {1, "xn--nit225k.jp", 2, false}, + {1, "xn--rht3d.jp", 2, false}, + {1, "xn--klty5x.jp", 2, false}, + {1, "xn--kltx9a.jp", 2, false}, + {1, "xn--kltp7d.jp", 2, false}, + {1, "xn--uuwu58a.jp", 2, false}, + {1, "xn--zbx025d.jp", 2, false}, + {1, "xn--ntso0iqx3a.jp", 2, false}, + {1, "xn--elqq16h.jp", 2, false}, + {1, "xn--4it168d.jp", 2, false}, + {1, "xn--klt787d.jp", 2, false}, + {1, "xn--rny31h.jp", 2, false}, + {1, "xn--7t0a264c.jp", 2, false}, + {1, "xn--5rtq34k.jp", 2, false}, + {1, "xn--k7yn95e.jp", 2, false}, + {1, "xn--tor131o.jp", 2, false}, + {1, "xn--d5qv7z876c.jp", 2, false}, + {2, "kawasaki.jp", 3, false}, + {2, "kitakyushu.jp", 3, false}, + {2, "kobe.jp", 3, false}, + {2, "nagoya.jp", 3, false}, + {2, "sapporo.jp", 3, false}, + {2, "sendai.jp", 3, false}, + {2, "yokohama.jp", 3, false}, + {3, "city.kawasaki.jp", 3, false}, + {3, "city.kitakyushu.jp", 3, false}, + {3, "city.kobe.jp", 3, false}, + {3, "city.nagoya.jp", 3, false}, + {3, "city.sapporo.jp", 3, false}, + {3, "city.sendai.jp", 3, false}, + {3, "city.yokohama.jp", 3, false}, + {1, "aisai.aichi.jp", 3, false}, + {1, "ama.aichi.jp", 3, false}, + {1, "anjo.aichi.jp", 3, false}, + {1, "asuke.aichi.jp", 3, false}, + {1, "chiryu.aichi.jp", 3, false}, + {1, "chita.aichi.jp", 3, false}, + {1, "fuso.aichi.jp", 3, false}, + {1, "gamagori.aichi.jp", 3, false}, + {1, "handa.aichi.jp", 3, false}, + {1, "hazu.aichi.jp", 3, false}, + {1, "hekinan.aichi.jp", 3, false}, + {1, "higashiura.aichi.jp", 3, false}, + {1, "ichinomiya.aichi.jp", 3, false}, + {1, "inazawa.aichi.jp", 3, false}, + {1, "inuyama.aichi.jp", 3, false}, + {1, "isshiki.aichi.jp", 3, false}, + {1, "iwakura.aichi.jp", 3, false}, + {1, "kanie.aichi.jp", 3, false}, + {1, "kariya.aichi.jp", 3, false}, + {1, "kasugai.aichi.jp", 3, false}, + {1, "kira.aichi.jp", 3, false}, + {1, "kiyosu.aichi.jp", 3, false}, + {1, "komaki.aichi.jp", 3, false}, + {1, "konan.aichi.jp", 3, false}, + {1, "kota.aichi.jp", 3, false}, + {1, "mihama.aichi.jp", 3, false}, + {1, "miyoshi.aichi.jp", 3, false}, + {1, "nishio.aichi.jp", 3, false}, + {1, "nisshin.aichi.jp", 3, false}, + {1, "obu.aichi.jp", 3, false}, + {1, "oguchi.aichi.jp", 3, false}, + {1, "oharu.aichi.jp", 3, false}, + {1, "okazaki.aichi.jp", 3, false}, + {1, "owariasahi.aichi.jp", 3, false}, + {1, "seto.aichi.jp", 3, false}, + {1, "shikatsu.aichi.jp", 3, false}, + {1, "shinshiro.aichi.jp", 3, false}, + {1, "shitara.aichi.jp", 3, false}, + {1, "tahara.aichi.jp", 3, false}, + {1, "takahama.aichi.jp", 3, false}, + {1, "tobishima.aichi.jp", 3, false}, + {1, "toei.aichi.jp", 3, false}, + {1, "togo.aichi.jp", 3, false}, + {1, "tokai.aichi.jp", 3, false}, + {1, "tokoname.aichi.jp", 3, false}, + {1, "toyoake.aichi.jp", 3, false}, + {1, "toyohashi.aichi.jp", 3, false}, + {1, "toyokawa.aichi.jp", 3, false}, + {1, "toyone.aichi.jp", 3, false}, + {1, "toyota.aichi.jp", 3, false}, + {1, "tsushima.aichi.jp", 3, false}, + {1, "yatomi.aichi.jp", 3, false}, + {1, "akita.akita.jp", 3, false}, + {1, "daisen.akita.jp", 3, false}, + {1, "fujisato.akita.jp", 3, false}, + {1, "gojome.akita.jp", 3, false}, + {1, "hachirogata.akita.jp", 3, false}, + {1, "happou.akita.jp", 3, false}, + {1, "higashinaruse.akita.jp", 3, false}, + {1, "honjo.akita.jp", 3, false}, + {1, "honjyo.akita.jp", 3, false}, + {1, "ikawa.akita.jp", 3, false}, + {1, "kamikoani.akita.jp", 3, false}, + {1, "kamioka.akita.jp", 3, false}, + {1, "katagami.akita.jp", 3, false}, + {1, "kazuno.akita.jp", 3, false}, + {1, "kitaakita.akita.jp", 3, false}, + {1, "kosaka.akita.jp", 3, false}, + {1, "kyowa.akita.jp", 3, false}, + {1, "misato.akita.jp", 3, false}, + {1, "mitane.akita.jp", 3, false}, + {1, "moriyoshi.akita.jp", 3, false}, + {1, "nikaho.akita.jp", 3, false}, + {1, "noshiro.akita.jp", 3, false}, + {1, "odate.akita.jp", 3, false}, + {1, "oga.akita.jp", 3, false}, + {1, "ogata.akita.jp", 3, false}, + {1, "semboku.akita.jp", 3, false}, + {1, "yokote.akita.jp", 3, false}, + {1, "yurihonjo.akita.jp", 3, false}, + {1, "aomori.aomori.jp", 3, false}, + {1, "gonohe.aomori.jp", 3, false}, + {1, "hachinohe.aomori.jp", 3, false}, + {1, "hashikami.aomori.jp", 3, false}, + {1, "hiranai.aomori.jp", 3, false}, + {1, "hirosaki.aomori.jp", 3, false}, + {1, "itayanagi.aomori.jp", 3, false}, + {1, "kuroishi.aomori.jp", 3, false}, + {1, "misawa.aomori.jp", 3, false}, + {1, "mutsu.aomori.jp", 3, false}, + {1, "nakadomari.aomori.jp", 3, false}, + {1, "noheji.aomori.jp", 3, false}, + {1, "oirase.aomori.jp", 3, false}, + {1, "owani.aomori.jp", 3, false}, + {1, "rokunohe.aomori.jp", 3, false}, + {1, "sannohe.aomori.jp", 3, false}, + {1, "shichinohe.aomori.jp", 3, false}, + {1, "shingo.aomori.jp", 3, false}, + {1, "takko.aomori.jp", 3, false}, + {1, "towada.aomori.jp", 3, false}, + {1, "tsugaru.aomori.jp", 3, false}, + {1, "tsuruta.aomori.jp", 3, false}, + {1, "abiko.chiba.jp", 3, false}, + {1, "asahi.chiba.jp", 3, false}, + {1, "chonan.chiba.jp", 3, false}, + {1, "chosei.chiba.jp", 3, false}, + {1, "choshi.chiba.jp", 3, false}, + {1, "chuo.chiba.jp", 3, false}, + {1, "funabashi.chiba.jp", 3, false}, + {1, "futtsu.chiba.jp", 3, false}, + {1, "hanamigawa.chiba.jp", 3, false}, + {1, "ichihara.chiba.jp", 3, false}, + {1, "ichikawa.chiba.jp", 3, false}, + {1, "ichinomiya.chiba.jp", 3, false}, + {1, "inzai.chiba.jp", 3, false}, + {1, "isumi.chiba.jp", 3, false}, + {1, "kamagaya.chiba.jp", 3, false}, + {1, "kamogawa.chiba.jp", 3, false}, + {1, "kashiwa.chiba.jp", 3, false}, + {1, "katori.chiba.jp", 3, false}, + {1, "katsuura.chiba.jp", 3, false}, + {1, "kimitsu.chiba.jp", 3, false}, + {1, "kisarazu.chiba.jp", 3, false}, + {1, "kozaki.chiba.jp", 3, false}, + {1, "kujukuri.chiba.jp", 3, false}, + {1, "kyonan.chiba.jp", 3, false}, + {1, "matsudo.chiba.jp", 3, false}, + {1, "midori.chiba.jp", 3, false}, + {1, "mihama.chiba.jp", 3, false}, + {1, "minamiboso.chiba.jp", 3, false}, + {1, "mobara.chiba.jp", 3, false}, + {1, "mutsuzawa.chiba.jp", 3, false}, + {1, "nagara.chiba.jp", 3, false}, + {1, "nagareyama.chiba.jp", 3, false}, + {1, "narashino.chiba.jp", 3, false}, + {1, "narita.chiba.jp", 3, false}, + {1, "noda.chiba.jp", 3, false}, + {1, "oamishirasato.chiba.jp", 3, false}, + {1, "omigawa.chiba.jp", 3, false}, + {1, "onjuku.chiba.jp", 3, false}, + {1, "otaki.chiba.jp", 3, false}, + {1, "sakae.chiba.jp", 3, false}, + {1, "sakura.chiba.jp", 3, false}, + {1, "shimofusa.chiba.jp", 3, false}, + {1, "shirako.chiba.jp", 3, false}, + {1, "shiroi.chiba.jp", 3, false}, + {1, "shisui.chiba.jp", 3, false}, + {1, "sodegaura.chiba.jp", 3, false}, + {1, "sosa.chiba.jp", 3, false}, + {1, "tako.chiba.jp", 3, false}, + {1, "tateyama.chiba.jp", 3, false}, + {1, "togane.chiba.jp", 3, false}, + {1, "tohnosho.chiba.jp", 3, false}, + {1, "tomisato.chiba.jp", 3, false}, + {1, "urayasu.chiba.jp", 3, false}, + {1, "yachimata.chiba.jp", 3, false}, + {1, "yachiyo.chiba.jp", 3, false}, + {1, "yokaichiba.chiba.jp", 3, false}, + {1, "yokoshibahikari.chiba.jp", 3, false}, + {1, "yotsukaido.chiba.jp", 3, false}, + {1, "ainan.ehime.jp", 3, false}, + {1, "honai.ehime.jp", 3, false}, + {1, "ikata.ehime.jp", 3, false}, + {1, "imabari.ehime.jp", 3, false}, + {1, "iyo.ehime.jp", 3, false}, + {1, "kamijima.ehime.jp", 3, false}, + {1, "kihoku.ehime.jp", 3, false}, + {1, "kumakogen.ehime.jp", 3, false}, + {1, "masaki.ehime.jp", 3, false}, + {1, "matsuno.ehime.jp", 3, false}, + {1, "matsuyama.ehime.jp", 3, false}, + {1, "namikata.ehime.jp", 3, false}, + {1, "niihama.ehime.jp", 3, false}, + {1, "ozu.ehime.jp", 3, false}, + {1, "saijo.ehime.jp", 3, false}, + {1, "seiyo.ehime.jp", 3, false}, + {1, "shikokuchuo.ehime.jp", 3, false}, + {1, "tobe.ehime.jp", 3, false}, + {1, "toon.ehime.jp", 3, false}, + {1, "uchiko.ehime.jp", 3, false}, + {1, "uwajima.ehime.jp", 3, false}, + {1, "yawatahama.ehime.jp", 3, false}, + {1, "echizen.fukui.jp", 3, false}, + {1, "eiheiji.fukui.jp", 3, false}, + {1, "fukui.fukui.jp", 3, false}, + {1, "ikeda.fukui.jp", 3, false}, + {1, "katsuyama.fukui.jp", 3, false}, + {1, "mihama.fukui.jp", 3, false}, + {1, "minamiechizen.fukui.jp", 3, false}, + {1, "obama.fukui.jp", 3, false}, + {1, "ohi.fukui.jp", 3, false}, + {1, "ono.fukui.jp", 3, false}, + {1, "sabae.fukui.jp", 3, false}, + {1, "sakai.fukui.jp", 3, false}, + {1, "takahama.fukui.jp", 3, false}, + {1, "tsuruga.fukui.jp", 3, false}, + {1, "wakasa.fukui.jp", 3, false}, + {1, "ashiya.fukuoka.jp", 3, false}, + {1, "buzen.fukuoka.jp", 3, false}, + {1, "chikugo.fukuoka.jp", 3, false}, + {1, "chikuho.fukuoka.jp", 3, false}, + {1, "chikujo.fukuoka.jp", 3, false}, + {1, "chikushino.fukuoka.jp", 3, false}, + {1, "chikuzen.fukuoka.jp", 3, false}, + {1, "chuo.fukuoka.jp", 3, false}, + {1, "dazaifu.fukuoka.jp", 3, false}, + {1, "fukuchi.fukuoka.jp", 3, false}, + {1, "hakata.fukuoka.jp", 3, false}, + {1, "higashi.fukuoka.jp", 3, false}, + {1, "hirokawa.fukuoka.jp", 3, false}, + {1, "hisayama.fukuoka.jp", 3, false}, + {1, "iizuka.fukuoka.jp", 3, false}, + {1, "inatsuki.fukuoka.jp", 3, false}, + {1, "kaho.fukuoka.jp", 3, false}, + {1, "kasuga.fukuoka.jp", 3, false}, + {1, "kasuya.fukuoka.jp", 3, false}, + {1, "kawara.fukuoka.jp", 3, false}, + {1, "keisen.fukuoka.jp", 3, false}, + {1, "koga.fukuoka.jp", 3, false}, + {1, "kurate.fukuoka.jp", 3, false}, + {1, "kurogi.fukuoka.jp", 3, false}, + {1, "kurume.fukuoka.jp", 3, false}, + {1, "minami.fukuoka.jp", 3, false}, + {1, "miyako.fukuoka.jp", 3, false}, + {1, "miyama.fukuoka.jp", 3, false}, + {1, "miyawaka.fukuoka.jp", 3, false}, + {1, "mizumaki.fukuoka.jp", 3, false}, + {1, "munakata.fukuoka.jp", 3, false}, + {1, "nakagawa.fukuoka.jp", 3, false}, + {1, "nakama.fukuoka.jp", 3, false}, + {1, "nishi.fukuoka.jp", 3, false}, + {1, "nogata.fukuoka.jp", 3, false}, + {1, "ogori.fukuoka.jp", 3, false}, + {1, "okagaki.fukuoka.jp", 3, false}, + {1, "okawa.fukuoka.jp", 3, false}, + {1, "oki.fukuoka.jp", 3, false}, + {1, "omuta.fukuoka.jp", 3, false}, + {1, "onga.fukuoka.jp", 3, false}, + {1, "onojo.fukuoka.jp", 3, false}, + {1, "oto.fukuoka.jp", 3, false}, + {1, "saigawa.fukuoka.jp", 3, false}, + {1, "sasaguri.fukuoka.jp", 3, false}, + {1, "shingu.fukuoka.jp", 3, false}, + {1, "shinyoshitomi.fukuoka.jp", 3, false}, + {1, "shonai.fukuoka.jp", 3, false}, + {1, "soeda.fukuoka.jp", 3, false}, + {1, "sue.fukuoka.jp", 3, false}, + {1, "tachiarai.fukuoka.jp", 3, false}, + {1, "tagawa.fukuoka.jp", 3, false}, + {1, "takata.fukuoka.jp", 3, false}, + {1, "toho.fukuoka.jp", 3, false}, + {1, "toyotsu.fukuoka.jp", 3, false}, + {1, "tsuiki.fukuoka.jp", 3, false}, + {1, "ukiha.fukuoka.jp", 3, false}, + {1, "umi.fukuoka.jp", 3, false}, + {1, "usui.fukuoka.jp", 3, false}, + {1, "yamada.fukuoka.jp", 3, false}, + {1, "yame.fukuoka.jp", 3, false}, + {1, "yanagawa.fukuoka.jp", 3, false}, + {1, "yukuhashi.fukuoka.jp", 3, false}, + {1, "aizubange.fukushima.jp", 3, false}, + {1, "aizumisato.fukushima.jp", 3, false}, + {1, "aizuwakamatsu.fukushima.jp", 3, false}, + {1, "asakawa.fukushima.jp", 3, false}, + {1, "bandai.fukushima.jp", 3, false}, + {1, "date.fukushima.jp", 3, false}, + {1, "fukushima.fukushima.jp", 3, false}, + {1, "furudono.fukushima.jp", 3, false}, + {1, "futaba.fukushima.jp", 3, false}, + {1, "hanawa.fukushima.jp", 3, false}, + {1, "higashi.fukushima.jp", 3, false}, + {1, "hirata.fukushima.jp", 3, false}, + {1, "hirono.fukushima.jp", 3, false}, + {1, "iitate.fukushima.jp", 3, false}, + {1, "inawashiro.fukushima.jp", 3, false}, + {1, "ishikawa.fukushima.jp", 3, false}, + {1, "iwaki.fukushima.jp", 3, false}, + {1, "izumizaki.fukushima.jp", 3, false}, + {1, "kagamiishi.fukushima.jp", 3, false}, + {1, "kaneyama.fukushima.jp", 3, false}, + {1, "kawamata.fukushima.jp", 3, false}, + {1, "kitakata.fukushima.jp", 3, false}, + {1, "kitashiobara.fukushima.jp", 3, false}, + {1, "koori.fukushima.jp", 3, false}, + {1, "koriyama.fukushima.jp", 3, false}, + {1, "kunimi.fukushima.jp", 3, false}, + {1, "miharu.fukushima.jp", 3, false}, + {1, "mishima.fukushima.jp", 3, false}, + {1, "namie.fukushima.jp", 3, false}, + {1, "nango.fukushima.jp", 3, false}, + {1, "nishiaizu.fukushima.jp", 3, false}, + {1, "nishigo.fukushima.jp", 3, false}, + {1, "okuma.fukushima.jp", 3, false}, + {1, "omotego.fukushima.jp", 3, false}, + {1, "ono.fukushima.jp", 3, false}, + {1, "otama.fukushima.jp", 3, false}, + {1, "samegawa.fukushima.jp", 3, false}, + {1, "shimogo.fukushima.jp", 3, false}, + {1, "shirakawa.fukushima.jp", 3, false}, + {1, "showa.fukushima.jp", 3, false}, + {1, "soma.fukushima.jp", 3, false}, + {1, "sukagawa.fukushima.jp", 3, false}, + {1, "taishin.fukushima.jp", 3, false}, + {1, "tamakawa.fukushima.jp", 3, false}, + {1, "tanagura.fukushima.jp", 3, false}, + {1, "tenei.fukushima.jp", 3, false}, + {1, "yabuki.fukushima.jp", 3, false}, + {1, "yamato.fukushima.jp", 3, false}, + {1, "yamatsuri.fukushima.jp", 3, false}, + {1, "yanaizu.fukushima.jp", 3, false}, + {1, "yugawa.fukushima.jp", 3, false}, + {1, "anpachi.gifu.jp", 3, false}, + {1, "ena.gifu.jp", 3, false}, + {1, "gifu.gifu.jp", 3, false}, + {1, "ginan.gifu.jp", 3, false}, + {1, "godo.gifu.jp", 3, false}, + {1, "gujo.gifu.jp", 3, false}, + {1, "hashima.gifu.jp", 3, false}, + {1, "hichiso.gifu.jp", 3, false}, + {1, "hida.gifu.jp", 3, false}, + {1, "higashishirakawa.gifu.jp", 3, false}, + {1, "ibigawa.gifu.jp", 3, false}, + {1, "ikeda.gifu.jp", 3, false}, + {1, "kakamigahara.gifu.jp", 3, false}, + {1, "kani.gifu.jp", 3, false}, + {1, "kasahara.gifu.jp", 3, false}, + {1, "kasamatsu.gifu.jp", 3, false}, + {1, "kawaue.gifu.jp", 3, false}, + {1, "kitagata.gifu.jp", 3, false}, + {1, "mino.gifu.jp", 3, false}, + {1, "minokamo.gifu.jp", 3, false}, + {1, "mitake.gifu.jp", 3, false}, + {1, "mizunami.gifu.jp", 3, false}, + {1, "motosu.gifu.jp", 3, false}, + {1, "nakatsugawa.gifu.jp", 3, false}, + {1, "ogaki.gifu.jp", 3, false}, + {1, "sakahogi.gifu.jp", 3, false}, + {1, "seki.gifu.jp", 3, false}, + {1, "sekigahara.gifu.jp", 3, false}, + {1, "shirakawa.gifu.jp", 3, false}, + {1, "tajimi.gifu.jp", 3, false}, + {1, "takayama.gifu.jp", 3, false}, + {1, "tarui.gifu.jp", 3, false}, + {1, "toki.gifu.jp", 3, false}, + {1, "tomika.gifu.jp", 3, false}, + {1, "wanouchi.gifu.jp", 3, false}, + {1, "yamagata.gifu.jp", 3, false}, + {1, "yaotsu.gifu.jp", 3, false}, + {1, "yoro.gifu.jp", 3, false}, + {1, "annaka.gunma.jp", 3, false}, + {1, "chiyoda.gunma.jp", 3, false}, + {1, "fujioka.gunma.jp", 3, false}, + {1, "higashiagatsuma.gunma.jp", 3, false}, + {1, "isesaki.gunma.jp", 3, false}, + {1, "itakura.gunma.jp", 3, false}, + {1, "kanna.gunma.jp", 3, false}, + {1, "kanra.gunma.jp", 3, false}, + {1, "katashina.gunma.jp", 3, false}, + {1, "kawaba.gunma.jp", 3, false}, + {1, "kiryu.gunma.jp", 3, false}, + {1, "kusatsu.gunma.jp", 3, false}, + {1, "maebashi.gunma.jp", 3, false}, + {1, "meiwa.gunma.jp", 3, false}, + {1, "midori.gunma.jp", 3, false}, + {1, "minakami.gunma.jp", 3, false}, + {1, "naganohara.gunma.jp", 3, false}, + {1, "nakanojo.gunma.jp", 3, false}, + {1, "nanmoku.gunma.jp", 3, false}, + {1, "numata.gunma.jp", 3, false}, + {1, "oizumi.gunma.jp", 3, false}, + {1, "ora.gunma.jp", 3, false}, + {1, "ota.gunma.jp", 3, false}, + {1, "shibukawa.gunma.jp", 3, false}, + {1, "shimonita.gunma.jp", 3, false}, + {1, "shinto.gunma.jp", 3, false}, + {1, "showa.gunma.jp", 3, false}, + {1, "takasaki.gunma.jp", 3, false}, + {1, "takayama.gunma.jp", 3, false}, + {1, "tamamura.gunma.jp", 3, false}, + {1, "tatebayashi.gunma.jp", 3, false}, + {1, "tomioka.gunma.jp", 3, false}, + {1, "tsukiyono.gunma.jp", 3, false}, + {1, "tsumagoi.gunma.jp", 3, false}, + {1, "ueno.gunma.jp", 3, false}, + {1, "yoshioka.gunma.jp", 3, false}, + {1, "asaminami.hiroshima.jp", 3, false}, + {1, "daiwa.hiroshima.jp", 3, false}, + {1, "etajima.hiroshima.jp", 3, false}, + {1, "fuchu.hiroshima.jp", 3, false}, + {1, "fukuyama.hiroshima.jp", 3, false}, + {1, "hatsukaichi.hiroshima.jp", 3, false}, + {1, "higashihiroshima.hiroshima.jp", 3, false}, + {1, "hongo.hiroshima.jp", 3, false}, + {1, "jinsekikogen.hiroshima.jp", 3, false}, + {1, "kaita.hiroshima.jp", 3, false}, + {1, "kui.hiroshima.jp", 3, false}, + {1, "kumano.hiroshima.jp", 3, false}, + {1, "kure.hiroshima.jp", 3, false}, + {1, "mihara.hiroshima.jp", 3, false}, + {1, "miyoshi.hiroshima.jp", 3, false}, + {1, "naka.hiroshima.jp", 3, false}, + {1, "onomichi.hiroshima.jp", 3, false}, + {1, "osakikamijima.hiroshima.jp", 3, false}, + {1, "otake.hiroshima.jp", 3, false}, + {1, "saka.hiroshima.jp", 3, false}, + {1, "sera.hiroshima.jp", 3, false}, + {1, "seranishi.hiroshima.jp", 3, false}, + {1, "shinichi.hiroshima.jp", 3, false}, + {1, "shobara.hiroshima.jp", 3, false}, + {1, "takehara.hiroshima.jp", 3, false}, + {1, "abashiri.hokkaido.jp", 3, false}, + {1, "abira.hokkaido.jp", 3, false}, + {1, "aibetsu.hokkaido.jp", 3, false}, + {1, "akabira.hokkaido.jp", 3, false}, + {1, "akkeshi.hokkaido.jp", 3, false}, + {1, "asahikawa.hokkaido.jp", 3, false}, + {1, "ashibetsu.hokkaido.jp", 3, false}, + {1, "ashoro.hokkaido.jp", 3, false}, + {1, "assabu.hokkaido.jp", 3, false}, + {1, "atsuma.hokkaido.jp", 3, false}, + {1, "bibai.hokkaido.jp", 3, false}, + {1, "biei.hokkaido.jp", 3, false}, + {1, "bifuka.hokkaido.jp", 3, false}, + {1, "bihoro.hokkaido.jp", 3, false}, + {1, "biratori.hokkaido.jp", 3, false}, + {1, "chippubetsu.hokkaido.jp", 3, false}, + {1, "chitose.hokkaido.jp", 3, false}, + {1, "date.hokkaido.jp", 3, false}, + {1, "ebetsu.hokkaido.jp", 3, false}, + {1, "embetsu.hokkaido.jp", 3, false}, + {1, "eniwa.hokkaido.jp", 3, false}, + {1, "erimo.hokkaido.jp", 3, false}, + {1, "esan.hokkaido.jp", 3, false}, + {1, "esashi.hokkaido.jp", 3, false}, + {1, "fukagawa.hokkaido.jp", 3, false}, + {1, "fukushima.hokkaido.jp", 3, false}, + {1, "furano.hokkaido.jp", 3, false}, + {1, "furubira.hokkaido.jp", 3, false}, + {1, "haboro.hokkaido.jp", 3, false}, + {1, "hakodate.hokkaido.jp", 3, false}, + {1, "hamatonbetsu.hokkaido.jp", 3, false}, + {1, "hidaka.hokkaido.jp", 3, false}, + {1, "higashikagura.hokkaido.jp", 3, false}, + {1, "higashikawa.hokkaido.jp", 3, false}, + {1, "hiroo.hokkaido.jp", 3, false}, + {1, "hokuryu.hokkaido.jp", 3, false}, + {1, "hokuto.hokkaido.jp", 3, false}, + {1, "honbetsu.hokkaido.jp", 3, false}, + {1, "horokanai.hokkaido.jp", 3, false}, + {1, "horonobe.hokkaido.jp", 3, false}, + {1, "ikeda.hokkaido.jp", 3, false}, + {1, "imakane.hokkaido.jp", 3, false}, + {1, "ishikari.hokkaido.jp", 3, false}, + {1, "iwamizawa.hokkaido.jp", 3, false}, + {1, "iwanai.hokkaido.jp", 3, false}, + {1, "kamifurano.hokkaido.jp", 3, false}, + {1, "kamikawa.hokkaido.jp", 3, false}, + {1, "kamishihoro.hokkaido.jp", 3, false}, + {1, "kamisunagawa.hokkaido.jp", 3, false}, + {1, "kamoenai.hokkaido.jp", 3, false}, + {1, "kayabe.hokkaido.jp", 3, false}, + {1, "kembuchi.hokkaido.jp", 3, false}, + {1, "kikonai.hokkaido.jp", 3, false}, + {1, "kimobetsu.hokkaido.jp", 3, false}, + {1, "kitahiroshima.hokkaido.jp", 3, false}, + {1, "kitami.hokkaido.jp", 3, false}, + {1, "kiyosato.hokkaido.jp", 3, false}, + {1, "koshimizu.hokkaido.jp", 3, false}, + {1, "kunneppu.hokkaido.jp", 3, false}, + {1, "kuriyama.hokkaido.jp", 3, false}, + {1, "kuromatsunai.hokkaido.jp", 3, false}, + {1, "kushiro.hokkaido.jp", 3, false}, + {1, "kutchan.hokkaido.jp", 3, false}, + {1, "kyowa.hokkaido.jp", 3, false}, + {1, "mashike.hokkaido.jp", 3, false}, + {1, "matsumae.hokkaido.jp", 3, false}, + {1, "mikasa.hokkaido.jp", 3, false}, + {1, "minamifurano.hokkaido.jp", 3, false}, + {1, "mombetsu.hokkaido.jp", 3, false}, + {1, "moseushi.hokkaido.jp", 3, false}, + {1, "mukawa.hokkaido.jp", 3, false}, + {1, "muroran.hokkaido.jp", 3, false}, + {1, "naie.hokkaido.jp", 3, false}, + {1, "nakagawa.hokkaido.jp", 3, false}, + {1, "nakasatsunai.hokkaido.jp", 3, false}, + {1, "nakatombetsu.hokkaido.jp", 3, false}, + {1, "nanae.hokkaido.jp", 3, false}, + {1, "nanporo.hokkaido.jp", 3, false}, + {1, "nayoro.hokkaido.jp", 3, false}, + {1, "nemuro.hokkaido.jp", 3, false}, + {1, "niikappu.hokkaido.jp", 3, false}, + {1, "niki.hokkaido.jp", 3, false}, + {1, "nishiokoppe.hokkaido.jp", 3, false}, + {1, "noboribetsu.hokkaido.jp", 3, false}, + {1, "numata.hokkaido.jp", 3, false}, + {1, "obihiro.hokkaido.jp", 3, false}, + {1, "obira.hokkaido.jp", 3, false}, + {1, "oketo.hokkaido.jp", 3, false}, + {1, "okoppe.hokkaido.jp", 3, false}, + {1, "otaru.hokkaido.jp", 3, false}, + {1, "otobe.hokkaido.jp", 3, false}, + {1, "otofuke.hokkaido.jp", 3, false}, + {1, "otoineppu.hokkaido.jp", 3, false}, + {1, "oumu.hokkaido.jp", 3, false}, + {1, "ozora.hokkaido.jp", 3, false}, + {1, "pippu.hokkaido.jp", 3, false}, + {1, "rankoshi.hokkaido.jp", 3, false}, + {1, "rebun.hokkaido.jp", 3, false}, + {1, "rikubetsu.hokkaido.jp", 3, false}, + {1, "rishiri.hokkaido.jp", 3, false}, + {1, "rishirifuji.hokkaido.jp", 3, false}, + {1, "saroma.hokkaido.jp", 3, false}, + {1, "sarufutsu.hokkaido.jp", 3, false}, + {1, "shakotan.hokkaido.jp", 3, false}, + {1, "shari.hokkaido.jp", 3, false}, + {1, "shibecha.hokkaido.jp", 3, false}, + {1, "shibetsu.hokkaido.jp", 3, false}, + {1, "shikabe.hokkaido.jp", 3, false}, + {1, "shikaoi.hokkaido.jp", 3, false}, + {1, "shimamaki.hokkaido.jp", 3, false}, + {1, "shimizu.hokkaido.jp", 3, false}, + {1, "shimokawa.hokkaido.jp", 3, false}, + {1, "shinshinotsu.hokkaido.jp", 3, false}, + {1, "shintoku.hokkaido.jp", 3, false}, + {1, "shiranuka.hokkaido.jp", 3, false}, + {1, "shiraoi.hokkaido.jp", 3, false}, + {1, "shiriuchi.hokkaido.jp", 3, false}, + {1, "sobetsu.hokkaido.jp", 3, false}, + {1, "sunagawa.hokkaido.jp", 3, false}, + {1, "taiki.hokkaido.jp", 3, false}, + {1, "takasu.hokkaido.jp", 3, false}, + {1, "takikawa.hokkaido.jp", 3, false}, + {1, "takinoue.hokkaido.jp", 3, false}, + {1, "teshikaga.hokkaido.jp", 3, false}, + {1, "tobetsu.hokkaido.jp", 3, false}, + {1, "tohma.hokkaido.jp", 3, false}, + {1, "tomakomai.hokkaido.jp", 3, false}, + {1, "tomari.hokkaido.jp", 3, false}, + {1, "toya.hokkaido.jp", 3, false}, + {1, "toyako.hokkaido.jp", 3, false}, + {1, "toyotomi.hokkaido.jp", 3, false}, + {1, "toyoura.hokkaido.jp", 3, false}, + {1, "tsubetsu.hokkaido.jp", 3, false}, + {1, "tsukigata.hokkaido.jp", 3, false}, + {1, "urakawa.hokkaido.jp", 3, false}, + {1, "urausu.hokkaido.jp", 3, false}, + {1, "uryu.hokkaido.jp", 3, false}, + {1, "utashinai.hokkaido.jp", 3, false}, + {1, "wakkanai.hokkaido.jp", 3, false}, + {1, "wassamu.hokkaido.jp", 3, false}, + {1, "yakumo.hokkaido.jp", 3, false}, + {1, "yoichi.hokkaido.jp", 3, false}, + {1, "aioi.hyogo.jp", 3, false}, + {1, "akashi.hyogo.jp", 3, false}, + {1, "ako.hyogo.jp", 3, false}, + {1, "amagasaki.hyogo.jp", 3, false}, + {1, "aogaki.hyogo.jp", 3, false}, + {1, "asago.hyogo.jp", 3, false}, + {1, "ashiya.hyogo.jp", 3, false}, + {1, "awaji.hyogo.jp", 3, false}, + {1, "fukusaki.hyogo.jp", 3, false}, + {1, "goshiki.hyogo.jp", 3, false}, + {1, "harima.hyogo.jp", 3, false}, + {1, "himeji.hyogo.jp", 3, false}, + {1, "ichikawa.hyogo.jp", 3, false}, + {1, "inagawa.hyogo.jp", 3, false}, + {1, "itami.hyogo.jp", 3, false}, + {1, "kakogawa.hyogo.jp", 3, false}, + {1, "kamigori.hyogo.jp", 3, false}, + {1, "kamikawa.hyogo.jp", 3, false}, + {1, "kasai.hyogo.jp", 3, false}, + {1, "kasuga.hyogo.jp", 3, false}, + {1, "kawanishi.hyogo.jp", 3, false}, + {1, "miki.hyogo.jp", 3, false}, + {1, "minamiawaji.hyogo.jp", 3, false}, + {1, "nishinomiya.hyogo.jp", 3, false}, + {1, "nishiwaki.hyogo.jp", 3, false}, + {1, "ono.hyogo.jp", 3, false}, + {1, "sanda.hyogo.jp", 3, false}, + {1, "sannan.hyogo.jp", 3, false}, + {1, "sasayama.hyogo.jp", 3, false}, + {1, "sayo.hyogo.jp", 3, false}, + {1, "shingu.hyogo.jp", 3, false}, + {1, "shinonsen.hyogo.jp", 3, false}, + {1, "shiso.hyogo.jp", 3, false}, + {1, "sumoto.hyogo.jp", 3, false}, + {1, "taishi.hyogo.jp", 3, false}, + {1, "taka.hyogo.jp", 3, false}, + {1, "takarazuka.hyogo.jp", 3, false}, + {1, "takasago.hyogo.jp", 3, false}, + {1, "takino.hyogo.jp", 3, false}, + {1, "tamba.hyogo.jp", 3, false}, + {1, "tatsuno.hyogo.jp", 3, false}, + {1, "toyooka.hyogo.jp", 3, false}, + {1, "yabu.hyogo.jp", 3, false}, + {1, "yashiro.hyogo.jp", 3, false}, + {1, "yoka.hyogo.jp", 3, false}, + {1, "yokawa.hyogo.jp", 3, false}, + {1, "ami.ibaraki.jp", 3, false}, + {1, "asahi.ibaraki.jp", 3, false}, + {1, "bando.ibaraki.jp", 3, false}, + {1, "chikusei.ibaraki.jp", 3, false}, + {1, "daigo.ibaraki.jp", 3, false}, + {1, "fujishiro.ibaraki.jp", 3, false}, + {1, "hitachi.ibaraki.jp", 3, false}, + {1, "hitachinaka.ibaraki.jp", 3, false}, + {1, "hitachiomiya.ibaraki.jp", 3, false}, + {1, "hitachiota.ibaraki.jp", 3, false}, + {1, "ibaraki.ibaraki.jp", 3, false}, + {1, "ina.ibaraki.jp", 3, false}, + {1, "inashiki.ibaraki.jp", 3, false}, + {1, "itako.ibaraki.jp", 3, false}, + {1, "iwama.ibaraki.jp", 3, false}, + {1, "joso.ibaraki.jp", 3, false}, + {1, "kamisu.ibaraki.jp", 3, false}, + {1, "kasama.ibaraki.jp", 3, false}, + {1, "kashima.ibaraki.jp", 3, false}, + {1, "kasumigaura.ibaraki.jp", 3, false}, + {1, "koga.ibaraki.jp", 3, false}, + {1, "miho.ibaraki.jp", 3, false}, + {1, "mito.ibaraki.jp", 3, false}, + {1, "moriya.ibaraki.jp", 3, false}, + {1, "naka.ibaraki.jp", 3, false}, + {1, "namegata.ibaraki.jp", 3, false}, + {1, "oarai.ibaraki.jp", 3, false}, + {1, "ogawa.ibaraki.jp", 3, false}, + {1, "omitama.ibaraki.jp", 3, false}, + {1, "ryugasaki.ibaraki.jp", 3, false}, + {1, "sakai.ibaraki.jp", 3, false}, + {1, "sakuragawa.ibaraki.jp", 3, false}, + {1, "shimodate.ibaraki.jp", 3, false}, + {1, "shimotsuma.ibaraki.jp", 3, false}, + {1, "shirosato.ibaraki.jp", 3, false}, + {1, "sowa.ibaraki.jp", 3, false}, + {1, "suifu.ibaraki.jp", 3, false}, + {1, "takahagi.ibaraki.jp", 3, false}, + {1, "tamatsukuri.ibaraki.jp", 3, false}, + {1, "tokai.ibaraki.jp", 3, false}, + {1, "tomobe.ibaraki.jp", 3, false}, + {1, "tone.ibaraki.jp", 3, false}, + {1, "toride.ibaraki.jp", 3, false}, + {1, "tsuchiura.ibaraki.jp", 3, false}, + {1, "tsukuba.ibaraki.jp", 3, false}, + {1, "uchihara.ibaraki.jp", 3, false}, + {1, "ushiku.ibaraki.jp", 3, false}, + {1, "yachiyo.ibaraki.jp", 3, false}, + {1, "yamagata.ibaraki.jp", 3, false}, + {1, "yawara.ibaraki.jp", 3, false}, + {1, "yuki.ibaraki.jp", 3, false}, + {1, "anamizu.ishikawa.jp", 3, false}, + {1, "hakui.ishikawa.jp", 3, false}, + {1, "hakusan.ishikawa.jp", 3, false}, + {1, "kaga.ishikawa.jp", 3, false}, + {1, "kahoku.ishikawa.jp", 3, false}, + {1, "kanazawa.ishikawa.jp", 3, false}, + {1, "kawakita.ishikawa.jp", 3, false}, + {1, "komatsu.ishikawa.jp", 3, false}, + {1, "nakanoto.ishikawa.jp", 3, false}, + {1, "nanao.ishikawa.jp", 3, false}, + {1, "nomi.ishikawa.jp", 3, false}, + {1, "nonoichi.ishikawa.jp", 3, false}, + {1, "noto.ishikawa.jp", 3, false}, + {1, "shika.ishikawa.jp", 3, false}, + {1, "suzu.ishikawa.jp", 3, false}, + {1, "tsubata.ishikawa.jp", 3, false}, + {1, "tsurugi.ishikawa.jp", 3, false}, + {1, "uchinada.ishikawa.jp", 3, false}, + {1, "wajima.ishikawa.jp", 3, false}, + {1, "fudai.iwate.jp", 3, false}, + {1, "fujisawa.iwate.jp", 3, false}, + {1, "hanamaki.iwate.jp", 3, false}, + {1, "hiraizumi.iwate.jp", 3, false}, + {1, "hirono.iwate.jp", 3, false}, + {1, "ichinohe.iwate.jp", 3, false}, + {1, "ichinoseki.iwate.jp", 3, false}, + {1, "iwaizumi.iwate.jp", 3, false}, + {1, "iwate.iwate.jp", 3, false}, + {1, "joboji.iwate.jp", 3, false}, + {1, "kamaishi.iwate.jp", 3, false}, + {1, "kanegasaki.iwate.jp", 3, false}, + {1, "karumai.iwate.jp", 3, false}, + {1, "kawai.iwate.jp", 3, false}, + {1, "kitakami.iwate.jp", 3, false}, + {1, "kuji.iwate.jp", 3, false}, + {1, "kunohe.iwate.jp", 3, false}, + {1, "kuzumaki.iwate.jp", 3, false}, + {1, "miyako.iwate.jp", 3, false}, + {1, "mizusawa.iwate.jp", 3, false}, + {1, "morioka.iwate.jp", 3, false}, + {1, "ninohe.iwate.jp", 3, false}, + {1, "noda.iwate.jp", 3, false}, + {1, "ofunato.iwate.jp", 3, false}, + {1, "oshu.iwate.jp", 3, false}, + {1, "otsuchi.iwate.jp", 3, false}, + {1, "rikuzentakata.iwate.jp", 3, false}, + {1, "shiwa.iwate.jp", 3, false}, + {1, "shizukuishi.iwate.jp", 3, false}, + {1, "sumita.iwate.jp", 3, false}, + {1, "tanohata.iwate.jp", 3, false}, + {1, "tono.iwate.jp", 3, false}, + {1, "yahaba.iwate.jp", 3, false}, + {1, "yamada.iwate.jp", 3, false}, + {1, "ayagawa.kagawa.jp", 3, false}, + {1, "higashikagawa.kagawa.jp", 3, false}, + {1, "kanonji.kagawa.jp", 3, false}, + {1, "kotohira.kagawa.jp", 3, false}, + {1, "manno.kagawa.jp", 3, false}, + {1, "marugame.kagawa.jp", 3, false}, + {1, "mitoyo.kagawa.jp", 3, false}, + {1, "naoshima.kagawa.jp", 3, false}, + {1, "sanuki.kagawa.jp", 3, false}, + {1, "tadotsu.kagawa.jp", 3, false}, + {1, "takamatsu.kagawa.jp", 3, false}, + {1, "tonosho.kagawa.jp", 3, false}, + {1, "uchinomi.kagawa.jp", 3, false}, + {1, "utazu.kagawa.jp", 3, false}, + {1, "zentsuji.kagawa.jp", 3, false}, + {1, "akune.kagoshima.jp", 3, false}, + {1, "amami.kagoshima.jp", 3, false}, + {1, "hioki.kagoshima.jp", 3, false}, + {1, "isa.kagoshima.jp", 3, false}, + {1, "isen.kagoshima.jp", 3, false}, + {1, "izumi.kagoshima.jp", 3, false}, + {1, "kagoshima.kagoshima.jp", 3, false}, + {1, "kanoya.kagoshima.jp", 3, false}, + {1, "kawanabe.kagoshima.jp", 3, false}, + {1, "kinko.kagoshima.jp", 3, false}, + {1, "kouyama.kagoshima.jp", 3, false}, + {1, "makurazaki.kagoshima.jp", 3, false}, + {1, "matsumoto.kagoshima.jp", 3, false}, + {1, "minamitane.kagoshima.jp", 3, false}, + {1, "nakatane.kagoshima.jp", 3, false}, + {1, "nishinoomote.kagoshima.jp", 3, false}, + {1, "satsumasendai.kagoshima.jp", 3, false}, + {1, "soo.kagoshima.jp", 3, false}, + {1, "tarumizu.kagoshima.jp", 3, false}, + {1, "yusui.kagoshima.jp", 3, false}, + {1, "aikawa.kanagawa.jp", 3, false}, + {1, "atsugi.kanagawa.jp", 3, false}, + {1, "ayase.kanagawa.jp", 3, false}, + {1, "chigasaki.kanagawa.jp", 3, false}, + {1, "ebina.kanagawa.jp", 3, false}, + {1, "fujisawa.kanagawa.jp", 3, false}, + {1, "hadano.kanagawa.jp", 3, false}, + {1, "hakone.kanagawa.jp", 3, false}, + {1, "hiratsuka.kanagawa.jp", 3, false}, + {1, "isehara.kanagawa.jp", 3, false}, + {1, "kaisei.kanagawa.jp", 3, false}, + {1, "kamakura.kanagawa.jp", 3, false}, + {1, "kiyokawa.kanagawa.jp", 3, false}, + {1, "matsuda.kanagawa.jp", 3, false}, + {1, "minamiashigara.kanagawa.jp", 3, false}, + {1, "miura.kanagawa.jp", 3, false}, + {1, "nakai.kanagawa.jp", 3, false}, + {1, "ninomiya.kanagawa.jp", 3, false}, + {1, "odawara.kanagawa.jp", 3, false}, + {1, "oi.kanagawa.jp", 3, false}, + {1, "oiso.kanagawa.jp", 3, false}, + {1, "sagamihara.kanagawa.jp", 3, false}, + {1, "samukawa.kanagawa.jp", 3, false}, + {1, "tsukui.kanagawa.jp", 3, false}, + {1, "yamakita.kanagawa.jp", 3, false}, + {1, "yamato.kanagawa.jp", 3, false}, + {1, "yokosuka.kanagawa.jp", 3, false}, + {1, "yugawara.kanagawa.jp", 3, false}, + {1, "zama.kanagawa.jp", 3, false}, + {1, "zushi.kanagawa.jp", 3, false}, + {1, "aki.kochi.jp", 3, false}, + {1, "geisei.kochi.jp", 3, false}, + {1, "hidaka.kochi.jp", 3, false}, + {1, "higashitsuno.kochi.jp", 3, false}, + {1, "ino.kochi.jp", 3, false}, + {1, "kagami.kochi.jp", 3, false}, + {1, "kami.kochi.jp", 3, false}, + {1, "kitagawa.kochi.jp", 3, false}, + {1, "kochi.kochi.jp", 3, false}, + {1, "mihara.kochi.jp", 3, false}, + {1, "motoyama.kochi.jp", 3, false}, + {1, "muroto.kochi.jp", 3, false}, + {1, "nahari.kochi.jp", 3, false}, + {1, "nakamura.kochi.jp", 3, false}, + {1, "nankoku.kochi.jp", 3, false}, + {1, "nishitosa.kochi.jp", 3, false}, + {1, "niyodogawa.kochi.jp", 3, false}, + {1, "ochi.kochi.jp", 3, false}, + {1, "okawa.kochi.jp", 3, false}, + {1, "otoyo.kochi.jp", 3, false}, + {1, "otsuki.kochi.jp", 3, false}, + {1, "sakawa.kochi.jp", 3, false}, + {1, "sukumo.kochi.jp", 3, false}, + {1, "susaki.kochi.jp", 3, false}, + {1, "tosa.kochi.jp", 3, false}, + {1, "tosashimizu.kochi.jp", 3, false}, + {1, "toyo.kochi.jp", 3, false}, + {1, "tsuno.kochi.jp", 3, false}, + {1, "umaji.kochi.jp", 3, false}, + {1, "yasuda.kochi.jp", 3, false}, + {1, "yusuhara.kochi.jp", 3, false}, + {1, "amakusa.kumamoto.jp", 3, false}, + {1, "arao.kumamoto.jp", 3, false}, + {1, "aso.kumamoto.jp", 3, false}, + {1, "choyo.kumamoto.jp", 3, false}, + {1, "gyokuto.kumamoto.jp", 3, false}, + {1, "kamiamakusa.kumamoto.jp", 3, false}, + {1, "kikuchi.kumamoto.jp", 3, false}, + {1, "kumamoto.kumamoto.jp", 3, false}, + {1, "mashiki.kumamoto.jp", 3, false}, + {1, "mifune.kumamoto.jp", 3, false}, + {1, "minamata.kumamoto.jp", 3, false}, + {1, "minamioguni.kumamoto.jp", 3, false}, + {1, "nagasu.kumamoto.jp", 3, false}, + {1, "nishihara.kumamoto.jp", 3, false}, + {1, "oguni.kumamoto.jp", 3, false}, + {1, "ozu.kumamoto.jp", 3, false}, + {1, "sumoto.kumamoto.jp", 3, false}, + {1, "takamori.kumamoto.jp", 3, false}, + {1, "uki.kumamoto.jp", 3, false}, + {1, "uto.kumamoto.jp", 3, false}, + {1, "yamaga.kumamoto.jp", 3, false}, + {1, "yamato.kumamoto.jp", 3, false}, + {1, "yatsushiro.kumamoto.jp", 3, false}, + {1, "ayabe.kyoto.jp", 3, false}, + {1, "fukuchiyama.kyoto.jp", 3, false}, + {1, "higashiyama.kyoto.jp", 3, false}, + {1, "ide.kyoto.jp", 3, false}, + {1, "ine.kyoto.jp", 3, false}, + {1, "joyo.kyoto.jp", 3, false}, + {1, "kameoka.kyoto.jp", 3, false}, + {1, "kamo.kyoto.jp", 3, false}, + {1, "kita.kyoto.jp", 3, false}, + {1, "kizu.kyoto.jp", 3, false}, + {1, "kumiyama.kyoto.jp", 3, false}, + {1, "kyotamba.kyoto.jp", 3, false}, + {1, "kyotanabe.kyoto.jp", 3, false}, + {1, "kyotango.kyoto.jp", 3, false}, + {1, "maizuru.kyoto.jp", 3, false}, + {1, "minami.kyoto.jp", 3, false}, + {1, "minamiyamashiro.kyoto.jp", 3, false}, + {1, "miyazu.kyoto.jp", 3, false}, + {1, "muko.kyoto.jp", 3, false}, + {1, "nagaokakyo.kyoto.jp", 3, false}, + {1, "nakagyo.kyoto.jp", 3, false}, + {1, "nantan.kyoto.jp", 3, false}, + {1, "oyamazaki.kyoto.jp", 3, false}, + {1, "sakyo.kyoto.jp", 3, false}, + {1, "seika.kyoto.jp", 3, false}, + {1, "tanabe.kyoto.jp", 3, false}, + {1, "uji.kyoto.jp", 3, false}, + {1, "ujitawara.kyoto.jp", 3, false}, + {1, "wazuka.kyoto.jp", 3, false}, + {1, "yamashina.kyoto.jp", 3, false}, + {1, "yawata.kyoto.jp", 3, false}, + {1, "asahi.mie.jp", 3, false}, + {1, "inabe.mie.jp", 3, false}, + {1, "ise.mie.jp", 3, false}, + {1, "kameyama.mie.jp", 3, false}, + {1, "kawagoe.mie.jp", 3, false}, + {1, "kiho.mie.jp", 3, false}, + {1, "kisosaki.mie.jp", 3, false}, + {1, "kiwa.mie.jp", 3, false}, + {1, "komono.mie.jp", 3, false}, + {1, "kumano.mie.jp", 3, false}, + {1, "kuwana.mie.jp", 3, false}, + {1, "matsusaka.mie.jp", 3, false}, + {1, "meiwa.mie.jp", 3, false}, + {1, "mihama.mie.jp", 3, false}, + {1, "minamiise.mie.jp", 3, false}, + {1, "misugi.mie.jp", 3, false}, + {1, "miyama.mie.jp", 3, false}, + {1, "nabari.mie.jp", 3, false}, + {1, "shima.mie.jp", 3, false}, + {1, "suzuka.mie.jp", 3, false}, + {1, "tado.mie.jp", 3, false}, + {1, "taiki.mie.jp", 3, false}, + {1, "taki.mie.jp", 3, false}, + {1, "tamaki.mie.jp", 3, false}, + {1, "toba.mie.jp", 3, false}, + {1, "tsu.mie.jp", 3, false}, + {1, "udono.mie.jp", 3, false}, + {1, "ureshino.mie.jp", 3, false}, + {1, "watarai.mie.jp", 3, false}, + {1, "yokkaichi.mie.jp", 3, false}, + {1, "furukawa.miyagi.jp", 3, false}, + {1, "higashimatsushima.miyagi.jp", 3, false}, + {1, "ishinomaki.miyagi.jp", 3, false}, + {1, "iwanuma.miyagi.jp", 3, false}, + {1, "kakuda.miyagi.jp", 3, false}, + {1, "kami.miyagi.jp", 3, false}, + {1, "kawasaki.miyagi.jp", 3, false}, + {1, "marumori.miyagi.jp", 3, false}, + {1, "matsushima.miyagi.jp", 3, false}, + {1, "minamisanriku.miyagi.jp", 3, false}, + {1, "misato.miyagi.jp", 3, false}, + {1, "murata.miyagi.jp", 3, false}, + {1, "natori.miyagi.jp", 3, false}, + {1, "ogawara.miyagi.jp", 3, false}, + {1, "ohira.miyagi.jp", 3, false}, + {1, "onagawa.miyagi.jp", 3, false}, + {1, "osaki.miyagi.jp", 3, false}, + {1, "rifu.miyagi.jp", 3, false}, + {1, "semine.miyagi.jp", 3, false}, + {1, "shibata.miyagi.jp", 3, false}, + {1, "shichikashuku.miyagi.jp", 3, false}, + {1, "shikama.miyagi.jp", 3, false}, + {1, "shiogama.miyagi.jp", 3, false}, + {1, "shiroishi.miyagi.jp", 3, false}, + {1, "tagajo.miyagi.jp", 3, false}, + {1, "taiwa.miyagi.jp", 3, false}, + {1, "tome.miyagi.jp", 3, false}, + {1, "tomiya.miyagi.jp", 3, false}, + {1, "wakuya.miyagi.jp", 3, false}, + {1, "watari.miyagi.jp", 3, false}, + {1, "yamamoto.miyagi.jp", 3, false}, + {1, "zao.miyagi.jp", 3, false}, + {1, "aya.miyazaki.jp", 3, false}, + {1, "ebino.miyazaki.jp", 3, false}, + {1, "gokase.miyazaki.jp", 3, false}, + {1, "hyuga.miyazaki.jp", 3, false}, + {1, "kadogawa.miyazaki.jp", 3, false}, + {1, "kawaminami.miyazaki.jp", 3, false}, + {1, "kijo.miyazaki.jp", 3, false}, + {1, "kitagawa.miyazaki.jp", 3, false}, + {1, "kitakata.miyazaki.jp", 3, false}, + {1, "kitaura.miyazaki.jp", 3, false}, + {1, "kobayashi.miyazaki.jp", 3, false}, + {1, "kunitomi.miyazaki.jp", 3, false}, + {1, "kushima.miyazaki.jp", 3, false}, + {1, "mimata.miyazaki.jp", 3, false}, + {1, "miyakonojo.miyazaki.jp", 3, false}, + {1, "miyazaki.miyazaki.jp", 3, false}, + {1, "morotsuka.miyazaki.jp", 3, false}, + {1, "nichinan.miyazaki.jp", 3, false}, + {1, "nishimera.miyazaki.jp", 3, false}, + {1, "nobeoka.miyazaki.jp", 3, false}, + {1, "saito.miyazaki.jp", 3, false}, + {1, "shiiba.miyazaki.jp", 3, false}, + {1, "shintomi.miyazaki.jp", 3, false}, + {1, "takaharu.miyazaki.jp", 3, false}, + {1, "takanabe.miyazaki.jp", 3, false}, + {1, "takazaki.miyazaki.jp", 3, false}, + {1, "tsuno.miyazaki.jp", 3, false}, + {1, "achi.nagano.jp", 3, false}, + {1, "agematsu.nagano.jp", 3, false}, + {1, "anan.nagano.jp", 3, false}, + {1, "aoki.nagano.jp", 3, false}, + {1, "asahi.nagano.jp", 3, false}, + {1, "azumino.nagano.jp", 3, false}, + {1, "chikuhoku.nagano.jp", 3, false}, + {1, "chikuma.nagano.jp", 3, false}, + {1, "chino.nagano.jp", 3, false}, + {1, "fujimi.nagano.jp", 3, false}, + {1, "hakuba.nagano.jp", 3, false}, + {1, "hara.nagano.jp", 3, false}, + {1, "hiraya.nagano.jp", 3, false}, + {1, "iida.nagano.jp", 3, false}, + {1, "iijima.nagano.jp", 3, false}, + {1, "iiyama.nagano.jp", 3, false}, + {1, "iizuna.nagano.jp", 3, false}, + {1, "ikeda.nagano.jp", 3, false}, + {1, "ikusaka.nagano.jp", 3, false}, + {1, "ina.nagano.jp", 3, false}, + {1, "karuizawa.nagano.jp", 3, false}, + {1, "kawakami.nagano.jp", 3, false}, + {1, "kiso.nagano.jp", 3, false}, + {1, "kisofukushima.nagano.jp", 3, false}, + {1, "kitaaiki.nagano.jp", 3, false}, + {1, "komagane.nagano.jp", 3, false}, + {1, "komoro.nagano.jp", 3, false}, + {1, "matsukawa.nagano.jp", 3, false}, + {1, "matsumoto.nagano.jp", 3, false}, + {1, "miasa.nagano.jp", 3, false}, + {1, "minamiaiki.nagano.jp", 3, false}, + {1, "minamimaki.nagano.jp", 3, false}, + {1, "minamiminowa.nagano.jp", 3, false}, + {1, "minowa.nagano.jp", 3, false}, + {1, "miyada.nagano.jp", 3, false}, + {1, "miyota.nagano.jp", 3, false}, + {1, "mochizuki.nagano.jp", 3, false}, + {1, "nagano.nagano.jp", 3, false}, + {1, "nagawa.nagano.jp", 3, false}, + {1, "nagiso.nagano.jp", 3, false}, + {1, "nakagawa.nagano.jp", 3, false}, + {1, "nakano.nagano.jp", 3, false}, + {1, "nozawaonsen.nagano.jp", 3, false}, + {1, "obuse.nagano.jp", 3, false}, + {1, "ogawa.nagano.jp", 3, false}, + {1, "okaya.nagano.jp", 3, false}, + {1, "omachi.nagano.jp", 3, false}, + {1, "omi.nagano.jp", 3, false}, + {1, "ookuwa.nagano.jp", 3, false}, + {1, "ooshika.nagano.jp", 3, false}, + {1, "otaki.nagano.jp", 3, false}, + {1, "otari.nagano.jp", 3, false}, + {1, "sakae.nagano.jp", 3, false}, + {1, "sakaki.nagano.jp", 3, false}, + {1, "saku.nagano.jp", 3, false}, + {1, "sakuho.nagano.jp", 3, false}, + {1, "shimosuwa.nagano.jp", 3, false}, + {1, "shinanomachi.nagano.jp", 3, false}, + {1, "shiojiri.nagano.jp", 3, false}, + {1, "suwa.nagano.jp", 3, false}, + {1, "suzaka.nagano.jp", 3, false}, + {1, "takagi.nagano.jp", 3, false}, + {1, "takamori.nagano.jp", 3, false}, + {1, "takayama.nagano.jp", 3, false}, + {1, "tateshina.nagano.jp", 3, false}, + {1, "tatsuno.nagano.jp", 3, false}, + {1, "togakushi.nagano.jp", 3, false}, + {1, "togura.nagano.jp", 3, false}, + {1, "tomi.nagano.jp", 3, false}, + {1, "ueda.nagano.jp", 3, false}, + {1, "wada.nagano.jp", 3, false}, + {1, "yamagata.nagano.jp", 3, false}, + {1, "yamanouchi.nagano.jp", 3, false}, + {1, "yasaka.nagano.jp", 3, false}, + {1, "yasuoka.nagano.jp", 3, false}, + {1, "chijiwa.nagasaki.jp", 3, false}, + {1, "futsu.nagasaki.jp", 3, false}, + {1, "goto.nagasaki.jp", 3, false}, + {1, "hasami.nagasaki.jp", 3, false}, + {1, "hirado.nagasaki.jp", 3, false}, + {1, "iki.nagasaki.jp", 3, false}, + {1, "isahaya.nagasaki.jp", 3, false}, + {1, "kawatana.nagasaki.jp", 3, false}, + {1, "kuchinotsu.nagasaki.jp", 3, false}, + {1, "matsuura.nagasaki.jp", 3, false}, + {1, "nagasaki.nagasaki.jp", 3, false}, + {1, "obama.nagasaki.jp", 3, false}, + {1, "omura.nagasaki.jp", 3, false}, + {1, "oseto.nagasaki.jp", 3, false}, + {1, "saikai.nagasaki.jp", 3, false}, + {1, "sasebo.nagasaki.jp", 3, false}, + {1, "seihi.nagasaki.jp", 3, false}, + {1, "shimabara.nagasaki.jp", 3, false}, + {1, "shinkamigoto.nagasaki.jp", 3, false}, + {1, "togitsu.nagasaki.jp", 3, false}, + {1, "tsushima.nagasaki.jp", 3, false}, + {1, "unzen.nagasaki.jp", 3, false}, + {1, "ando.nara.jp", 3, false}, + {1, "gose.nara.jp", 3, false}, + {1, "heguri.nara.jp", 3, false}, + {1, "higashiyoshino.nara.jp", 3, false}, + {1, "ikaruga.nara.jp", 3, false}, + {1, "ikoma.nara.jp", 3, false}, + {1, "kamikitayama.nara.jp", 3, false}, + {1, "kanmaki.nara.jp", 3, false}, + {1, "kashiba.nara.jp", 3, false}, + {1, "kashihara.nara.jp", 3, false}, + {1, "katsuragi.nara.jp", 3, false}, + {1, "kawai.nara.jp", 3, false}, + {1, "kawakami.nara.jp", 3, false}, + {1, "kawanishi.nara.jp", 3, false}, + {1, "koryo.nara.jp", 3, false}, + {1, "kurotaki.nara.jp", 3, false}, + {1, "mitsue.nara.jp", 3, false}, + {1, "miyake.nara.jp", 3, false}, + {1, "nara.nara.jp", 3, false}, + {1, "nosegawa.nara.jp", 3, false}, + {1, "oji.nara.jp", 3, false}, + {1, "ouda.nara.jp", 3, false}, + {1, "oyodo.nara.jp", 3, false}, + {1, "sakurai.nara.jp", 3, false}, + {1, "sango.nara.jp", 3, false}, + {1, "shimoichi.nara.jp", 3, false}, + {1, "shimokitayama.nara.jp", 3, false}, + {1, "shinjo.nara.jp", 3, false}, + {1, "soni.nara.jp", 3, false}, + {1, "takatori.nara.jp", 3, false}, + {1, "tawaramoto.nara.jp", 3, false}, + {1, "tenkawa.nara.jp", 3, false}, + {1, "tenri.nara.jp", 3, false}, + {1, "uda.nara.jp", 3, false}, + {1, "yamatokoriyama.nara.jp", 3, false}, + {1, "yamatotakada.nara.jp", 3, false}, + {1, "yamazoe.nara.jp", 3, false}, + {1, "yoshino.nara.jp", 3, false}, + {1, "aga.niigata.jp", 3, false}, + {1, "agano.niigata.jp", 3, false}, + {1, "gosen.niigata.jp", 3, false}, + {1, "itoigawa.niigata.jp", 3, false}, + {1, "izumozaki.niigata.jp", 3, false}, + {1, "joetsu.niigata.jp", 3, false}, + {1, "kamo.niigata.jp", 3, false}, + {1, "kariwa.niigata.jp", 3, false}, + {1, "kashiwazaki.niigata.jp", 3, false}, + {1, "minamiuonuma.niigata.jp", 3, false}, + {1, "mitsuke.niigata.jp", 3, false}, + {1, "muika.niigata.jp", 3, false}, + {1, "murakami.niigata.jp", 3, false}, + {1, "myoko.niigata.jp", 3, false}, + {1, "nagaoka.niigata.jp", 3, false}, + {1, "niigata.niigata.jp", 3, false}, + {1, "ojiya.niigata.jp", 3, false}, + {1, "omi.niigata.jp", 3, false}, + {1, "sado.niigata.jp", 3, false}, + {1, "sanjo.niigata.jp", 3, false}, + {1, "seiro.niigata.jp", 3, false}, + {1, "seirou.niigata.jp", 3, false}, + {1, "sekikawa.niigata.jp", 3, false}, + {1, "shibata.niigata.jp", 3, false}, + {1, "tagami.niigata.jp", 3, false}, + {1, "tainai.niigata.jp", 3, false}, + {1, "tochio.niigata.jp", 3, false}, + {1, "tokamachi.niigata.jp", 3, false}, + {1, "tsubame.niigata.jp", 3, false}, + {1, "tsunan.niigata.jp", 3, false}, + {1, "uonuma.niigata.jp", 3, false}, + {1, "yahiko.niigata.jp", 3, false}, + {1, "yoita.niigata.jp", 3, false}, + {1, "yuzawa.niigata.jp", 3, false}, + {1, "beppu.oita.jp", 3, false}, + {1, "bungoono.oita.jp", 3, false}, + {1, "bungotakada.oita.jp", 3, false}, + {1, "hasama.oita.jp", 3, false}, + {1, "hiji.oita.jp", 3, false}, + {1, "himeshima.oita.jp", 3, false}, + {1, "hita.oita.jp", 3, false}, + {1, "kamitsue.oita.jp", 3, false}, + {1, "kokonoe.oita.jp", 3, false}, + {1, "kuju.oita.jp", 3, false}, + {1, "kunisaki.oita.jp", 3, false}, + {1, "kusu.oita.jp", 3, false}, + {1, "oita.oita.jp", 3, false}, + {1, "saiki.oita.jp", 3, false}, + {1, "taketa.oita.jp", 3, false}, + {1, "tsukumi.oita.jp", 3, false}, + {1, "usa.oita.jp", 3, false}, + {1, "usuki.oita.jp", 3, false}, + {1, "yufu.oita.jp", 3, false}, + {1, "akaiwa.okayama.jp", 3, false}, + {1, "asakuchi.okayama.jp", 3, false}, + {1, "bizen.okayama.jp", 3, false}, + {1, "hayashima.okayama.jp", 3, false}, + {1, "ibara.okayama.jp", 3, false}, + {1, "kagamino.okayama.jp", 3, false}, + {1, "kasaoka.okayama.jp", 3, false}, + {1, "kibichuo.okayama.jp", 3, false}, + {1, "kumenan.okayama.jp", 3, false}, + {1, "kurashiki.okayama.jp", 3, false}, + {1, "maniwa.okayama.jp", 3, false}, + {1, "misaki.okayama.jp", 3, false}, + {1, "nagi.okayama.jp", 3, false}, + {1, "niimi.okayama.jp", 3, false}, + {1, "nishiawakura.okayama.jp", 3, false}, + {1, "okayama.okayama.jp", 3, false}, + {1, "satosho.okayama.jp", 3, false}, + {1, "setouchi.okayama.jp", 3, false}, + {1, "shinjo.okayama.jp", 3, false}, + {1, "shoo.okayama.jp", 3, false}, + {1, "soja.okayama.jp", 3, false}, + {1, "takahashi.okayama.jp", 3, false}, + {1, "tamano.okayama.jp", 3, false}, + {1, "tsuyama.okayama.jp", 3, false}, + {1, "wake.okayama.jp", 3, false}, + {1, "yakage.okayama.jp", 3, false}, + {1, "aguni.okinawa.jp", 3, false}, + {1, "ginowan.okinawa.jp", 3, false}, + {1, "ginoza.okinawa.jp", 3, false}, + {1, "gushikami.okinawa.jp", 3, false}, + {1, "haebaru.okinawa.jp", 3, false}, + {1, "higashi.okinawa.jp", 3, false}, + {1, "hirara.okinawa.jp", 3, false}, + {1, "iheya.okinawa.jp", 3, false}, + {1, "ishigaki.okinawa.jp", 3, false}, + {1, "ishikawa.okinawa.jp", 3, false}, + {1, "itoman.okinawa.jp", 3, false}, + {1, "izena.okinawa.jp", 3, false}, + {1, "kadena.okinawa.jp", 3, false}, + {1, "kin.okinawa.jp", 3, false}, + {1, "kitadaito.okinawa.jp", 3, false}, + {1, "kitanakagusuku.okinawa.jp", 3, false}, + {1, "kumejima.okinawa.jp", 3, false}, + {1, "kunigami.okinawa.jp", 3, false}, + {1, "minamidaito.okinawa.jp", 3, false}, + {1, "motobu.okinawa.jp", 3, false}, + {1, "nago.okinawa.jp", 3, false}, + {1, "naha.okinawa.jp", 3, false}, + {1, "nakagusuku.okinawa.jp", 3, false}, + {1, "nakijin.okinawa.jp", 3, false}, + {1, "nanjo.okinawa.jp", 3, false}, + {1, "nishihara.okinawa.jp", 3, false}, + {1, "ogimi.okinawa.jp", 3, false}, + {1, "okinawa.okinawa.jp", 3, false}, + {1, "onna.okinawa.jp", 3, false}, + {1, "shimoji.okinawa.jp", 3, false}, + {1, "taketomi.okinawa.jp", 3, false}, + {1, "tarama.okinawa.jp", 3, false}, + {1, "tokashiki.okinawa.jp", 3, false}, + {1, "tomigusuku.okinawa.jp", 3, false}, + {1, "tonaki.okinawa.jp", 3, false}, + {1, "urasoe.okinawa.jp", 3, false}, + {1, "uruma.okinawa.jp", 3, false}, + {1, "yaese.okinawa.jp", 3, false}, + {1, "yomitan.okinawa.jp", 3, false}, + {1, "yonabaru.okinawa.jp", 3, false}, + {1, "yonaguni.okinawa.jp", 3, false}, + {1, "zamami.okinawa.jp", 3, false}, + {1, "abeno.osaka.jp", 3, false}, + {1, "chihayaakasaka.osaka.jp", 3, false}, + {1, "chuo.osaka.jp", 3, false}, + {1, "daito.osaka.jp", 3, false}, + {1, "fujiidera.osaka.jp", 3, false}, + {1, "habikino.osaka.jp", 3, false}, + {1, "hannan.osaka.jp", 3, false}, + {1, "higashiosaka.osaka.jp", 3, false}, + {1, "higashisumiyoshi.osaka.jp", 3, false}, + {1, "higashiyodogawa.osaka.jp", 3, false}, + {1, "hirakata.osaka.jp", 3, false}, + {1, "ibaraki.osaka.jp", 3, false}, + {1, "ikeda.osaka.jp", 3, false}, + {1, "izumi.osaka.jp", 3, false}, + {1, "izumiotsu.osaka.jp", 3, false}, + {1, "izumisano.osaka.jp", 3, false}, + {1, "kadoma.osaka.jp", 3, false}, + {1, "kaizuka.osaka.jp", 3, false}, + {1, "kanan.osaka.jp", 3, false}, + {1, "kashiwara.osaka.jp", 3, false}, + {1, "katano.osaka.jp", 3, false}, + {1, "kawachinagano.osaka.jp", 3, false}, + {1, "kishiwada.osaka.jp", 3, false}, + {1, "kita.osaka.jp", 3, false}, + {1, "kumatori.osaka.jp", 3, false}, + {1, "matsubara.osaka.jp", 3, false}, + {1, "minato.osaka.jp", 3, false}, + {1, "minoh.osaka.jp", 3, false}, + {1, "misaki.osaka.jp", 3, false}, + {1, "moriguchi.osaka.jp", 3, false}, + {1, "neyagawa.osaka.jp", 3, false}, + {1, "nishi.osaka.jp", 3, false}, + {1, "nose.osaka.jp", 3, false}, + {1, "osakasayama.osaka.jp", 3, false}, + {1, "sakai.osaka.jp", 3, false}, + {1, "sayama.osaka.jp", 3, false}, + {1, "sennan.osaka.jp", 3, false}, + {1, "settsu.osaka.jp", 3, false}, + {1, "shijonawate.osaka.jp", 3, false}, + {1, "shimamoto.osaka.jp", 3, false}, + {1, "suita.osaka.jp", 3, false}, + {1, "tadaoka.osaka.jp", 3, false}, + {1, "taishi.osaka.jp", 3, false}, + {1, "tajiri.osaka.jp", 3, false}, + {1, "takaishi.osaka.jp", 3, false}, + {1, "takatsuki.osaka.jp", 3, false}, + {1, "tondabayashi.osaka.jp", 3, false}, + {1, "toyonaka.osaka.jp", 3, false}, + {1, "toyono.osaka.jp", 3, false}, + {1, "yao.osaka.jp", 3, false}, + {1, "ariake.saga.jp", 3, false}, + {1, "arita.saga.jp", 3, false}, + {1, "fukudomi.saga.jp", 3, false}, + {1, "genkai.saga.jp", 3, false}, + {1, "hamatama.saga.jp", 3, false}, + {1, "hizen.saga.jp", 3, false}, + {1, "imari.saga.jp", 3, false}, + {1, "kamimine.saga.jp", 3, false}, + {1, "kanzaki.saga.jp", 3, false}, + {1, "karatsu.saga.jp", 3, false}, + {1, "kashima.saga.jp", 3, false}, + {1, "kitagata.saga.jp", 3, false}, + {1, "kitahata.saga.jp", 3, false}, + {1, "kiyama.saga.jp", 3, false}, + {1, "kouhoku.saga.jp", 3, false}, + {1, "kyuragi.saga.jp", 3, false}, + {1, "nishiarita.saga.jp", 3, false}, + {1, "ogi.saga.jp", 3, false}, + {1, "omachi.saga.jp", 3, false}, + {1, "ouchi.saga.jp", 3, false}, + {1, "saga.saga.jp", 3, false}, + {1, "shiroishi.saga.jp", 3, false}, + {1, "taku.saga.jp", 3, false}, + {1, "tara.saga.jp", 3, false}, + {1, "tosu.saga.jp", 3, false}, + {1, "yoshinogari.saga.jp", 3, false}, + {1, "arakawa.saitama.jp", 3, false}, + {1, "asaka.saitama.jp", 3, false}, + {1, "chichibu.saitama.jp", 3, false}, + {1, "fujimi.saitama.jp", 3, false}, + {1, "fujimino.saitama.jp", 3, false}, + {1, "fukaya.saitama.jp", 3, false}, + {1, "hanno.saitama.jp", 3, false}, + {1, "hanyu.saitama.jp", 3, false}, + {1, "hasuda.saitama.jp", 3, false}, + {1, "hatogaya.saitama.jp", 3, false}, + {1, "hatoyama.saitama.jp", 3, false}, + {1, "hidaka.saitama.jp", 3, false}, + {1, "higashichichibu.saitama.jp", 3, false}, + {1, "higashimatsuyama.saitama.jp", 3, false}, + {1, "honjo.saitama.jp", 3, false}, + {1, "ina.saitama.jp", 3, false}, + {1, "iruma.saitama.jp", 3, false}, + {1, "iwatsuki.saitama.jp", 3, false}, + {1, "kamiizumi.saitama.jp", 3, false}, + {1, "kamikawa.saitama.jp", 3, false}, + {1, "kamisato.saitama.jp", 3, false}, + {1, "kasukabe.saitama.jp", 3, false}, + {1, "kawagoe.saitama.jp", 3, false}, + {1, "kawaguchi.saitama.jp", 3, false}, + {1, "kawajima.saitama.jp", 3, false}, + {1, "kazo.saitama.jp", 3, false}, + {1, "kitamoto.saitama.jp", 3, false}, + {1, "koshigaya.saitama.jp", 3, false}, + {1, "kounosu.saitama.jp", 3, false}, + {1, "kuki.saitama.jp", 3, false}, + {1, "kumagaya.saitama.jp", 3, false}, + {1, "matsubushi.saitama.jp", 3, false}, + {1, "minano.saitama.jp", 3, false}, + {1, "misato.saitama.jp", 3, false}, + {1, "miyashiro.saitama.jp", 3, false}, + {1, "miyoshi.saitama.jp", 3, false}, + {1, "moroyama.saitama.jp", 3, false}, + {1, "nagatoro.saitama.jp", 3, false}, + {1, "namegawa.saitama.jp", 3, false}, + {1, "niiza.saitama.jp", 3, false}, + {1, "ogano.saitama.jp", 3, false}, + {1, "ogawa.saitama.jp", 3, false}, + {1, "ogose.saitama.jp", 3, false}, + {1, "okegawa.saitama.jp", 3, false}, + {1, "omiya.saitama.jp", 3, false}, + {1, "otaki.saitama.jp", 3, false}, + {1, "ranzan.saitama.jp", 3, false}, + {1, "ryokami.saitama.jp", 3, false}, + {1, "saitama.saitama.jp", 3, false}, + {1, "sakado.saitama.jp", 3, false}, + {1, "satte.saitama.jp", 3, false}, + {1, "sayama.saitama.jp", 3, false}, + {1, "shiki.saitama.jp", 3, false}, + {1, "shiraoka.saitama.jp", 3, false}, + {1, "soka.saitama.jp", 3, false}, + {1, "sugito.saitama.jp", 3, false}, + {1, "toda.saitama.jp", 3, false}, + {1, "tokigawa.saitama.jp", 3, false}, + {1, "tokorozawa.saitama.jp", 3, false}, + {1, "tsurugashima.saitama.jp", 3, false}, + {1, "urawa.saitama.jp", 3, false}, + {1, "warabi.saitama.jp", 3, false}, + {1, "yashio.saitama.jp", 3, false}, + {1, "yokoze.saitama.jp", 3, false}, + {1, "yono.saitama.jp", 3, false}, + {1, "yorii.saitama.jp", 3, false}, + {1, "yoshida.saitama.jp", 3, false}, + {1, "yoshikawa.saitama.jp", 3, false}, + {1, "yoshimi.saitama.jp", 3, false}, + {1, "aisho.shiga.jp", 3, false}, + {1, "gamo.shiga.jp", 3, false}, + {1, "higashiomi.shiga.jp", 3, false}, + {1, "hikone.shiga.jp", 3, false}, + {1, "koka.shiga.jp", 3, false}, + {1, "konan.shiga.jp", 3, false}, + {1, "kosei.shiga.jp", 3, false}, + {1, "koto.shiga.jp", 3, false}, + {1, "kusatsu.shiga.jp", 3, false}, + {1, "maibara.shiga.jp", 3, false}, + {1, "moriyama.shiga.jp", 3, false}, + {1, "nagahama.shiga.jp", 3, false}, + {1, "nishiazai.shiga.jp", 3, false}, + {1, "notogawa.shiga.jp", 3, false}, + {1, "omihachiman.shiga.jp", 3, false}, + {1, "otsu.shiga.jp", 3, false}, + {1, "ritto.shiga.jp", 3, false}, + {1, "ryuoh.shiga.jp", 3, false}, + {1, "takashima.shiga.jp", 3, false}, + {1, "takatsuki.shiga.jp", 3, false}, + {1, "torahime.shiga.jp", 3, false}, + {1, "toyosato.shiga.jp", 3, false}, + {1, "yasu.shiga.jp", 3, false}, + {1, "akagi.shimane.jp", 3, false}, + {1, "ama.shimane.jp", 3, false}, + {1, "gotsu.shimane.jp", 3, false}, + {1, "hamada.shimane.jp", 3, false}, + {1, "higashiizumo.shimane.jp", 3, false}, + {1, "hikawa.shimane.jp", 3, false}, + {1, "hikimi.shimane.jp", 3, false}, + {1, "izumo.shimane.jp", 3, false}, + {1, "kakinoki.shimane.jp", 3, false}, + {1, "masuda.shimane.jp", 3, false}, + {1, "matsue.shimane.jp", 3, false}, + {1, "misato.shimane.jp", 3, false}, + {1, "nishinoshima.shimane.jp", 3, false}, + {1, "ohda.shimane.jp", 3, false}, + {1, "okinoshima.shimane.jp", 3, false}, + {1, "okuizumo.shimane.jp", 3, false}, + {1, "shimane.shimane.jp", 3, false}, + {1, "tamayu.shimane.jp", 3, false}, + {1, "tsuwano.shimane.jp", 3, false}, + {1, "unnan.shimane.jp", 3, false}, + {1, "yakumo.shimane.jp", 3, false}, + {1, "yasugi.shimane.jp", 3, false}, + {1, "yatsuka.shimane.jp", 3, false}, + {1, "arai.shizuoka.jp", 3, false}, + {1, "atami.shizuoka.jp", 3, false}, + {1, "fuji.shizuoka.jp", 3, false}, + {1, "fujieda.shizuoka.jp", 3, false}, + {1, "fujikawa.shizuoka.jp", 3, false}, + {1, "fujinomiya.shizuoka.jp", 3, false}, + {1, "fukuroi.shizuoka.jp", 3, false}, + {1, "gotemba.shizuoka.jp", 3, false}, + {1, "haibara.shizuoka.jp", 3, false}, + {1, "hamamatsu.shizuoka.jp", 3, false}, + {1, "higashiizu.shizuoka.jp", 3, false}, + {1, "ito.shizuoka.jp", 3, false}, + {1, "iwata.shizuoka.jp", 3, false}, + {1, "izu.shizuoka.jp", 3, false}, + {1, "izunokuni.shizuoka.jp", 3, false}, + {1, "kakegawa.shizuoka.jp", 3, false}, + {1, "kannami.shizuoka.jp", 3, false}, + {1, "kawanehon.shizuoka.jp", 3, false}, + {1, "kawazu.shizuoka.jp", 3, false}, + {1, "kikugawa.shizuoka.jp", 3, false}, + {1, "kosai.shizuoka.jp", 3, false}, + {1, "makinohara.shizuoka.jp", 3, false}, + {1, "matsuzaki.shizuoka.jp", 3, false}, + {1, "minamiizu.shizuoka.jp", 3, false}, + {1, "mishima.shizuoka.jp", 3, false}, + {1, "morimachi.shizuoka.jp", 3, false}, + {1, "nishiizu.shizuoka.jp", 3, false}, + {1, "numazu.shizuoka.jp", 3, false}, + {1, "omaezaki.shizuoka.jp", 3, false}, + {1, "shimada.shizuoka.jp", 3, false}, + {1, "shimizu.shizuoka.jp", 3, false}, + {1, "shimoda.shizuoka.jp", 3, false}, + {1, "shizuoka.shizuoka.jp", 3, false}, + {1, "susono.shizuoka.jp", 3, false}, + {1, "yaizu.shizuoka.jp", 3, false}, + {1, "yoshida.shizuoka.jp", 3, false}, + {1, "ashikaga.tochigi.jp", 3, false}, + {1, "bato.tochigi.jp", 3, false}, + {1, "haga.tochigi.jp", 3, false}, + {1, "ichikai.tochigi.jp", 3, false}, + {1, "iwafune.tochigi.jp", 3, false}, + {1, "kaminokawa.tochigi.jp", 3, false}, + {1, "kanuma.tochigi.jp", 3, false}, + {1, "karasuyama.tochigi.jp", 3, false}, + {1, "kuroiso.tochigi.jp", 3, false}, + {1, "mashiko.tochigi.jp", 3, false}, + {1, "mibu.tochigi.jp", 3, false}, + {1, "moka.tochigi.jp", 3, false}, + {1, "motegi.tochigi.jp", 3, false}, + {1, "nasu.tochigi.jp", 3, false}, + {1, "nasushiobara.tochigi.jp", 3, false}, + {1, "nikko.tochigi.jp", 3, false}, + {1, "nishikata.tochigi.jp", 3, false}, + {1, "nogi.tochigi.jp", 3, false}, + {1, "ohira.tochigi.jp", 3, false}, + {1, "ohtawara.tochigi.jp", 3, false}, + {1, "oyama.tochigi.jp", 3, false}, + {1, "sakura.tochigi.jp", 3, false}, + {1, "sano.tochigi.jp", 3, false}, + {1, "shimotsuke.tochigi.jp", 3, false}, + {1, "shioya.tochigi.jp", 3, false}, + {1, "takanezawa.tochigi.jp", 3, false}, + {1, "tochigi.tochigi.jp", 3, false}, + {1, "tsuga.tochigi.jp", 3, false}, + {1, "ujiie.tochigi.jp", 3, false}, + {1, "utsunomiya.tochigi.jp", 3, false}, + {1, "yaita.tochigi.jp", 3, false}, + {1, "aizumi.tokushima.jp", 3, false}, + {1, "anan.tokushima.jp", 3, false}, + {1, "ichiba.tokushima.jp", 3, false}, + {1, "itano.tokushima.jp", 3, false}, + {1, "kainan.tokushima.jp", 3, false}, + {1, "komatsushima.tokushima.jp", 3, false}, + {1, "matsushige.tokushima.jp", 3, false}, + {1, "mima.tokushima.jp", 3, false}, + {1, "minami.tokushima.jp", 3, false}, + {1, "miyoshi.tokushima.jp", 3, false}, + {1, "mugi.tokushima.jp", 3, false}, + {1, "nakagawa.tokushima.jp", 3, false}, + {1, "naruto.tokushima.jp", 3, false}, + {1, "sanagochi.tokushima.jp", 3, false}, + {1, "shishikui.tokushima.jp", 3, false}, + {1, "tokushima.tokushima.jp", 3, false}, + {1, "wajiki.tokushima.jp", 3, false}, + {1, "adachi.tokyo.jp", 3, false}, + {1, "akiruno.tokyo.jp", 3, false}, + {1, "akishima.tokyo.jp", 3, false}, + {1, "aogashima.tokyo.jp", 3, false}, + {1, "arakawa.tokyo.jp", 3, false}, + {1, "bunkyo.tokyo.jp", 3, false}, + {1, "chiyoda.tokyo.jp", 3, false}, + {1, "chofu.tokyo.jp", 3, false}, + {1, "chuo.tokyo.jp", 3, false}, + {1, "edogawa.tokyo.jp", 3, false}, + {1, "fuchu.tokyo.jp", 3, false}, + {1, "fussa.tokyo.jp", 3, false}, + {1, "hachijo.tokyo.jp", 3, false}, + {1, "hachioji.tokyo.jp", 3, false}, + {1, "hamura.tokyo.jp", 3, false}, + {1, "higashikurume.tokyo.jp", 3, false}, + {1, "higashimurayama.tokyo.jp", 3, false}, + {1, "higashiyamato.tokyo.jp", 3, false}, + {1, "hino.tokyo.jp", 3, false}, + {1, "hinode.tokyo.jp", 3, false}, + {1, "hinohara.tokyo.jp", 3, false}, + {1, "inagi.tokyo.jp", 3, false}, + {1, "itabashi.tokyo.jp", 3, false}, + {1, "katsushika.tokyo.jp", 3, false}, + {1, "kita.tokyo.jp", 3, false}, + {1, "kiyose.tokyo.jp", 3, false}, + {1, "kodaira.tokyo.jp", 3, false}, + {1, "koganei.tokyo.jp", 3, false}, + {1, "kokubunji.tokyo.jp", 3, false}, + {1, "komae.tokyo.jp", 3, false}, + {1, "koto.tokyo.jp", 3, false}, + {1, "kouzushima.tokyo.jp", 3, false}, + {1, "kunitachi.tokyo.jp", 3, false}, + {1, "machida.tokyo.jp", 3, false}, + {1, "meguro.tokyo.jp", 3, false}, + {1, "minato.tokyo.jp", 3, false}, + {1, "mitaka.tokyo.jp", 3, false}, + {1, "mizuho.tokyo.jp", 3, false}, + {1, "musashimurayama.tokyo.jp", 3, false}, + {1, "musashino.tokyo.jp", 3, false}, + {1, "nakano.tokyo.jp", 3, false}, + {1, "nerima.tokyo.jp", 3, false}, + {1, "ogasawara.tokyo.jp", 3, false}, + {1, "okutama.tokyo.jp", 3, false}, + {1, "ome.tokyo.jp", 3, false}, + {1, "oshima.tokyo.jp", 3, false}, + {1, "ota.tokyo.jp", 3, false}, + {1, "setagaya.tokyo.jp", 3, false}, + {1, "shibuya.tokyo.jp", 3, false}, + {1, "shinagawa.tokyo.jp", 3, false}, + {1, "shinjuku.tokyo.jp", 3, false}, + {1, "suginami.tokyo.jp", 3, false}, + {1, "sumida.tokyo.jp", 3, false}, + {1, "tachikawa.tokyo.jp", 3, false}, + {1, "taito.tokyo.jp", 3, false}, + {1, "tama.tokyo.jp", 3, false}, + {1, "toshima.tokyo.jp", 3, false}, + {1, "chizu.tottori.jp", 3, false}, + {1, "hino.tottori.jp", 3, false}, + {1, "kawahara.tottori.jp", 3, false}, + {1, "koge.tottori.jp", 3, false}, + {1, "kotoura.tottori.jp", 3, false}, + {1, "misasa.tottori.jp", 3, false}, + {1, "nanbu.tottori.jp", 3, false}, + {1, "nichinan.tottori.jp", 3, false}, + {1, "sakaiminato.tottori.jp", 3, false}, + {1, "tottori.tottori.jp", 3, false}, + {1, "wakasa.tottori.jp", 3, false}, + {1, "yazu.tottori.jp", 3, false}, + {1, "yonago.tottori.jp", 3, false}, + {1, "asahi.toyama.jp", 3, false}, + {1, "fuchu.toyama.jp", 3, false}, + {1, "fukumitsu.toyama.jp", 3, false}, + {1, "funahashi.toyama.jp", 3, false}, + {1, "himi.toyama.jp", 3, false}, + {1, "imizu.toyama.jp", 3, false}, + {1, "inami.toyama.jp", 3, false}, + {1, "johana.toyama.jp", 3, false}, + {1, "kamiichi.toyama.jp", 3, false}, + {1, "kurobe.toyama.jp", 3, false}, + {1, "nakaniikawa.toyama.jp", 3, false}, + {1, "namerikawa.toyama.jp", 3, false}, + {1, "nanto.toyama.jp", 3, false}, + {1, "nyuzen.toyama.jp", 3, false}, + {1, "oyabe.toyama.jp", 3, false}, + {1, "taira.toyama.jp", 3, false}, + {1, "takaoka.toyama.jp", 3, false}, + {1, "tateyama.toyama.jp", 3, false}, + {1, "toga.toyama.jp", 3, false}, + {1, "tonami.toyama.jp", 3, false}, + {1, "toyama.toyama.jp", 3, false}, + {1, "unazuki.toyama.jp", 3, false}, + {1, "uozu.toyama.jp", 3, false}, + {1, "yamada.toyama.jp", 3, false}, + {1, "arida.wakayama.jp", 3, false}, + {1, "aridagawa.wakayama.jp", 3, false}, + {1, "gobo.wakayama.jp", 3, false}, + {1, "hashimoto.wakayama.jp", 3, false}, + {1, "hidaka.wakayama.jp", 3, false}, + {1, "hirogawa.wakayama.jp", 3, false}, + {1, "inami.wakayama.jp", 3, false}, + {1, "iwade.wakayama.jp", 3, false}, + {1, "kainan.wakayama.jp", 3, false}, + {1, "kamitonda.wakayama.jp", 3, false}, + {1, "katsuragi.wakayama.jp", 3, false}, + {1, "kimino.wakayama.jp", 3, false}, + {1, "kinokawa.wakayama.jp", 3, false}, + {1, "kitayama.wakayama.jp", 3, false}, + {1, "koya.wakayama.jp", 3, false}, + {1, "koza.wakayama.jp", 3, false}, + {1, "kozagawa.wakayama.jp", 3, false}, + {1, "kudoyama.wakayama.jp", 3, false}, + {1, "kushimoto.wakayama.jp", 3, false}, + {1, "mihama.wakayama.jp", 3, false}, + {1, "misato.wakayama.jp", 3, false}, + {1, "nachikatsuura.wakayama.jp", 3, false}, + {1, "shingu.wakayama.jp", 3, false}, + {1, "shirahama.wakayama.jp", 3, false}, + {1, "taiji.wakayama.jp", 3, false}, + {1, "tanabe.wakayama.jp", 3, false}, + {1, "wakayama.wakayama.jp", 3, false}, + {1, "yuasa.wakayama.jp", 3, false}, + {1, "yura.wakayama.jp", 3, false}, + {1, "asahi.yamagata.jp", 3, false}, + {1, "funagata.yamagata.jp", 3, false}, + {1, "higashine.yamagata.jp", 3, false}, + {1, "iide.yamagata.jp", 3, false}, + {1, "kahoku.yamagata.jp", 3, false}, + {1, "kaminoyama.yamagata.jp", 3, false}, + {1, "kaneyama.yamagata.jp", 3, false}, + {1, "kawanishi.yamagata.jp", 3, false}, + {1, "mamurogawa.yamagata.jp", 3, false}, + {1, "mikawa.yamagata.jp", 3, false}, + {1, "murayama.yamagata.jp", 3, false}, + {1, "nagai.yamagata.jp", 3, false}, + {1, "nakayama.yamagata.jp", 3, false}, + {1, "nanyo.yamagata.jp", 3, false}, + {1, "nishikawa.yamagata.jp", 3, false}, + {1, "obanazawa.yamagata.jp", 3, false}, + {1, "oe.yamagata.jp", 3, false}, + {1, "oguni.yamagata.jp", 3, false}, + {1, "ohkura.yamagata.jp", 3, false}, + {1, "oishida.yamagata.jp", 3, false}, + {1, "sagae.yamagata.jp", 3, false}, + {1, "sakata.yamagata.jp", 3, false}, + {1, "sakegawa.yamagata.jp", 3, false}, + {1, "shinjo.yamagata.jp", 3, false}, + {1, "shirataka.yamagata.jp", 3, false}, + {1, "shonai.yamagata.jp", 3, false}, + {1, "takahata.yamagata.jp", 3, false}, + {1, "tendo.yamagata.jp", 3, false}, + {1, "tozawa.yamagata.jp", 3, false}, + {1, "tsuruoka.yamagata.jp", 3, false}, + {1, "yamagata.yamagata.jp", 3, false}, + {1, "yamanobe.yamagata.jp", 3, false}, + {1, "yonezawa.yamagata.jp", 3, false}, + {1, "yuza.yamagata.jp", 3, false}, + {1, "abu.yamaguchi.jp", 3, false}, + {1, "hagi.yamaguchi.jp", 3, false}, + {1, "hikari.yamaguchi.jp", 3, false}, + {1, "hofu.yamaguchi.jp", 3, false}, + {1, "iwakuni.yamaguchi.jp", 3, false}, + {1, "kudamatsu.yamaguchi.jp", 3, false}, + {1, "mitou.yamaguchi.jp", 3, false}, + {1, "nagato.yamaguchi.jp", 3, false}, + {1, "oshima.yamaguchi.jp", 3, false}, + {1, "shimonoseki.yamaguchi.jp", 3, false}, + {1, "shunan.yamaguchi.jp", 3, false}, + {1, "tabuse.yamaguchi.jp", 3, false}, + {1, "tokuyama.yamaguchi.jp", 3, false}, + {1, "toyota.yamaguchi.jp", 3, false}, + {1, "ube.yamaguchi.jp", 3, false}, + {1, "yuu.yamaguchi.jp", 3, false}, + {1, "chuo.yamanashi.jp", 3, false}, + {1, "doshi.yamanashi.jp", 3, false}, + {1, "fuefuki.yamanashi.jp", 3, false}, + {1, "fujikawa.yamanashi.jp", 3, false}, + {1, "fujikawaguchiko.yamanashi.jp", 3, false}, + {1, "fujiyoshida.yamanashi.jp", 3, false}, + {1, "hayakawa.yamanashi.jp", 3, false}, + {1, "hokuto.yamanashi.jp", 3, false}, + {1, "ichikawamisato.yamanashi.jp", 3, false}, + {1, "kai.yamanashi.jp", 3, false}, + {1, "kofu.yamanashi.jp", 3, false}, + {1, "koshu.yamanashi.jp", 3, false}, + {1, "kosuge.yamanashi.jp", 3, false}, + {1, "minami-alps.yamanashi.jp", 3, false}, + {1, "minobu.yamanashi.jp", 3, false}, + {1, "nakamichi.yamanashi.jp", 3, false}, + {1, "nanbu.yamanashi.jp", 3, false}, + {1, "narusawa.yamanashi.jp", 3, false}, + {1, "nirasaki.yamanashi.jp", 3, false}, + {1, "nishikatsura.yamanashi.jp", 3, false}, + {1, "oshino.yamanashi.jp", 3, false}, + {1, "otsuki.yamanashi.jp", 3, false}, + {1, "showa.yamanashi.jp", 3, false}, + {1, "tabayama.yamanashi.jp", 3, false}, + {1, "tsuru.yamanashi.jp", 3, false}, + {1, "uenohara.yamanashi.jp", 3, false}, + {1, "yamanakako.yamanashi.jp", 3, false}, + {1, "yamanashi.yamanashi.jp", 3, false}, + {1, "ke", 1, false}, + {1, "ac.ke", 2, false}, + {1, "co.ke", 2, false}, + {1, "go.ke", 2, false}, + {1, "info.ke", 2, false}, + {1, "me.ke", 2, false}, + {1, "mobi.ke", 2, false}, + {1, "ne.ke", 2, false}, + {1, "or.ke", 2, false}, + {1, "sc.ke", 2, false}, + {1, "kg", 1, false}, + {1, "org.kg", 2, false}, + {1, "net.kg", 2, false}, + {1, "com.kg", 2, false}, + {1, "edu.kg", 2, false}, + {1, "gov.kg", 2, false}, + {1, "mil.kg", 2, false}, + {2, "kh", 2, false}, + {1, "ki", 1, false}, + {1, "edu.ki", 2, false}, + {1, "biz.ki", 2, false}, + {1, "net.ki", 2, false}, + {1, "org.ki", 2, false}, + {1, "gov.ki", 2, false}, + {1, "info.ki", 2, false}, + {1, "com.ki", 2, false}, + {1, "km", 1, false}, + {1, "org.km", 2, false}, + {1, "nom.km", 2, false}, + {1, "gov.km", 2, false}, + {1, "prd.km", 2, false}, + {1, "tm.km", 2, false}, + {1, "edu.km", 2, false}, + {1, "mil.km", 2, false}, + {1, "ass.km", 2, false}, + {1, "com.km", 2, false}, + {1, "coop.km", 2, false}, + {1, "asso.km", 2, false}, + {1, "presse.km", 2, false}, + {1, "medecin.km", 2, false}, + {1, "notaires.km", 2, false}, + {1, "pharmaciens.km", 2, false}, + {1, "veterinaire.km", 2, false}, + {1, "gouv.km", 2, false}, + {1, "kn", 1, false}, + {1, "net.kn", 2, false}, + {1, "org.kn", 2, false}, + {1, "edu.kn", 2, false}, + {1, "gov.kn", 2, false}, + {1, "kp", 1, false}, + {1, "com.kp", 2, false}, + {1, "edu.kp", 2, false}, + {1, "gov.kp", 2, false}, + {1, "org.kp", 2, false}, + {1, "rep.kp", 2, false}, + {1, "tra.kp", 2, false}, + {1, "kr", 1, false}, + {1, "ac.kr", 2, false}, + {1, "co.kr", 2, false}, + {1, "es.kr", 2, false}, + {1, "go.kr", 2, false}, + {1, "hs.kr", 2, false}, + {1, "kg.kr", 2, false}, + {1, "mil.kr", 2, false}, + {1, "ms.kr", 2, false}, + {1, "ne.kr", 2, false}, + {1, "or.kr", 2, false}, + {1, "pe.kr", 2, false}, + {1, "re.kr", 2, false}, + {1, "sc.kr", 2, false}, + {1, "busan.kr", 2, false}, + {1, "chungbuk.kr", 2, false}, + {1, "chungnam.kr", 2, false}, + {1, "daegu.kr", 2, false}, + {1, "daejeon.kr", 2, false}, + {1, "gangwon.kr", 2, false}, + {1, "gwangju.kr", 2, false}, + {1, "gyeongbuk.kr", 2, false}, + {1, "gyeonggi.kr", 2, false}, + {1, "gyeongnam.kr", 2, false}, + {1, "incheon.kr", 2, false}, + {1, "jeju.kr", 2, false}, + {1, "jeonbuk.kr", 2, false}, + {1, "jeonnam.kr", 2, false}, + {1, "seoul.kr", 2, false}, + {1, "ulsan.kr", 2, false}, + {1, "kw", 1, false}, + {1, "com.kw", 2, false}, + {1, "edu.kw", 2, false}, + {1, "emb.kw", 2, false}, + {1, "gov.kw", 2, false}, + {1, "ind.kw", 2, false}, + {1, "net.kw", 2, false}, + {1, "org.kw", 2, false}, + {1, "ky", 1, false}, + {1, "edu.ky", 2, false}, + {1, "gov.ky", 2, false}, + {1, "com.ky", 2, false}, + {1, "org.ky", 2, false}, + {1, "net.ky", 2, false}, + {1, "kz", 1, false}, + {1, "org.kz", 2, false}, + {1, "edu.kz", 2, false}, + {1, "net.kz", 2, false}, + {1, "gov.kz", 2, false}, + {1, "mil.kz", 2, false}, + {1, "com.kz", 2, false}, + {1, "la", 1, false}, + {1, "int.la", 2, false}, + {1, "net.la", 2, false}, + {1, "info.la", 2, false}, + {1, "edu.la", 2, false}, + {1, "gov.la", 2, false}, + {1, "per.la", 2, false}, + {1, "com.la", 2, false}, + {1, "org.la", 2, false}, + {1, "lb", 1, false}, + {1, "com.lb", 2, false}, + {1, "edu.lb", 2, false}, + {1, "gov.lb", 2, false}, + {1, "net.lb", 2, false}, + {1, "org.lb", 2, false}, + {1, "lc", 1, false}, + {1, "com.lc", 2, false}, + {1, "net.lc", 2, false}, + {1, "co.lc", 2, false}, + {1, "org.lc", 2, false}, + {1, "edu.lc", 2, false}, + {1, "gov.lc", 2, false}, + {1, "li", 1, false}, + {1, "lk", 1, false}, + {1, "gov.lk", 2, false}, + {1, "sch.lk", 2, false}, + {1, "net.lk", 2, false}, + {1, "int.lk", 2, false}, + {1, "com.lk", 2, false}, + {1, "org.lk", 2, false}, + {1, "edu.lk", 2, false}, + {1, "ngo.lk", 2, false}, + {1, "soc.lk", 2, false}, + {1, "web.lk", 2, false}, + {1, "ltd.lk", 2, false}, + {1, "assn.lk", 2, false}, + {1, "grp.lk", 2, false}, + {1, "hotel.lk", 2, false}, + {1, "ac.lk", 2, false}, + {1, "lr", 1, false}, + {1, "com.lr", 2, false}, + {1, "edu.lr", 2, false}, + {1, "gov.lr", 2, false}, + {1, "org.lr", 2, false}, + {1, "net.lr", 2, false}, + {1, "ls", 1, false}, + {1, "ac.ls", 2, false}, + {1, "biz.ls", 2, false}, + {1, "co.ls", 2, false}, + {1, "edu.ls", 2, false}, + {1, "gov.ls", 2, false}, + {1, "info.ls", 2, false}, + {1, "net.ls", 2, false}, + {1, "org.ls", 2, false}, + {1, "sc.ls", 2, false}, + {1, "lt", 1, false}, + {1, "gov.lt", 2, false}, + {1, "lu", 1, false}, + {1, "lv", 1, false}, + {1, "com.lv", 2, false}, + {1, "edu.lv", 2, false}, + {1, "gov.lv", 2, false}, + {1, "org.lv", 2, false}, + {1, "mil.lv", 2, false}, + {1, "id.lv", 2, false}, + {1, "net.lv", 2, false}, + {1, "asn.lv", 2, false}, + {1, "conf.lv", 2, false}, + {1, "ly", 1, false}, + {1, "com.ly", 2, false}, + {1, "net.ly", 2, false}, + {1, "gov.ly", 2, false}, + {1, "plc.ly", 2, false}, + {1, "edu.ly", 2, false}, + {1, "sch.ly", 2, false}, + {1, "med.ly", 2, false}, + {1, "org.ly", 2, false}, + {1, "id.ly", 2, false}, + {1, "ma", 1, false}, + {1, "co.ma", 2, false}, + {1, "net.ma", 2, false}, + {1, "gov.ma", 2, false}, + {1, "org.ma", 2, false}, + {1, "ac.ma", 2, false}, + {1, "press.ma", 2, false}, + {1, "mc", 1, false}, + {1, "tm.mc", 2, false}, + {1, "asso.mc", 2, false}, + {1, "md", 1, false}, + {1, "me", 1, false}, + {1, "co.me", 2, false}, + {1, "net.me", 2, false}, + {1, "org.me", 2, false}, + {1, "edu.me", 2, false}, + {1, "ac.me", 2, false}, + {1, "gov.me", 2, false}, + {1, "its.me", 2, false}, + {1, "priv.me", 2, false}, + {1, "mg", 1, false}, + {1, "org.mg", 2, false}, + {1, "nom.mg", 2, false}, + {1, "gov.mg", 2, false}, + {1, "prd.mg", 2, false}, + {1, "tm.mg", 2, false}, + {1, "edu.mg", 2, false}, + {1, "mil.mg", 2, false}, + {1, "com.mg", 2, false}, + {1, "co.mg", 2, false}, + {1, "mh", 1, false}, + {1, "mil", 1, false}, + {1, "mk", 1, false}, + {1, "com.mk", 2, false}, + {1, "org.mk", 2, false}, + {1, "net.mk", 2, false}, + {1, "edu.mk", 2, false}, + {1, "gov.mk", 2, false}, + {1, "inf.mk", 2, false}, + {1, "name.mk", 2, false}, + {1, "ml", 1, false}, + {1, "com.ml", 2, false}, + {1, "edu.ml", 2, false}, + {1, "gouv.ml", 2, false}, + {1, "gov.ml", 2, false}, + {1, "net.ml", 2, false}, + {1, "org.ml", 2, false}, + {1, "presse.ml", 2, false}, + {2, "mm", 2, false}, + {1, "mn", 1, false}, + {1, "gov.mn", 2, false}, + {1, "edu.mn", 2, false}, + {1, "org.mn", 2, false}, + {1, "mo", 1, false}, + {1, "com.mo", 2, false}, + {1, "net.mo", 2, false}, + {1, "org.mo", 2, false}, + {1, "edu.mo", 2, false}, + {1, "gov.mo", 2, false}, + {1, "mobi", 1, false}, + {1, "mp", 1, false}, + {1, "mq", 1, false}, + {1, "mr", 1, false}, + {1, "gov.mr", 2, false}, + {1, "ms", 1, false}, + {1, "com.ms", 2, false}, + {1, "edu.ms", 2, false}, + {1, "gov.ms", 2, false}, + {1, "net.ms", 2, false}, + {1, "org.ms", 2, false}, + {1, "mt", 1, false}, + {1, "com.mt", 2, false}, + {1, "edu.mt", 2, false}, + {1, "net.mt", 2, false}, + {1, "org.mt", 2, false}, + {1, "mu", 1, false}, + {1, "com.mu", 2, false}, + {1, "net.mu", 2, false}, + {1, "org.mu", 2, false}, + {1, "gov.mu", 2, false}, + {1, "ac.mu", 2, false}, + {1, "co.mu", 2, false}, + {1, "or.mu", 2, false}, + {1, "museum", 1, false}, + {1, "academy.museum", 2, false}, + {1, "agriculture.museum", 2, false}, + {1, "air.museum", 2, false}, + {1, "airguard.museum", 2, false}, + {1, "alabama.museum", 2, false}, + {1, "alaska.museum", 2, false}, + {1, "amber.museum", 2, false}, + {1, "ambulance.museum", 2, false}, + {1, "american.museum", 2, false}, + {1, "americana.museum", 2, false}, + {1, "americanantiques.museum", 2, false}, + {1, "americanart.museum", 2, false}, + {1, "amsterdam.museum", 2, false}, + {1, "and.museum", 2, false}, + {1, "annefrank.museum", 2, false}, + {1, "anthro.museum", 2, false}, + {1, "anthropology.museum", 2, false}, + {1, "antiques.museum", 2, false}, + {1, "aquarium.museum", 2, false}, + {1, "arboretum.museum", 2, false}, + {1, "archaeological.museum", 2, false}, + {1, "archaeology.museum", 2, false}, + {1, "architecture.museum", 2, false}, + {1, "art.museum", 2, false}, + {1, "artanddesign.museum", 2, false}, + {1, "artcenter.museum", 2, false}, + {1, "artdeco.museum", 2, false}, + {1, "arteducation.museum", 2, false}, + {1, "artgallery.museum", 2, false}, + {1, "arts.museum", 2, false}, + {1, "artsandcrafts.museum", 2, false}, + {1, "asmatart.museum", 2, false}, + {1, "assassination.museum", 2, false}, + {1, "assisi.museum", 2, false}, + {1, "association.museum", 2, false}, + {1, "astronomy.museum", 2, false}, + {1, "atlanta.museum", 2, false}, + {1, "austin.museum", 2, false}, + {1, "australia.museum", 2, false}, + {1, "automotive.museum", 2, false}, + {1, "aviation.museum", 2, false}, + {1, "axis.museum", 2, false}, + {1, "badajoz.museum", 2, false}, + {1, "baghdad.museum", 2, false}, + {1, "bahn.museum", 2, false}, + {1, "bale.museum", 2, false}, + {1, "baltimore.museum", 2, false}, + {1, "barcelona.museum", 2, false}, + {1, "baseball.museum", 2, false}, + {1, "basel.museum", 2, false}, + {1, "baths.museum", 2, false}, + {1, "bauern.museum", 2, false}, + {1, "beauxarts.museum", 2, false}, + {1, "beeldengeluid.museum", 2, false}, + {1, "bellevue.museum", 2, false}, + {1, "bergbau.museum", 2, false}, + {1, "berkeley.museum", 2, false}, + {1, "berlin.museum", 2, false}, + {1, "bern.museum", 2, false}, + {1, "bible.museum", 2, false}, + {1, "bilbao.museum", 2, false}, + {1, "bill.museum", 2, false}, + {1, "birdart.museum", 2, false}, + {1, "birthplace.museum", 2, false}, + {1, "bonn.museum", 2, false}, + {1, "boston.museum", 2, false}, + {1, "botanical.museum", 2, false}, + {1, "botanicalgarden.museum", 2, false}, + {1, "botanicgarden.museum", 2, false}, + {1, "botany.museum", 2, false}, + {1, "brandywinevalley.museum", 2, false}, + {1, "brasil.museum", 2, false}, + {1, "bristol.museum", 2, false}, + {1, "british.museum", 2, false}, + {1, "britishcolumbia.museum", 2, false}, + {1, "broadcast.museum", 2, false}, + {1, "brunel.museum", 2, false}, + {1, "brussel.museum", 2, false}, + {1, "brussels.museum", 2, false}, + {1, "bruxelles.museum", 2, false}, + {1, "building.museum", 2, false}, + {1, "burghof.museum", 2, false}, + {1, "bus.museum", 2, false}, + {1, "bushey.museum", 2, false}, + {1, "cadaques.museum", 2, false}, + {1, "california.museum", 2, false}, + {1, "cambridge.museum", 2, false}, + {1, "can.museum", 2, false}, + {1, "canada.museum", 2, false}, + {1, "capebreton.museum", 2, false}, + {1, "carrier.museum", 2, false}, + {1, "cartoonart.museum", 2, false}, + {1, "casadelamoneda.museum", 2, false}, + {1, "castle.museum", 2, false}, + {1, "castres.museum", 2, false}, + {1, "celtic.museum", 2, false}, + {1, "center.museum", 2, false}, + {1, "chattanooga.museum", 2, false}, + {1, "cheltenham.museum", 2, false}, + {1, "chesapeakebay.museum", 2, false}, + {1, "chicago.museum", 2, false}, + {1, "children.museum", 2, false}, + {1, "childrens.museum", 2, false}, + {1, "childrensgarden.museum", 2, false}, + {1, "chiropractic.museum", 2, false}, + {1, "chocolate.museum", 2, false}, + {1, "christiansburg.museum", 2, false}, + {1, "cincinnati.museum", 2, false}, + {1, "cinema.museum", 2, false}, + {1, "circus.museum", 2, false}, + {1, "civilisation.museum", 2, false}, + {1, "civilization.museum", 2, false}, + {1, "civilwar.museum", 2, false}, + {1, "clinton.museum", 2, false}, + {1, "clock.museum", 2, false}, + {1, "coal.museum", 2, false}, + {1, "coastaldefence.museum", 2, false}, + {1, "cody.museum", 2, false}, + {1, "coldwar.museum", 2, false}, + {1, "collection.museum", 2, false}, + {1, "colonialwilliamsburg.museum", 2, false}, + {1, "coloradoplateau.museum", 2, false}, + {1, "columbia.museum", 2, false}, + {1, "columbus.museum", 2, false}, + {1, "communication.museum", 2, false}, + {1, "communications.museum", 2, false}, + {1, "community.museum", 2, false}, + {1, "computer.museum", 2, false}, + {1, "computerhistory.museum", 2, false}, + {1, "xn--comunicaes-v6a2o.museum", 2, false}, + {1, "contemporary.museum", 2, false}, + {1, "contemporaryart.museum", 2, false}, + {1, "convent.museum", 2, false}, + {1, "copenhagen.museum", 2, false}, + {1, "corporation.museum", 2, false}, + {1, "xn--correios-e-telecomunicaes-ghc29a.museum", 2, false}, + {1, "corvette.museum", 2, false}, + {1, "costume.museum", 2, false}, + {1, "countryestate.museum", 2, false}, + {1, "county.museum", 2, false}, + {1, "crafts.museum", 2, false}, + {1, "cranbrook.museum", 2, false}, + {1, "creation.museum", 2, false}, + {1, "cultural.museum", 2, false}, + {1, "culturalcenter.museum", 2, false}, + {1, "culture.museum", 2, false}, + {1, "cyber.museum", 2, false}, + {1, "cymru.museum", 2, false}, + {1, "dali.museum", 2, false}, + {1, "dallas.museum", 2, false}, + {1, "database.museum", 2, false}, + {1, "ddr.museum", 2, false}, + {1, "decorativearts.museum", 2, false}, + {1, "delaware.museum", 2, false}, + {1, "delmenhorst.museum", 2, false}, + {1, "denmark.museum", 2, false}, + {1, "depot.museum", 2, false}, + {1, "design.museum", 2, false}, + {1, "detroit.museum", 2, false}, + {1, "dinosaur.museum", 2, false}, + {1, "discovery.museum", 2, false}, + {1, "dolls.museum", 2, false}, + {1, "donostia.museum", 2, false}, + {1, "durham.museum", 2, false}, + {1, "eastafrica.museum", 2, false}, + {1, "eastcoast.museum", 2, false}, + {1, "education.museum", 2, false}, + {1, "educational.museum", 2, false}, + {1, "egyptian.museum", 2, false}, + {1, "eisenbahn.museum", 2, false}, + {1, "elburg.museum", 2, false}, + {1, "elvendrell.museum", 2, false}, + {1, "embroidery.museum", 2, false}, + {1, "encyclopedic.museum", 2, false}, + {1, "england.museum", 2, false}, + {1, "entomology.museum", 2, false}, + {1, "environment.museum", 2, false}, + {1, "environmentalconservation.museum", 2, false}, + {1, "epilepsy.museum", 2, false}, + {1, "essex.museum", 2, false}, + {1, "estate.museum", 2, false}, + {1, "ethnology.museum", 2, false}, + {1, "exeter.museum", 2, false}, + {1, "exhibition.museum", 2, false}, + {1, "family.museum", 2, false}, + {1, "farm.museum", 2, false}, + {1, "farmequipment.museum", 2, false}, + {1, "farmers.museum", 2, false}, + {1, "farmstead.museum", 2, false}, + {1, "field.museum", 2, false}, + {1, "figueres.museum", 2, false}, + {1, "filatelia.museum", 2, false}, + {1, "film.museum", 2, false}, + {1, "fineart.museum", 2, false}, + {1, "finearts.museum", 2, false}, + {1, "finland.museum", 2, false}, + {1, "flanders.museum", 2, false}, + {1, "florida.museum", 2, false}, + {1, "force.museum", 2, false}, + {1, "fortmissoula.museum", 2, false}, + {1, "fortworth.museum", 2, false}, + {1, "foundation.museum", 2, false}, + {1, "francaise.museum", 2, false}, + {1, "frankfurt.museum", 2, false}, + {1, "franziskaner.museum", 2, false}, + {1, "freemasonry.museum", 2, false}, + {1, "freiburg.museum", 2, false}, + {1, "fribourg.museum", 2, false}, + {1, "frog.museum", 2, false}, + {1, "fundacio.museum", 2, false}, + {1, "furniture.museum", 2, false}, + {1, "gallery.museum", 2, false}, + {1, "garden.museum", 2, false}, + {1, "gateway.museum", 2, false}, + {1, "geelvinck.museum", 2, false}, + {1, "gemological.museum", 2, false}, + {1, "geology.museum", 2, false}, + {1, "georgia.museum", 2, false}, + {1, "giessen.museum", 2, false}, + {1, "glas.museum", 2, false}, + {1, "glass.museum", 2, false}, + {1, "gorge.museum", 2, false}, + {1, "grandrapids.museum", 2, false}, + {1, "graz.museum", 2, false}, + {1, "guernsey.museum", 2, false}, + {1, "halloffame.museum", 2, false}, + {1, "hamburg.museum", 2, false}, + {1, "handson.museum", 2, false}, + {1, "harvestcelebration.museum", 2, false}, + {1, "hawaii.museum", 2, false}, + {1, "health.museum", 2, false}, + {1, "heimatunduhren.museum", 2, false}, + {1, "hellas.museum", 2, false}, + {1, "helsinki.museum", 2, false}, + {1, "hembygdsforbund.museum", 2, false}, + {1, "heritage.museum", 2, false}, + {1, "histoire.museum", 2, false}, + {1, "historical.museum", 2, false}, + {1, "historicalsociety.museum", 2, false}, + {1, "historichouses.museum", 2, false}, + {1, "historisch.museum", 2, false}, + {1, "historisches.museum", 2, false}, + {1, "history.museum", 2, false}, + {1, "historyofscience.museum", 2, false}, + {1, "horology.museum", 2, false}, + {1, "house.museum", 2, false}, + {1, "humanities.museum", 2, false}, + {1, "illustration.museum", 2, false}, + {1, "imageandsound.museum", 2, false}, + {1, "indian.museum", 2, false}, + {1, "indiana.museum", 2, false}, + {1, "indianapolis.museum", 2, false}, + {1, "indianmarket.museum", 2, false}, + {1, "intelligence.museum", 2, false}, + {1, "interactive.museum", 2, false}, + {1, "iraq.museum", 2, false}, + {1, "iron.museum", 2, false}, + {1, "isleofman.museum", 2, false}, + {1, "jamison.museum", 2, false}, + {1, "jefferson.museum", 2, false}, + {1, "jerusalem.museum", 2, false}, + {1, "jewelry.museum", 2, false}, + {1, "jewish.museum", 2, false}, + {1, "jewishart.museum", 2, false}, + {1, "jfk.museum", 2, false}, + {1, "journalism.museum", 2, false}, + {1, "judaica.museum", 2, false}, + {1, "judygarland.museum", 2, false}, + {1, "juedisches.museum", 2, false}, + {1, "juif.museum", 2, false}, + {1, "karate.museum", 2, false}, + {1, "karikatur.museum", 2, false}, + {1, "kids.museum", 2, false}, + {1, "koebenhavn.museum", 2, false}, + {1, "koeln.museum", 2, false}, + {1, "kunst.museum", 2, false}, + {1, "kunstsammlung.museum", 2, false}, + {1, "kunstunddesign.museum", 2, false}, + {1, "labor.museum", 2, false}, + {1, "labour.museum", 2, false}, + {1, "lajolla.museum", 2, false}, + {1, "lancashire.museum", 2, false}, + {1, "landes.museum", 2, false}, + {1, "lans.museum", 2, false}, + {1, "xn--lns-qla.museum", 2, false}, + {1, "larsson.museum", 2, false}, + {1, "lewismiller.museum", 2, false}, + {1, "lincoln.museum", 2, false}, + {1, "linz.museum", 2, false}, + {1, "living.museum", 2, false}, + {1, "livinghistory.museum", 2, false}, + {1, "localhistory.museum", 2, false}, + {1, "london.museum", 2, false}, + {1, "losangeles.museum", 2, false}, + {1, "louvre.museum", 2, false}, + {1, "loyalist.museum", 2, false}, + {1, "lucerne.museum", 2, false}, + {1, "luxembourg.museum", 2, false}, + {1, "luzern.museum", 2, false}, + {1, "mad.museum", 2, false}, + {1, "madrid.museum", 2, false}, + {1, "mallorca.museum", 2, false}, + {1, "manchester.museum", 2, false}, + {1, "mansion.museum", 2, false}, + {1, "mansions.museum", 2, false}, + {1, "manx.museum", 2, false}, + {1, "marburg.museum", 2, false}, + {1, "maritime.museum", 2, false}, + {1, "maritimo.museum", 2, false}, + {1, "maryland.museum", 2, false}, + {1, "marylhurst.museum", 2, false}, + {1, "media.museum", 2, false}, + {1, "medical.museum", 2, false}, + {1, "medizinhistorisches.museum", 2, false}, + {1, "meeres.museum", 2, false}, + {1, "memorial.museum", 2, false}, + {1, "mesaverde.museum", 2, false}, + {1, "michigan.museum", 2, false}, + {1, "midatlantic.museum", 2, false}, + {1, "military.museum", 2, false}, + {1, "mill.museum", 2, false}, + {1, "miners.museum", 2, false}, + {1, "mining.museum", 2, false}, + {1, "minnesota.museum", 2, false}, + {1, "missile.museum", 2, false}, + {1, "missoula.museum", 2, false}, + {1, "modern.museum", 2, false}, + {1, "moma.museum", 2, false}, + {1, "money.museum", 2, false}, + {1, "monmouth.museum", 2, false}, + {1, "monticello.museum", 2, false}, + {1, "montreal.museum", 2, false}, + {1, "moscow.museum", 2, false}, + {1, "motorcycle.museum", 2, false}, + {1, "muenchen.museum", 2, false}, + {1, "muenster.museum", 2, false}, + {1, "mulhouse.museum", 2, false}, + {1, "muncie.museum", 2, false}, + {1, "museet.museum", 2, false}, + {1, "museumcenter.museum", 2, false}, + {1, "museumvereniging.museum", 2, false}, + {1, "music.museum", 2, false}, + {1, "national.museum", 2, false}, + {1, "nationalfirearms.museum", 2, false}, + {1, "nationalheritage.museum", 2, false}, + {1, "nativeamerican.museum", 2, false}, + {1, "naturalhistory.museum", 2, false}, + {1, "naturalhistorymuseum.museum", 2, false}, + {1, "naturalsciences.museum", 2, false}, + {1, "nature.museum", 2, false}, + {1, "naturhistorisches.museum", 2, false}, + {1, "natuurwetenschappen.museum", 2, false}, + {1, "naumburg.museum", 2, false}, + {1, "naval.museum", 2, false}, + {1, "nebraska.museum", 2, false}, + {1, "neues.museum", 2, false}, + {1, "newhampshire.museum", 2, false}, + {1, "newjersey.museum", 2, false}, + {1, "newmexico.museum", 2, false}, + {1, "newport.museum", 2, false}, + {1, "newspaper.museum", 2, false}, + {1, "newyork.museum", 2, false}, + {1, "niepce.museum", 2, false}, + {1, "norfolk.museum", 2, false}, + {1, "north.museum", 2, false}, + {1, "nrw.museum", 2, false}, + {1, "nyc.museum", 2, false}, + {1, "nyny.museum", 2, false}, + {1, "oceanographic.museum", 2, false}, + {1, "oceanographique.museum", 2, false}, + {1, "omaha.museum", 2, false}, + {1, "online.museum", 2, false}, + {1, "ontario.museum", 2, false}, + {1, "openair.museum", 2, false}, + {1, "oregon.museum", 2, false}, + {1, "oregontrail.museum", 2, false}, + {1, "otago.museum", 2, false}, + {1, "oxford.museum", 2, false}, + {1, "pacific.museum", 2, false}, + {1, "paderborn.museum", 2, false}, + {1, "palace.museum", 2, false}, + {1, "paleo.museum", 2, false}, + {1, "palmsprings.museum", 2, false}, + {1, "panama.museum", 2, false}, + {1, "paris.museum", 2, false}, + {1, "pasadena.museum", 2, false}, + {1, "pharmacy.museum", 2, false}, + {1, "philadelphia.museum", 2, false}, + {1, "philadelphiaarea.museum", 2, false}, + {1, "philately.museum", 2, false}, + {1, "phoenix.museum", 2, false}, + {1, "photography.museum", 2, false}, + {1, "pilots.museum", 2, false}, + {1, "pittsburgh.museum", 2, false}, + {1, "planetarium.museum", 2, false}, + {1, "plantation.museum", 2, false}, + {1, "plants.museum", 2, false}, + {1, "plaza.museum", 2, false}, + {1, "portal.museum", 2, false}, + {1, "portland.museum", 2, false}, + {1, "portlligat.museum", 2, false}, + {1, "posts-and-telecommunications.museum", 2, false}, + {1, "preservation.museum", 2, false}, + {1, "presidio.museum", 2, false}, + {1, "press.museum", 2, false}, + {1, "project.museum", 2, false}, + {1, "public.museum", 2, false}, + {1, "pubol.museum", 2, false}, + {1, "quebec.museum", 2, false}, + {1, "railroad.museum", 2, false}, + {1, "railway.museum", 2, false}, + {1, "research.museum", 2, false}, + {1, "resistance.museum", 2, false}, + {1, "riodejaneiro.museum", 2, false}, + {1, "rochester.museum", 2, false}, + {1, "rockart.museum", 2, false}, + {1, "roma.museum", 2, false}, + {1, "russia.museum", 2, false}, + {1, "saintlouis.museum", 2, false}, + {1, "salem.museum", 2, false}, + {1, "salvadordali.museum", 2, false}, + {1, "salzburg.museum", 2, false}, + {1, "sandiego.museum", 2, false}, + {1, "sanfrancisco.museum", 2, false}, + {1, "santabarbara.museum", 2, false}, + {1, "santacruz.museum", 2, false}, + {1, "santafe.museum", 2, false}, + {1, "saskatchewan.museum", 2, false}, + {1, "satx.museum", 2, false}, + {1, "savannahga.museum", 2, false}, + {1, "schlesisches.museum", 2, false}, + {1, "schoenbrunn.museum", 2, false}, + {1, "schokoladen.museum", 2, false}, + {1, "school.museum", 2, false}, + {1, "schweiz.museum", 2, false}, + {1, "science.museum", 2, false}, + {1, "scienceandhistory.museum", 2, false}, + {1, "scienceandindustry.museum", 2, false}, + {1, "sciencecenter.museum", 2, false}, + {1, "sciencecenters.museum", 2, false}, + {1, "science-fiction.museum", 2, false}, + {1, "sciencehistory.museum", 2, false}, + {1, "sciences.museum", 2, false}, + {1, "sciencesnaturelles.museum", 2, false}, + {1, "scotland.museum", 2, false}, + {1, "seaport.museum", 2, false}, + {1, "settlement.museum", 2, false}, + {1, "settlers.museum", 2, false}, + {1, "shell.museum", 2, false}, + {1, "sherbrooke.museum", 2, false}, + {1, "sibenik.museum", 2, false}, + {1, "silk.museum", 2, false}, + {1, "ski.museum", 2, false}, + {1, "skole.museum", 2, false}, + {1, "society.museum", 2, false}, + {1, "sologne.museum", 2, false}, + {1, "soundandvision.museum", 2, false}, + {1, "southcarolina.museum", 2, false}, + {1, "southwest.museum", 2, false}, + {1, "space.museum", 2, false}, + {1, "spy.museum", 2, false}, + {1, "square.museum", 2, false}, + {1, "stadt.museum", 2, false}, + {1, "stalbans.museum", 2, false}, + {1, "starnberg.museum", 2, false}, + {1, "state.museum", 2, false}, + {1, "stateofdelaware.museum", 2, false}, + {1, "station.museum", 2, false}, + {1, "steam.museum", 2, false}, + {1, "steiermark.museum", 2, false}, + {1, "stjohn.museum", 2, false}, + {1, "stockholm.museum", 2, false}, + {1, "stpetersburg.museum", 2, false}, + {1, "stuttgart.museum", 2, false}, + {1, "suisse.museum", 2, false}, + {1, "surgeonshall.museum", 2, false}, + {1, "surrey.museum", 2, false}, + {1, "svizzera.museum", 2, false}, + {1, "sweden.museum", 2, false}, + {1, "sydney.museum", 2, false}, + {1, "tank.museum", 2, false}, + {1, "tcm.museum", 2, false}, + {1, "technology.museum", 2, false}, + {1, "telekommunikation.museum", 2, false}, + {1, "television.museum", 2, false}, + {1, "texas.museum", 2, false}, + {1, "textile.museum", 2, false}, + {1, "theater.museum", 2, false}, + {1, "time.museum", 2, false}, + {1, "timekeeping.museum", 2, false}, + {1, "topology.museum", 2, false}, + {1, "torino.museum", 2, false}, + {1, "touch.museum", 2, false}, + {1, "town.museum", 2, false}, + {1, "transport.museum", 2, false}, + {1, "tree.museum", 2, false}, + {1, "trolley.museum", 2, false}, + {1, "trust.museum", 2, false}, + {1, "trustee.museum", 2, false}, + {1, "uhren.museum", 2, false}, + {1, "ulm.museum", 2, false}, + {1, "undersea.museum", 2, false}, + {1, "university.museum", 2, false}, + {1, "usa.museum", 2, false}, + {1, "usantiques.museum", 2, false}, + {1, "usarts.museum", 2, false}, + {1, "uscountryestate.museum", 2, false}, + {1, "usculture.museum", 2, false}, + {1, "usdecorativearts.museum", 2, false}, + {1, "usgarden.museum", 2, false}, + {1, "ushistory.museum", 2, false}, + {1, "ushuaia.museum", 2, false}, + {1, "uslivinghistory.museum", 2, false}, + {1, "utah.museum", 2, false}, + {1, "uvic.museum", 2, false}, + {1, "valley.museum", 2, false}, + {1, "vantaa.museum", 2, false}, + {1, "versailles.museum", 2, false}, + {1, "viking.museum", 2, false}, + {1, "village.museum", 2, false}, + {1, "virginia.museum", 2, false}, + {1, "virtual.museum", 2, false}, + {1, "virtuel.museum", 2, false}, + {1, "vlaanderen.museum", 2, false}, + {1, "volkenkunde.museum", 2, false}, + {1, "wales.museum", 2, false}, + {1, "wallonie.museum", 2, false}, + {1, "war.museum", 2, false}, + {1, "washingtondc.museum", 2, false}, + {1, "watchandclock.museum", 2, false}, + {1, "watch-and-clock.museum", 2, false}, + {1, "western.museum", 2, false}, + {1, "westfalen.museum", 2, false}, + {1, "whaling.museum", 2, false}, + {1, "wildlife.museum", 2, false}, + {1, "williamsburg.museum", 2, false}, + {1, "windmill.museum", 2, false}, + {1, "workshop.museum", 2, false}, + {1, "york.museum", 2, false}, + {1, "yorkshire.museum", 2, false}, + {1, "yosemite.museum", 2, false}, + {1, "youth.museum", 2, false}, + {1, "zoological.museum", 2, false}, + {1, "zoology.museum", 2, false}, + {1, "xn--9dbhblg6di.museum", 2, false}, + {1, "xn--h1aegh.museum", 2, false}, + {1, "mv", 1, false}, + {1, "aero.mv", 2, false}, + {1, "biz.mv", 2, false}, + {1, "com.mv", 2, false}, + {1, "coop.mv", 2, false}, + {1, "edu.mv", 2, false}, + {1, "gov.mv", 2, false}, + {1, "info.mv", 2, false}, + {1, "int.mv", 2, false}, + {1, "mil.mv", 2, false}, + {1, "museum.mv", 2, false}, + {1, "name.mv", 2, false}, + {1, "net.mv", 2, false}, + {1, "org.mv", 2, false}, + {1, "pro.mv", 2, false}, + {1, "mw", 1, false}, + {1, "ac.mw", 2, false}, + {1, "biz.mw", 2, false}, + {1, "co.mw", 2, false}, + {1, "com.mw", 2, false}, + {1, "coop.mw", 2, false}, + {1, "edu.mw", 2, false}, + {1, "gov.mw", 2, false}, + {1, "int.mw", 2, false}, + {1, "museum.mw", 2, false}, + {1, "net.mw", 2, false}, + {1, "org.mw", 2, false}, + {1, "mx", 1, false}, + {1, "com.mx", 2, false}, + {1, "org.mx", 2, false}, + {1, "gob.mx", 2, false}, + {1, "edu.mx", 2, false}, + {1, "net.mx", 2, false}, + {1, "my", 1, false}, + {1, "com.my", 2, false}, + {1, "net.my", 2, false}, + {1, "org.my", 2, false}, + {1, "gov.my", 2, false}, + {1, "edu.my", 2, false}, + {1, "mil.my", 2, false}, + {1, "name.my", 2, false}, + {1, "mz", 1, false}, + {1, "ac.mz", 2, false}, + {1, "adv.mz", 2, false}, + {1, "co.mz", 2, false}, + {1, "edu.mz", 2, false}, + {1, "gov.mz", 2, false}, + {1, "mil.mz", 2, false}, + {1, "net.mz", 2, false}, + {1, "org.mz", 2, false}, + {1, "na", 1, false}, + {1, "info.na", 2, false}, + {1, "pro.na", 2, false}, + {1, "name.na", 2, false}, + {1, "school.na", 2, false}, + {1, "or.na", 2, false}, + {1, "dr.na", 2, false}, + {1, "us.na", 2, false}, + {1, "mx.na", 2, false}, + {1, "ca.na", 2, false}, + {1, "in.na", 2, false}, + {1, "cc.na", 2, false}, + {1, "tv.na", 2, false}, + {1, "ws.na", 2, false}, + {1, "mobi.na", 2, false}, + {1, "co.na", 2, false}, + {1, "com.na", 2, false}, + {1, "org.na", 2, false}, + {1, "name", 1, false}, + {1, "nc", 1, false}, + {1, "asso.nc", 2, false}, + {1, "nom.nc", 2, false}, + {1, "ne", 1, false}, + {1, "net", 1, false}, + {1, "nf", 1, false}, + {1, "com.nf", 2, false}, + {1, "net.nf", 2, false}, + {1, "per.nf", 2, false}, + {1, "rec.nf", 2, false}, + {1, "web.nf", 2, false}, + {1, "arts.nf", 2, false}, + {1, "firm.nf", 2, false}, + {1, "info.nf", 2, false}, + {1, "other.nf", 2, false}, + {1, "store.nf", 2, false}, + {1, "ng", 1, false}, + {1, "com.ng", 2, false}, + {1, "edu.ng", 2, false}, + {1, "gov.ng", 2, false}, + {1, "i.ng", 2, false}, + {1, "mil.ng", 2, false}, + {1, "mobi.ng", 2, false}, + {1, "name.ng", 2, false}, + {1, "net.ng", 2, false}, + {1, "org.ng", 2, false}, + {1, "sch.ng", 2, false}, + {1, "ni", 1, false}, + {1, "ac.ni", 2, false}, + {1, "biz.ni", 2, false}, + {1, "co.ni", 2, false}, + {1, "com.ni", 2, false}, + {1, "edu.ni", 2, false}, + {1, "gob.ni", 2, false}, + {1, "in.ni", 2, false}, + {1, "info.ni", 2, false}, + {1, "int.ni", 2, false}, + {1, "mil.ni", 2, false}, + {1, "net.ni", 2, false}, + {1, "nom.ni", 2, false}, + {1, "org.ni", 2, false}, + {1, "web.ni", 2, false}, + {1, "nl", 1, false}, + {1, "no", 1, false}, + {1, "fhs.no", 2, false}, + {1, "vgs.no", 2, false}, + {1, "fylkesbibl.no", 2, false}, + {1, "folkebibl.no", 2, false}, + {1, "museum.no", 2, false}, + {1, "idrett.no", 2, false}, + {1, "priv.no", 2, false}, + {1, "mil.no", 2, false}, + {1, "stat.no", 2, false}, + {1, "dep.no", 2, false}, + {1, "kommune.no", 2, false}, + {1, "herad.no", 2, false}, + {1, "aa.no", 2, false}, + {1, "ah.no", 2, false}, + {1, "bu.no", 2, false}, + {1, "fm.no", 2, false}, + {1, "hl.no", 2, false}, + {1, "hm.no", 2, false}, + {1, "jan-mayen.no", 2, false}, + {1, "mr.no", 2, false}, + {1, "nl.no", 2, false}, + {1, "nt.no", 2, false}, + {1, "of.no", 2, false}, + {1, "ol.no", 2, false}, + {1, "oslo.no", 2, false}, + {1, "rl.no", 2, false}, + {1, "sf.no", 2, false}, + {1, "st.no", 2, false}, + {1, "svalbard.no", 2, false}, + {1, "tm.no", 2, false}, + {1, "tr.no", 2, false}, + {1, "va.no", 2, false}, + {1, "vf.no", 2, false}, + {1, "gs.aa.no", 3, false}, + {1, "gs.ah.no", 3, false}, + {1, "gs.bu.no", 3, false}, + {1, "gs.fm.no", 3, false}, + {1, "gs.hl.no", 3, false}, + {1, "gs.hm.no", 3, false}, + {1, "gs.jan-mayen.no", 3, false}, + {1, "gs.mr.no", 3, false}, + {1, "gs.nl.no", 3, false}, + {1, "gs.nt.no", 3, false}, + {1, "gs.of.no", 3, false}, + {1, "gs.ol.no", 3, false}, + {1, "gs.oslo.no", 3, false}, + {1, "gs.rl.no", 3, false}, + {1, "gs.sf.no", 3, false}, + {1, "gs.st.no", 3, false}, + {1, "gs.svalbard.no", 3, false}, + {1, "gs.tm.no", 3, false}, + {1, "gs.tr.no", 3, false}, + {1, "gs.va.no", 3, false}, + {1, "gs.vf.no", 3, false}, + {1, "akrehamn.no", 2, false}, + {1, "xn--krehamn-dxa.no", 2, false}, + {1, "algard.no", 2, false}, + {1, "xn--lgrd-poac.no", 2, false}, + {1, "arna.no", 2, false}, + {1, "brumunddal.no", 2, false}, + {1, "bryne.no", 2, false}, + {1, "bronnoysund.no", 2, false}, + {1, "xn--brnnysund-m8ac.no", 2, false}, + {1, "drobak.no", 2, false}, + {1, "xn--drbak-wua.no", 2, false}, + {1, "egersund.no", 2, false}, + {1, "fetsund.no", 2, false}, + {1, "floro.no", 2, false}, + {1, "xn--flor-jra.no", 2, false}, + {1, "fredrikstad.no", 2, false}, + {1, "hokksund.no", 2, false}, + {1, "honefoss.no", 2, false}, + {1, "xn--hnefoss-q1a.no", 2, false}, + {1, "jessheim.no", 2, false}, + {1, "jorpeland.no", 2, false}, + {1, "xn--jrpeland-54a.no", 2, false}, + {1, "kirkenes.no", 2, false}, + {1, "kopervik.no", 2, false}, + {1, "krokstadelva.no", 2, false}, + {1, "langevag.no", 2, false}, + {1, "xn--langevg-jxa.no", 2, false}, + {1, "leirvik.no", 2, false}, + {1, "mjondalen.no", 2, false}, + {1, "xn--mjndalen-64a.no", 2, false}, + {1, "mo-i-rana.no", 2, false}, + {1, "mosjoen.no", 2, false}, + {1, "xn--mosjen-eya.no", 2, false}, + {1, "nesoddtangen.no", 2, false}, + {1, "orkanger.no", 2, false}, + {1, "osoyro.no", 2, false}, + {1, "xn--osyro-wua.no", 2, false}, + {1, "raholt.no", 2, false}, + {1, "xn--rholt-mra.no", 2, false}, + {1, "sandnessjoen.no", 2, false}, + {1, "xn--sandnessjen-ogb.no", 2, false}, + {1, "skedsmokorset.no", 2, false}, + {1, "slattum.no", 2, false}, + {1, "spjelkavik.no", 2, false}, + {1, "stathelle.no", 2, false}, + {1, "stavern.no", 2, false}, + {1, "stjordalshalsen.no", 2, false}, + {1, "xn--stjrdalshalsen-sqb.no", 2, false}, + {1, "tananger.no", 2, false}, + {1, "tranby.no", 2, false}, + {1, "vossevangen.no", 2, false}, + {1, "afjord.no", 2, false}, + {1, "xn--fjord-lra.no", 2, false}, + {1, "agdenes.no", 2, false}, + {1, "al.no", 2, false}, + {1, "xn--l-1fa.no", 2, false}, + {1, "alesund.no", 2, false}, + {1, "xn--lesund-hua.no", 2, false}, + {1, "alstahaug.no", 2, false}, + {1, "alta.no", 2, false}, + {1, "xn--lt-liac.no", 2, false}, + {1, "alaheadju.no", 2, false}, + {1, "xn--laheadju-7ya.no", 2, false}, + {1, "alvdal.no", 2, false}, + {1, "amli.no", 2, false}, + {1, "xn--mli-tla.no", 2, false}, + {1, "amot.no", 2, false}, + {1, "xn--mot-tla.no", 2, false}, + {1, "andebu.no", 2, false}, + {1, "andoy.no", 2, false}, + {1, "xn--andy-ira.no", 2, false}, + {1, "andasuolo.no", 2, false}, + {1, "ardal.no", 2, false}, + {1, "xn--rdal-poa.no", 2, false}, + {1, "aremark.no", 2, false}, + {1, "arendal.no", 2, false}, + {1, "xn--s-1fa.no", 2, false}, + {1, "aseral.no", 2, false}, + {1, "xn--seral-lra.no", 2, false}, + {1, "asker.no", 2, false}, + {1, "askim.no", 2, false}, + {1, "askvoll.no", 2, false}, + {1, "askoy.no", 2, false}, + {1, "xn--asky-ira.no", 2, false}, + {1, "asnes.no", 2, false}, + {1, "xn--snes-poa.no", 2, false}, + {1, "audnedaln.no", 2, false}, + {1, "aukra.no", 2, false}, + {1, "aure.no", 2, false}, + {1, "aurland.no", 2, false}, + {1, "aurskog-holand.no", 2, false}, + {1, "xn--aurskog-hland-jnb.no", 2, false}, + {1, "austevoll.no", 2, false}, + {1, "austrheim.no", 2, false}, + {1, "averoy.no", 2, false}, + {1, "xn--avery-yua.no", 2, false}, + {1, "balestrand.no", 2, false}, + {1, "ballangen.no", 2, false}, + {1, "balat.no", 2, false}, + {1, "xn--blt-elab.no", 2, false}, + {1, "balsfjord.no", 2, false}, + {1, "bahccavuotna.no", 2, false}, + {1, "xn--bhccavuotna-k7a.no", 2, false}, + {1, "bamble.no", 2, false}, + {1, "bardu.no", 2, false}, + {1, "beardu.no", 2, false}, + {1, "beiarn.no", 2, false}, + {1, "bajddar.no", 2, false}, + {1, "xn--bjddar-pta.no", 2, false}, + {1, "baidar.no", 2, false}, + {1, "xn--bidr-5nac.no", 2, false}, + {1, "berg.no", 2, false}, + {1, "bergen.no", 2, false}, + {1, "berlevag.no", 2, false}, + {1, "xn--berlevg-jxa.no", 2, false}, + {1, "bearalvahki.no", 2, false}, + {1, "xn--bearalvhki-y4a.no", 2, false}, + {1, "bindal.no", 2, false}, + {1, "birkenes.no", 2, false}, + {1, "bjarkoy.no", 2, false}, + {1, "xn--bjarky-fya.no", 2, false}, + {1, "bjerkreim.no", 2, false}, + {1, "bjugn.no", 2, false}, + {1, "bodo.no", 2, false}, + {1, "xn--bod-2na.no", 2, false}, + {1, "badaddja.no", 2, false}, + {1, "xn--bdddj-mrabd.no", 2, false}, + {1, "budejju.no", 2, false}, + {1, "bokn.no", 2, false}, + {1, "bremanger.no", 2, false}, + {1, "bronnoy.no", 2, false}, + {1, "xn--brnny-wuac.no", 2, false}, + {1, "bygland.no", 2, false}, + {1, "bykle.no", 2, false}, + {1, "barum.no", 2, false}, + {1, "xn--brum-voa.no", 2, false}, + {1, "bo.telemark.no", 3, false}, + {1, "xn--b-5ga.telemark.no", 3, false}, + {1, "bo.nordland.no", 3, false}, + {1, "xn--b-5ga.nordland.no", 3, false}, + {1, "bievat.no", 2, false}, + {1, "xn--bievt-0qa.no", 2, false}, + {1, "bomlo.no", 2, false}, + {1, "xn--bmlo-gra.no", 2, false}, + {1, "batsfjord.no", 2, false}, + {1, "xn--btsfjord-9za.no", 2, false}, + {1, "bahcavuotna.no", 2, false}, + {1, "xn--bhcavuotna-s4a.no", 2, false}, + {1, "dovre.no", 2, false}, + {1, "drammen.no", 2, false}, + {1, "drangedal.no", 2, false}, + {1, "dyroy.no", 2, false}, + {1, "xn--dyry-ira.no", 2, false}, + {1, "donna.no", 2, false}, + {1, "xn--dnna-gra.no", 2, false}, + {1, "eid.no", 2, false}, + {1, "eidfjord.no", 2, false}, + {1, "eidsberg.no", 2, false}, + {1, "eidskog.no", 2, false}, + {1, "eidsvoll.no", 2, false}, + {1, "eigersund.no", 2, false}, + {1, "elverum.no", 2, false}, + {1, "enebakk.no", 2, false}, + {1, "engerdal.no", 2, false}, + {1, "etne.no", 2, false}, + {1, "etnedal.no", 2, false}, + {1, "evenes.no", 2, false}, + {1, "evenassi.no", 2, false}, + {1, "xn--eveni-0qa01ga.no", 2, false}, + {1, "evje-og-hornnes.no", 2, false}, + {1, "farsund.no", 2, false}, + {1, "fauske.no", 2, false}, + {1, "fuossko.no", 2, false}, + {1, "fuoisku.no", 2, false}, + {1, "fedje.no", 2, false}, + {1, "fet.no", 2, false}, + {1, "finnoy.no", 2, false}, + {1, "xn--finny-yua.no", 2, false}, + {1, "fitjar.no", 2, false}, + {1, "fjaler.no", 2, false}, + {1, "fjell.no", 2, false}, + {1, "flakstad.no", 2, false}, + {1, "flatanger.no", 2, false}, + {1, "flekkefjord.no", 2, false}, + {1, "flesberg.no", 2, false}, + {1, "flora.no", 2, false}, + {1, "fla.no", 2, false}, + {1, "xn--fl-zia.no", 2, false}, + {1, "folldal.no", 2, false}, + {1, "forsand.no", 2, false}, + {1, "fosnes.no", 2, false}, + {1, "frei.no", 2, false}, + {1, "frogn.no", 2, false}, + {1, "froland.no", 2, false}, + {1, "frosta.no", 2, false}, + {1, "frana.no", 2, false}, + {1, "xn--frna-woa.no", 2, false}, + {1, "froya.no", 2, false}, + {1, "xn--frya-hra.no", 2, false}, + {1, "fusa.no", 2, false}, + {1, "fyresdal.no", 2, false}, + {1, "forde.no", 2, false}, + {1, "xn--frde-gra.no", 2, false}, + {1, "gamvik.no", 2, false}, + {1, "gangaviika.no", 2, false}, + {1, "xn--ggaviika-8ya47h.no", 2, false}, + {1, "gaular.no", 2, false}, + {1, "gausdal.no", 2, false}, + {1, "gildeskal.no", 2, false}, + {1, "xn--gildeskl-g0a.no", 2, false}, + {1, "giske.no", 2, false}, + {1, "gjemnes.no", 2, false}, + {1, "gjerdrum.no", 2, false}, + {1, "gjerstad.no", 2, false}, + {1, "gjesdal.no", 2, false}, + {1, "gjovik.no", 2, false}, + {1, "xn--gjvik-wua.no", 2, false}, + {1, "gloppen.no", 2, false}, + {1, "gol.no", 2, false}, + {1, "gran.no", 2, false}, + {1, "grane.no", 2, false}, + {1, "granvin.no", 2, false}, + {1, "gratangen.no", 2, false}, + {1, "grimstad.no", 2, false}, + {1, "grong.no", 2, false}, + {1, "kraanghke.no", 2, false}, + {1, "xn--kranghke-b0a.no", 2, false}, + {1, "grue.no", 2, false}, + {1, "gulen.no", 2, false}, + {1, "hadsel.no", 2, false}, + {1, "halden.no", 2, false}, + {1, "halsa.no", 2, false}, + {1, "hamar.no", 2, false}, + {1, "hamaroy.no", 2, false}, + {1, "habmer.no", 2, false}, + {1, "xn--hbmer-xqa.no", 2, false}, + {1, "hapmir.no", 2, false}, + {1, "xn--hpmir-xqa.no", 2, false}, + {1, "hammerfest.no", 2, false}, + {1, "hammarfeasta.no", 2, false}, + {1, "xn--hmmrfeasta-s4ac.no", 2, false}, + {1, "haram.no", 2, false}, + {1, "hareid.no", 2, false}, + {1, "harstad.no", 2, false}, + {1, "hasvik.no", 2, false}, + {1, "aknoluokta.no", 2, false}, + {1, "xn--koluokta-7ya57h.no", 2, false}, + {1, "hattfjelldal.no", 2, false}, + {1, "aarborte.no", 2, false}, + {1, "haugesund.no", 2, false}, + {1, "hemne.no", 2, false}, + {1, "hemnes.no", 2, false}, + {1, "hemsedal.no", 2, false}, + {1, "heroy.more-og-romsdal.no", 3, false}, + {1, "xn--hery-ira.xn--mre-og-romsdal-qqb.no", 3, false}, + {1, "heroy.nordland.no", 3, false}, + {1, "xn--hery-ira.nordland.no", 3, false}, + {1, "hitra.no", 2, false}, + {1, "hjartdal.no", 2, false}, + {1, "hjelmeland.no", 2, false}, + {1, "hobol.no", 2, false}, + {1, "xn--hobl-ira.no", 2, false}, + {1, "hof.no", 2, false}, + {1, "hol.no", 2, false}, + {1, "hole.no", 2, false}, + {1, "holmestrand.no", 2, false}, + {1, "holtalen.no", 2, false}, + {1, "xn--holtlen-hxa.no", 2, false}, + {1, "hornindal.no", 2, false}, + {1, "horten.no", 2, false}, + {1, "hurdal.no", 2, false}, + {1, "hurum.no", 2, false}, + {1, "hvaler.no", 2, false}, + {1, "hyllestad.no", 2, false}, + {1, "hagebostad.no", 2, false}, + {1, "xn--hgebostad-g3a.no", 2, false}, + {1, "hoyanger.no", 2, false}, + {1, "xn--hyanger-q1a.no", 2, false}, + {1, "hoylandet.no", 2, false}, + {1, "xn--hylandet-54a.no", 2, false}, + {1, "ha.no", 2, false}, + {1, "xn--h-2fa.no", 2, false}, + {1, "ibestad.no", 2, false}, + {1, "inderoy.no", 2, false}, + {1, "xn--indery-fya.no", 2, false}, + {1, "iveland.no", 2, false}, + {1, "jevnaker.no", 2, false}, + {1, "jondal.no", 2, false}, + {1, "jolster.no", 2, false}, + {1, "xn--jlster-bya.no", 2, false}, + {1, "karasjok.no", 2, false}, + {1, "karasjohka.no", 2, false}, + {1, "xn--krjohka-hwab49j.no", 2, false}, + {1, "karlsoy.no", 2, false}, + {1, "galsa.no", 2, false}, + {1, "xn--gls-elac.no", 2, false}, + {1, "karmoy.no", 2, false}, + {1, "xn--karmy-yua.no", 2, false}, + {1, "kautokeino.no", 2, false}, + {1, "guovdageaidnu.no", 2, false}, + {1, "klepp.no", 2, false}, + {1, "klabu.no", 2, false}, + {1, "xn--klbu-woa.no", 2, false}, + {1, "kongsberg.no", 2, false}, + {1, "kongsvinger.no", 2, false}, + {1, "kragero.no", 2, false}, + {1, "xn--krager-gya.no", 2, false}, + {1, "kristiansand.no", 2, false}, + {1, "kristiansund.no", 2, false}, + {1, "krodsherad.no", 2, false}, + {1, "xn--krdsherad-m8a.no", 2, false}, + {1, "kvalsund.no", 2, false}, + {1, "rahkkeravju.no", 2, false}, + {1, "xn--rhkkervju-01af.no", 2, false}, + {1, "kvam.no", 2, false}, + {1, "kvinesdal.no", 2, false}, + {1, "kvinnherad.no", 2, false}, + {1, "kviteseid.no", 2, false}, + {1, "kvitsoy.no", 2, false}, + {1, "xn--kvitsy-fya.no", 2, false}, + {1, "kvafjord.no", 2, false}, + {1, "xn--kvfjord-nxa.no", 2, false}, + {1, "giehtavuoatna.no", 2, false}, + {1, "kvanangen.no", 2, false}, + {1, "xn--kvnangen-k0a.no", 2, false}, + {1, "navuotna.no", 2, false}, + {1, "xn--nvuotna-hwa.no", 2, false}, + {1, "kafjord.no", 2, false}, + {1, "xn--kfjord-iua.no", 2, false}, + {1, "gaivuotna.no", 2, false}, + {1, "xn--givuotna-8ya.no", 2, false}, + {1, "larvik.no", 2, false}, + {1, "lavangen.no", 2, false}, + {1, "lavagis.no", 2, false}, + {1, "loabat.no", 2, false}, + {1, "xn--loabt-0qa.no", 2, false}, + {1, "lebesby.no", 2, false}, + {1, "davvesiida.no", 2, false}, + {1, "leikanger.no", 2, false}, + {1, "leirfjord.no", 2, false}, + {1, "leka.no", 2, false}, + {1, "leksvik.no", 2, false}, + {1, "lenvik.no", 2, false}, + {1, "leangaviika.no", 2, false}, + {1, "xn--leagaviika-52b.no", 2, false}, + {1, "lesja.no", 2, false}, + {1, "levanger.no", 2, false}, + {1, "lier.no", 2, false}, + {1, "lierne.no", 2, false}, + {1, "lillehammer.no", 2, false}, + {1, "lillesand.no", 2, false}, + {1, "lindesnes.no", 2, false}, + {1, "lindas.no", 2, false}, + {1, "xn--linds-pra.no", 2, false}, + {1, "lom.no", 2, false}, + {1, "loppa.no", 2, false}, + {1, "lahppi.no", 2, false}, + {1, "xn--lhppi-xqa.no", 2, false}, + {1, "lund.no", 2, false}, + {1, "lunner.no", 2, false}, + {1, "luroy.no", 2, false}, + {1, "xn--lury-ira.no", 2, false}, + {1, "luster.no", 2, false}, + {1, "lyngdal.no", 2, false}, + {1, "lyngen.no", 2, false}, + {1, "ivgu.no", 2, false}, + {1, "lardal.no", 2, false}, + {1, "lerdal.no", 2, false}, + {1, "xn--lrdal-sra.no", 2, false}, + {1, "lodingen.no", 2, false}, + {1, "xn--ldingen-q1a.no", 2, false}, + {1, "lorenskog.no", 2, false}, + {1, "xn--lrenskog-54a.no", 2, false}, + {1, "loten.no", 2, false}, + {1, "xn--lten-gra.no", 2, false}, + {1, "malvik.no", 2, false}, + {1, "masoy.no", 2, false}, + {1, "xn--msy-ula0h.no", 2, false}, + {1, "muosat.no", 2, false}, + {1, "xn--muost-0qa.no", 2, false}, + {1, "mandal.no", 2, false}, + {1, "marker.no", 2, false}, + {1, "marnardal.no", 2, false}, + {1, "masfjorden.no", 2, false}, + {1, "meland.no", 2, false}, + {1, "meldal.no", 2, false}, + {1, "melhus.no", 2, false}, + {1, "meloy.no", 2, false}, + {1, "xn--mely-ira.no", 2, false}, + {1, "meraker.no", 2, false}, + {1, "xn--merker-kua.no", 2, false}, + {1, "moareke.no", 2, false}, + {1, "xn--moreke-jua.no", 2, false}, + {1, "midsund.no", 2, false}, + {1, "midtre-gauldal.no", 2, false}, + {1, "modalen.no", 2, false}, + {1, "modum.no", 2, false}, + {1, "molde.no", 2, false}, + {1, "moskenes.no", 2, false}, + {1, "moss.no", 2, false}, + {1, "mosvik.no", 2, false}, + {1, "malselv.no", 2, false}, + {1, "xn--mlselv-iua.no", 2, false}, + {1, "malatvuopmi.no", 2, false}, + {1, "xn--mlatvuopmi-s4a.no", 2, false}, + {1, "namdalseid.no", 2, false}, + {1, "aejrie.no", 2, false}, + {1, "namsos.no", 2, false}, + {1, "namsskogan.no", 2, false}, + {1, "naamesjevuemie.no", 2, false}, + {1, "xn--nmesjevuemie-tcba.no", 2, false}, + {1, "laakesvuemie.no", 2, false}, + {1, "nannestad.no", 2, false}, + {1, "narvik.no", 2, false}, + {1, "narviika.no", 2, false}, + {1, "naustdal.no", 2, false}, + {1, "nedre-eiker.no", 2, false}, + {1, "nes.akershus.no", 3, false}, + {1, "nes.buskerud.no", 3, false}, + {1, "nesna.no", 2, false}, + {1, "nesodden.no", 2, false}, + {1, "nesseby.no", 2, false}, + {1, "unjarga.no", 2, false}, + {1, "xn--unjrga-rta.no", 2, false}, + {1, "nesset.no", 2, false}, + {1, "nissedal.no", 2, false}, + {1, "nittedal.no", 2, false}, + {1, "nord-aurdal.no", 2, false}, + {1, "nord-fron.no", 2, false}, + {1, "nord-odal.no", 2, false}, + {1, "norddal.no", 2, false}, + {1, "nordkapp.no", 2, false}, + {1, "davvenjarga.no", 2, false}, + {1, "xn--davvenjrga-y4a.no", 2, false}, + {1, "nordre-land.no", 2, false}, + {1, "nordreisa.no", 2, false}, + {1, "raisa.no", 2, false}, + {1, "xn--risa-5na.no", 2, false}, + {1, "nore-og-uvdal.no", 2, false}, + {1, "notodden.no", 2, false}, + {1, "naroy.no", 2, false}, + {1, "xn--nry-yla5g.no", 2, false}, + {1, "notteroy.no", 2, false}, + {1, "xn--nttery-byae.no", 2, false}, + {1, "odda.no", 2, false}, + {1, "oksnes.no", 2, false}, + {1, "xn--ksnes-uua.no", 2, false}, + {1, "oppdal.no", 2, false}, + {1, "oppegard.no", 2, false}, + {1, "xn--oppegrd-ixa.no", 2, false}, + {1, "orkdal.no", 2, false}, + {1, "orland.no", 2, false}, + {1, "xn--rland-uua.no", 2, false}, + {1, "orskog.no", 2, false}, + {1, "xn--rskog-uua.no", 2, false}, + {1, "orsta.no", 2, false}, + {1, "xn--rsta-fra.no", 2, false}, + {1, "os.hedmark.no", 3, false}, + {1, "os.hordaland.no", 3, false}, + {1, "osen.no", 2, false}, + {1, "osteroy.no", 2, false}, + {1, "xn--ostery-fya.no", 2, false}, + {1, "ostre-toten.no", 2, false}, + {1, "xn--stre-toten-zcb.no", 2, false}, + {1, "overhalla.no", 2, false}, + {1, "ovre-eiker.no", 2, false}, + {1, "xn--vre-eiker-k8a.no", 2, false}, + {1, "oyer.no", 2, false}, + {1, "xn--yer-zna.no", 2, false}, + {1, "oygarden.no", 2, false}, + {1, "xn--ygarden-p1a.no", 2, false}, + {1, "oystre-slidre.no", 2, false}, + {1, "xn--ystre-slidre-ujb.no", 2, false}, + {1, "porsanger.no", 2, false}, + {1, "porsangu.no", 2, false}, + {1, "xn--porsgu-sta26f.no", 2, false}, + {1, "porsgrunn.no", 2, false}, + {1, "radoy.no", 2, false}, + {1, "xn--rady-ira.no", 2, false}, + {1, "rakkestad.no", 2, false}, + {1, "rana.no", 2, false}, + {1, "ruovat.no", 2, false}, + {1, "randaberg.no", 2, false}, + {1, "rauma.no", 2, false}, + {1, "rendalen.no", 2, false}, + {1, "rennebu.no", 2, false}, + {1, "rennesoy.no", 2, false}, + {1, "xn--rennesy-v1a.no", 2, false}, + {1, "rindal.no", 2, false}, + {1, "ringebu.no", 2, false}, + {1, "ringerike.no", 2, false}, + {1, "ringsaker.no", 2, false}, + {1, "rissa.no", 2, false}, + {1, "risor.no", 2, false}, + {1, "xn--risr-ira.no", 2, false}, + {1, "roan.no", 2, false}, + {1, "rollag.no", 2, false}, + {1, "rygge.no", 2, false}, + {1, "ralingen.no", 2, false}, + {1, "xn--rlingen-mxa.no", 2, false}, + {1, "rodoy.no", 2, false}, + {1, "xn--rdy-0nab.no", 2, false}, + {1, "romskog.no", 2, false}, + {1, "xn--rmskog-bya.no", 2, false}, + {1, "roros.no", 2, false}, + {1, "xn--rros-gra.no", 2, false}, + {1, "rost.no", 2, false}, + {1, "xn--rst-0na.no", 2, false}, + {1, "royken.no", 2, false}, + {1, "xn--ryken-vua.no", 2, false}, + {1, "royrvik.no", 2, false}, + {1, "xn--ryrvik-bya.no", 2, false}, + {1, "rade.no", 2, false}, + {1, "xn--rde-ula.no", 2, false}, + {1, "salangen.no", 2, false}, + {1, "siellak.no", 2, false}, + {1, "saltdal.no", 2, false}, + {1, "salat.no", 2, false}, + {1, "xn--slt-elab.no", 2, false}, + {1, "xn--slat-5na.no", 2, false}, + {1, "samnanger.no", 2, false}, + {1, "sande.more-og-romsdal.no", 3, false}, + {1, "sande.xn--mre-og-romsdal-qqb.no", 3, false}, + {1, "sande.vestfold.no", 3, false}, + {1, "sandefjord.no", 2, false}, + {1, "sandnes.no", 2, false}, + {1, "sandoy.no", 2, false}, + {1, "xn--sandy-yua.no", 2, false}, + {1, "sarpsborg.no", 2, false}, + {1, "sauda.no", 2, false}, + {1, "sauherad.no", 2, false}, + {1, "sel.no", 2, false}, + {1, "selbu.no", 2, false}, + {1, "selje.no", 2, false}, + {1, "seljord.no", 2, false}, + {1, "sigdal.no", 2, false}, + {1, "siljan.no", 2, false}, + {1, "sirdal.no", 2, false}, + {1, "skaun.no", 2, false}, + {1, "skedsmo.no", 2, false}, + {1, "ski.no", 2, false}, + {1, "skien.no", 2, false}, + {1, "skiptvet.no", 2, false}, + {1, "skjervoy.no", 2, false}, + {1, "xn--skjervy-v1a.no", 2, false}, + {1, "skierva.no", 2, false}, + {1, "xn--skierv-uta.no", 2, false}, + {1, "skjak.no", 2, false}, + {1, "xn--skjk-soa.no", 2, false}, + {1, "skodje.no", 2, false}, + {1, "skanland.no", 2, false}, + {1, "xn--sknland-fxa.no", 2, false}, + {1, "skanit.no", 2, false}, + {1, "xn--sknit-yqa.no", 2, false}, + {1, "smola.no", 2, false}, + {1, "xn--smla-hra.no", 2, false}, + {1, "snillfjord.no", 2, false}, + {1, "snasa.no", 2, false}, + {1, "xn--snsa-roa.no", 2, false}, + {1, "snoasa.no", 2, false}, + {1, "snaase.no", 2, false}, + {1, "xn--snase-nra.no", 2, false}, + {1, "sogndal.no", 2, false}, + {1, "sokndal.no", 2, false}, + {1, "sola.no", 2, false}, + {1, "solund.no", 2, false}, + {1, "songdalen.no", 2, false}, + {1, "sortland.no", 2, false}, + {1, "spydeberg.no", 2, false}, + {1, "stange.no", 2, false}, + {1, "stavanger.no", 2, false}, + {1, "steigen.no", 2, false}, + {1, "steinkjer.no", 2, false}, + {1, "stjordal.no", 2, false}, + {1, "xn--stjrdal-s1a.no", 2, false}, + {1, "stokke.no", 2, false}, + {1, "stor-elvdal.no", 2, false}, + {1, "stord.no", 2, false}, + {1, "stordal.no", 2, false}, + {1, "storfjord.no", 2, false}, + {1, "omasvuotna.no", 2, false}, + {1, "strand.no", 2, false}, + {1, "stranda.no", 2, false}, + {1, "stryn.no", 2, false}, + {1, "sula.no", 2, false}, + {1, "suldal.no", 2, false}, + {1, "sund.no", 2, false}, + {1, "sunndal.no", 2, false}, + {1, "surnadal.no", 2, false}, + {1, "sveio.no", 2, false}, + {1, "svelvik.no", 2, false}, + {1, "sykkylven.no", 2, false}, + {1, "sogne.no", 2, false}, + {1, "xn--sgne-gra.no", 2, false}, + {1, "somna.no", 2, false}, + {1, "xn--smna-gra.no", 2, false}, + {1, "sondre-land.no", 2, false}, + {1, "xn--sndre-land-0cb.no", 2, false}, + {1, "sor-aurdal.no", 2, false}, + {1, "xn--sr-aurdal-l8a.no", 2, false}, + {1, "sor-fron.no", 2, false}, + {1, "xn--sr-fron-q1a.no", 2, false}, + {1, "sor-odal.no", 2, false}, + {1, "xn--sr-odal-q1a.no", 2, false}, + {1, "sor-varanger.no", 2, false}, + {1, "xn--sr-varanger-ggb.no", 2, false}, + {1, "matta-varjjat.no", 2, false}, + {1, "xn--mtta-vrjjat-k7af.no", 2, false}, + {1, "sorfold.no", 2, false}, + {1, "xn--srfold-bya.no", 2, false}, + {1, "sorreisa.no", 2, false}, + {1, "xn--srreisa-q1a.no", 2, false}, + {1, "sorum.no", 2, false}, + {1, "xn--srum-gra.no", 2, false}, + {1, "tana.no", 2, false}, + {1, "deatnu.no", 2, false}, + {1, "time.no", 2, false}, + {1, "tingvoll.no", 2, false}, + {1, "tinn.no", 2, false}, + {1, "tjeldsund.no", 2, false}, + {1, "dielddanuorri.no", 2, false}, + {1, "tjome.no", 2, false}, + {1, "xn--tjme-hra.no", 2, false}, + {1, "tokke.no", 2, false}, + {1, "tolga.no", 2, false}, + {1, "torsken.no", 2, false}, + {1, "tranoy.no", 2, false}, + {1, "xn--trany-yua.no", 2, false}, + {1, "tromso.no", 2, false}, + {1, "xn--troms-zua.no", 2, false}, + {1, "tromsa.no", 2, false}, + {1, "romsa.no", 2, false}, + {1, "trondheim.no", 2, false}, + {1, "troandin.no", 2, false}, + {1, "trysil.no", 2, false}, + {1, "trana.no", 2, false}, + {1, "xn--trna-woa.no", 2, false}, + {1, "trogstad.no", 2, false}, + {1, "xn--trgstad-r1a.no", 2, false}, + {1, "tvedestrand.no", 2, false}, + {1, "tydal.no", 2, false}, + {1, "tynset.no", 2, false}, + {1, "tysfjord.no", 2, false}, + {1, "divtasvuodna.no", 2, false}, + {1, "divttasvuotna.no", 2, false}, + {1, "tysnes.no", 2, false}, + {1, "tysvar.no", 2, false}, + {1, "xn--tysvr-vra.no", 2, false}, + {1, "tonsberg.no", 2, false}, + {1, "xn--tnsberg-q1a.no", 2, false}, + {1, "ullensaker.no", 2, false}, + {1, "ullensvang.no", 2, false}, + {1, "ulvik.no", 2, false}, + {1, "utsira.no", 2, false}, + {1, "vadso.no", 2, false}, + {1, "xn--vads-jra.no", 2, false}, + {1, "cahcesuolo.no", 2, false}, + {1, "xn--hcesuolo-7ya35b.no", 2, false}, + {1, "vaksdal.no", 2, false}, + {1, "valle.no", 2, false}, + {1, "vang.no", 2, false}, + {1, "vanylven.no", 2, false}, + {1, "vardo.no", 2, false}, + {1, "xn--vard-jra.no", 2, false}, + {1, "varggat.no", 2, false}, + {1, "xn--vrggt-xqad.no", 2, false}, + {1, "vefsn.no", 2, false}, + {1, "vaapste.no", 2, false}, + {1, "vega.no", 2, false}, + {1, "vegarshei.no", 2, false}, + {1, "xn--vegrshei-c0a.no", 2, false}, + {1, "vennesla.no", 2, false}, + {1, "verdal.no", 2, false}, + {1, "verran.no", 2, false}, + {1, "vestby.no", 2, false}, + {1, "vestnes.no", 2, false}, + {1, "vestre-slidre.no", 2, false}, + {1, "vestre-toten.no", 2, false}, + {1, "vestvagoy.no", 2, false}, + {1, "xn--vestvgy-ixa6o.no", 2, false}, + {1, "vevelstad.no", 2, false}, + {1, "vik.no", 2, false}, + {1, "vikna.no", 2, false}, + {1, "vindafjord.no", 2, false}, + {1, "volda.no", 2, false}, + {1, "voss.no", 2, false}, + {1, "varoy.no", 2, false}, + {1, "xn--vry-yla5g.no", 2, false}, + {1, "vagan.no", 2, false}, + {1, "xn--vgan-qoa.no", 2, false}, + {1, "voagat.no", 2, false}, + {1, "vagsoy.no", 2, false}, + {1, "xn--vgsy-qoa0j.no", 2, false}, + {1, "vaga.no", 2, false}, + {1, "xn--vg-yiab.no", 2, false}, + {1, "valer.ostfold.no", 3, false}, + {1, "xn--vler-qoa.xn--stfold-9xa.no", 3, false}, + {1, "valer.hedmark.no", 3, false}, + {1, "xn--vler-qoa.hedmark.no", 3, false}, + {2, "np", 2, false}, + {1, "nr", 1, false}, + {1, "biz.nr", 2, false}, + {1, "info.nr", 2, false}, + {1, "gov.nr", 2, false}, + {1, "edu.nr", 2, false}, + {1, "org.nr", 2, false}, + {1, "net.nr", 2, false}, + {1, "com.nr", 2, false}, + {1, "nu", 1, false}, + {1, "nz", 1, false}, + {1, "ac.nz", 2, false}, + {1, "co.nz", 2, false}, + {1, "cri.nz", 2, false}, + {1, "geek.nz", 2, false}, + {1, "gen.nz", 2, false}, + {1, "govt.nz", 2, false}, + {1, "health.nz", 2, false}, + {1, "iwi.nz", 2, false}, + {1, "kiwi.nz", 2, false}, + {1, "maori.nz", 2, false}, + {1, "mil.nz", 2, false}, + {1, "xn--mori-qsa.nz", 2, false}, + {1, "net.nz", 2, false}, + {1, "org.nz", 2, false}, + {1, "parliament.nz", 2, false}, + {1, "school.nz", 2, false}, + {1, "om", 1, false}, + {1, "co.om", 2, false}, + {1, "com.om", 2, false}, + {1, "edu.om", 2, false}, + {1, "gov.om", 2, false}, + {1, "med.om", 2, false}, + {1, "museum.om", 2, false}, + {1, "net.om", 2, false}, + {1, "org.om", 2, false}, + {1, "pro.om", 2, false}, + {1, "onion", 1, false}, + {1, "org", 1, false}, + {1, "pa", 1, false}, + {1, "ac.pa", 2, false}, + {1, "gob.pa", 2, false}, + {1, "com.pa", 2, false}, + {1, "org.pa", 2, false}, + {1, "sld.pa", 2, false}, + {1, "edu.pa", 2, false}, + {1, "net.pa", 2, false}, + {1, "ing.pa", 2, false}, + {1, "abo.pa", 2, false}, + {1, "med.pa", 2, false}, + {1, "nom.pa", 2, false}, + {1, "pe", 1, false}, + {1, "edu.pe", 2, false}, + {1, "gob.pe", 2, false}, + {1, "nom.pe", 2, false}, + {1, "mil.pe", 2, false}, + {1, "org.pe", 2, false}, + {1, "com.pe", 2, false}, + {1, "net.pe", 2, false}, + {1, "pf", 1, false}, + {1, "com.pf", 2, false}, + {1, "org.pf", 2, false}, + {1, "edu.pf", 2, false}, + {2, "pg", 2, false}, + {1, "ph", 1, false}, + {1, "com.ph", 2, false}, + {1, "net.ph", 2, false}, + {1, "org.ph", 2, false}, + {1, "gov.ph", 2, false}, + {1, "edu.ph", 2, false}, + {1, "ngo.ph", 2, false}, + {1, "mil.ph", 2, false}, + {1, "i.ph", 2, false}, + {1, "pk", 1, false}, + {1, "com.pk", 2, false}, + {1, "net.pk", 2, false}, + {1, "edu.pk", 2, false}, + {1, "org.pk", 2, false}, + {1, "fam.pk", 2, false}, + {1, "biz.pk", 2, false}, + {1, "web.pk", 2, false}, + {1, "gov.pk", 2, false}, + {1, "gob.pk", 2, false}, + {1, "gok.pk", 2, false}, + {1, "gon.pk", 2, false}, + {1, "gop.pk", 2, false}, + {1, "gos.pk", 2, false}, + {1, "info.pk", 2, false}, + {1, "pl", 1, false}, + {1, "com.pl", 2, false}, + {1, "net.pl", 2, false}, + {1, "org.pl", 2, false}, + {1, "aid.pl", 2, false}, + {1, "agro.pl", 2, false}, + {1, "atm.pl", 2, false}, + {1, "auto.pl", 2, false}, + {1, "biz.pl", 2, false}, + {1, "edu.pl", 2, false}, + {1, "gmina.pl", 2, false}, + {1, "gsm.pl", 2, false}, + {1, "info.pl", 2, false}, + {1, "mail.pl", 2, false}, + {1, "miasta.pl", 2, false}, + {1, "media.pl", 2, false}, + {1, "mil.pl", 2, false}, + {1, "nieruchomosci.pl", 2, false}, + {1, "nom.pl", 2, false}, + {1, "pc.pl", 2, false}, + {1, "powiat.pl", 2, false}, + {1, "priv.pl", 2, false}, + {1, "realestate.pl", 2, false}, + {1, "rel.pl", 2, false}, + {1, "sex.pl", 2, false}, + {1, "shop.pl", 2, false}, + {1, "sklep.pl", 2, false}, + {1, "sos.pl", 2, false}, + {1, "szkola.pl", 2, false}, + {1, "targi.pl", 2, false}, + {1, "tm.pl", 2, false}, + {1, "tourism.pl", 2, false}, + {1, "travel.pl", 2, false}, + {1, "turystyka.pl", 2, false}, + {1, "gov.pl", 2, false}, + {1, "ap.gov.pl", 3, false}, + {1, "ic.gov.pl", 3, false}, + {1, "is.gov.pl", 3, false}, + {1, "us.gov.pl", 3, false}, + {1, "kmpsp.gov.pl", 3, false}, + {1, "kppsp.gov.pl", 3, false}, + {1, "kwpsp.gov.pl", 3, false}, + {1, "psp.gov.pl", 3, false}, + {1, "wskr.gov.pl", 3, false}, + {1, "kwp.gov.pl", 3, false}, + {1, "mw.gov.pl", 3, false}, + {1, "ug.gov.pl", 3, false}, + {1, "um.gov.pl", 3, false}, + {1, "umig.gov.pl", 3, false}, + {1, "ugim.gov.pl", 3, false}, + {1, "upow.gov.pl", 3, false}, + {1, "uw.gov.pl", 3, false}, + {1, "starostwo.gov.pl", 3, false}, + {1, "pa.gov.pl", 3, false}, + {1, "po.gov.pl", 3, false}, + {1, "psse.gov.pl", 3, false}, + {1, "pup.gov.pl", 3, false}, + {1, "rzgw.gov.pl", 3, false}, + {1, "sa.gov.pl", 3, false}, + {1, "so.gov.pl", 3, false}, + {1, "sr.gov.pl", 3, false}, + {1, "wsa.gov.pl", 3, false}, + {1, "sko.gov.pl", 3, false}, + {1, "uzs.gov.pl", 3, false}, + {1, "wiih.gov.pl", 3, false}, + {1, "winb.gov.pl", 3, false}, + {1, "pinb.gov.pl", 3, false}, + {1, "wios.gov.pl", 3, false}, + {1, "witd.gov.pl", 3, false}, + {1, "wzmiuw.gov.pl", 3, false}, + {1, "piw.gov.pl", 3, false}, + {1, "wiw.gov.pl", 3, false}, + {1, "griw.gov.pl", 3, false}, + {1, "wif.gov.pl", 3, false}, + {1, "oum.gov.pl", 3, false}, + {1, "sdn.gov.pl", 3, false}, + {1, "zp.gov.pl", 3, false}, + {1, "uppo.gov.pl", 3, false}, + {1, "mup.gov.pl", 3, false}, + {1, "wuoz.gov.pl", 3, false}, + {1, "konsulat.gov.pl", 3, false}, + {1, "oirm.gov.pl", 3, false}, + {1, "augustow.pl", 2, false}, + {1, "babia-gora.pl", 2, false}, + {1, "bedzin.pl", 2, false}, + {1, "beskidy.pl", 2, false}, + {1, "bialowieza.pl", 2, false}, + {1, "bialystok.pl", 2, false}, + {1, "bielawa.pl", 2, false}, + {1, "bieszczady.pl", 2, false}, + {1, "boleslawiec.pl", 2, false}, + {1, "bydgoszcz.pl", 2, false}, + {1, "bytom.pl", 2, false}, + {1, "cieszyn.pl", 2, false}, + {1, "czeladz.pl", 2, false}, + {1, "czest.pl", 2, false}, + {1, "dlugoleka.pl", 2, false}, + {1, "elblag.pl", 2, false}, + {1, "elk.pl", 2, false}, + {1, "glogow.pl", 2, false}, + {1, "gniezno.pl", 2, false}, + {1, "gorlice.pl", 2, false}, + {1, "grajewo.pl", 2, false}, + {1, "ilawa.pl", 2, false}, + {1, "jaworzno.pl", 2, false}, + {1, "jelenia-gora.pl", 2, false}, + {1, "jgora.pl", 2, false}, + {1, "kalisz.pl", 2, false}, + {1, "kazimierz-dolny.pl", 2, false}, + {1, "karpacz.pl", 2, false}, + {1, "kartuzy.pl", 2, false}, + {1, "kaszuby.pl", 2, false}, + {1, "katowice.pl", 2, false}, + {1, "kepno.pl", 2, false}, + {1, "ketrzyn.pl", 2, false}, + {1, "klodzko.pl", 2, false}, + {1, "kobierzyce.pl", 2, false}, + {1, "kolobrzeg.pl", 2, false}, + {1, "konin.pl", 2, false}, + {1, "konskowola.pl", 2, false}, + {1, "kutno.pl", 2, false}, + {1, "lapy.pl", 2, false}, + {1, "lebork.pl", 2, false}, + {1, "legnica.pl", 2, false}, + {1, "lezajsk.pl", 2, false}, + {1, "limanowa.pl", 2, false}, + {1, "lomza.pl", 2, false}, + {1, "lowicz.pl", 2, false}, + {1, "lubin.pl", 2, false}, + {1, "lukow.pl", 2, false}, + {1, "malbork.pl", 2, false}, + {1, "malopolska.pl", 2, false}, + {1, "mazowsze.pl", 2, false}, + {1, "mazury.pl", 2, false}, + {1, "mielec.pl", 2, false}, + {1, "mielno.pl", 2, false}, + {1, "mragowo.pl", 2, false}, + {1, "naklo.pl", 2, false}, + {1, "nowaruda.pl", 2, false}, + {1, "nysa.pl", 2, false}, + {1, "olawa.pl", 2, false}, + {1, "olecko.pl", 2, false}, + {1, "olkusz.pl", 2, false}, + {1, "olsztyn.pl", 2, false}, + {1, "opoczno.pl", 2, false}, + {1, "opole.pl", 2, false}, + {1, "ostroda.pl", 2, false}, + {1, "ostroleka.pl", 2, false}, + {1, "ostrowiec.pl", 2, false}, + {1, "ostrowwlkp.pl", 2, false}, + {1, "pila.pl", 2, false}, + {1, "pisz.pl", 2, false}, + {1, "podhale.pl", 2, false}, + {1, "podlasie.pl", 2, false}, + {1, "polkowice.pl", 2, false}, + {1, "pomorze.pl", 2, false}, + {1, "pomorskie.pl", 2, false}, + {1, "prochowice.pl", 2, false}, + {1, "pruszkow.pl", 2, false}, + {1, "przeworsk.pl", 2, false}, + {1, "pulawy.pl", 2, false}, + {1, "radom.pl", 2, false}, + {1, "rawa-maz.pl", 2, false}, + {1, "rybnik.pl", 2, false}, + {1, "rzeszow.pl", 2, false}, + {1, "sanok.pl", 2, false}, + {1, "sejny.pl", 2, false}, + {1, "slask.pl", 2, false}, + {1, "slupsk.pl", 2, false}, + {1, "sosnowiec.pl", 2, false}, + {1, "stalowa-wola.pl", 2, false}, + {1, "skoczow.pl", 2, false}, + {1, "starachowice.pl", 2, false}, + {1, "stargard.pl", 2, false}, + {1, "suwalki.pl", 2, false}, + {1, "swidnica.pl", 2, false}, + {1, "swiebodzin.pl", 2, false}, + {1, "swinoujscie.pl", 2, false}, + {1, "szczecin.pl", 2, false}, + {1, "szczytno.pl", 2, false}, + {1, "tarnobrzeg.pl", 2, false}, + {1, "tgory.pl", 2, false}, + {1, "turek.pl", 2, false}, + {1, "tychy.pl", 2, false}, + {1, "ustka.pl", 2, false}, + {1, "walbrzych.pl", 2, false}, + {1, "warmia.pl", 2, false}, + {1, "warszawa.pl", 2, false}, + {1, "waw.pl", 2, false}, + {1, "wegrow.pl", 2, false}, + {1, "wielun.pl", 2, false}, + {1, "wlocl.pl", 2, false}, + {1, "wloclawek.pl", 2, false}, + {1, "wodzislaw.pl", 2, false}, + {1, "wolomin.pl", 2, false}, + {1, "wroclaw.pl", 2, false}, + {1, "zachpomor.pl", 2, false}, + {1, "zagan.pl", 2, false}, + {1, "zarow.pl", 2, false}, + {1, "zgora.pl", 2, false}, + {1, "zgorzelec.pl", 2, false}, + {1, "pm", 1, false}, + {1, "pn", 1, false}, + {1, "gov.pn", 2, false}, + {1, "co.pn", 2, false}, + {1, "org.pn", 2, false}, + {1, "edu.pn", 2, false}, + {1, "net.pn", 2, false}, + {1, "post", 1, false}, + {1, "pr", 1, false}, + {1, "com.pr", 2, false}, + {1, "net.pr", 2, false}, + {1, "org.pr", 2, false}, + {1, "gov.pr", 2, false}, + {1, "edu.pr", 2, false}, + {1, "isla.pr", 2, false}, + {1, "pro.pr", 2, false}, + {1, "biz.pr", 2, false}, + {1, "info.pr", 2, false}, + {1, "name.pr", 2, false}, + {1, "est.pr", 2, false}, + {1, "prof.pr", 2, false}, + {1, "ac.pr", 2, false}, + {1, "pro", 1, false}, + {1, "aaa.pro", 2, false}, + {1, "aca.pro", 2, false}, + {1, "acct.pro", 2, false}, + {1, "avocat.pro", 2, false}, + {1, "bar.pro", 2, false}, + {1, "cpa.pro", 2, false}, + {1, "eng.pro", 2, false}, + {1, "jur.pro", 2, false}, + {1, "law.pro", 2, false}, + {1, "med.pro", 2, false}, + {1, "recht.pro", 2, false}, + {1, "ps", 1, false}, + {1, "edu.ps", 2, false}, + {1, "gov.ps", 2, false}, + {1, "sec.ps", 2, false}, + {1, "plo.ps", 2, false}, + {1, "com.ps", 2, false}, + {1, "org.ps", 2, false}, + {1, "net.ps", 2, false}, + {1, "pt", 1, false}, + {1, "net.pt", 2, false}, + {1, "gov.pt", 2, false}, + {1, "org.pt", 2, false}, + {1, "edu.pt", 2, false}, + {1, "int.pt", 2, false}, + {1, "publ.pt", 2, false}, + {1, "com.pt", 2, false}, + {1, "nome.pt", 2, false}, + {1, "pw", 1, false}, + {1, "co.pw", 2, false}, + {1, "ne.pw", 2, false}, + {1, "or.pw", 2, false}, + {1, "ed.pw", 2, false}, + {1, "go.pw", 2, false}, + {1, "belau.pw", 2, false}, + {1, "py", 1, false}, + {1, "com.py", 2, false}, + {1, "coop.py", 2, false}, + {1, "edu.py", 2, false}, + {1, "gov.py", 2, false}, + {1, "mil.py", 2, false}, + {1, "net.py", 2, false}, + {1, "org.py", 2, false}, + {1, "qa", 1, false}, + {1, "com.qa", 2, false}, + {1, "edu.qa", 2, false}, + {1, "gov.qa", 2, false}, + {1, "mil.qa", 2, false}, + {1, "name.qa", 2, false}, + {1, "net.qa", 2, false}, + {1, "org.qa", 2, false}, + {1, "sch.qa", 2, false}, + {1, "re", 1, false}, + {1, "asso.re", 2, false}, + {1, "com.re", 2, false}, + {1, "nom.re", 2, false}, + {1, "ro", 1, false}, + {1, "arts.ro", 2, false}, + {1, "com.ro", 2, false}, + {1, "firm.ro", 2, false}, + {1, "info.ro", 2, false}, + {1, "nom.ro", 2, false}, + {1, "nt.ro", 2, false}, + {1, "org.ro", 2, false}, + {1, "rec.ro", 2, false}, + {1, "store.ro", 2, false}, + {1, "tm.ro", 2, false}, + {1, "www.ro", 2, false}, + {1, "rs", 1, false}, + {1, "ac.rs", 2, false}, + {1, "co.rs", 2, false}, + {1, "edu.rs", 2, false}, + {1, "gov.rs", 2, false}, + {1, "in.rs", 2, false}, + {1, "org.rs", 2, false}, + {1, "ru", 1, false}, + {1, "rw", 1, false}, + {1, "ac.rw", 2, false}, + {1, "co.rw", 2, false}, + {1, "coop.rw", 2, false}, + {1, "gov.rw", 2, false}, + {1, "mil.rw", 2, false}, + {1, "net.rw", 2, false}, + {1, "org.rw", 2, false}, + {1, "sa", 1, false}, + {1, "com.sa", 2, false}, + {1, "net.sa", 2, false}, + {1, "org.sa", 2, false}, + {1, "gov.sa", 2, false}, + {1, "med.sa", 2, false}, + {1, "pub.sa", 2, false}, + {1, "edu.sa", 2, false}, + {1, "sch.sa", 2, false}, + {1, "sb", 1, false}, + {1, "com.sb", 2, false}, + {1, "edu.sb", 2, false}, + {1, "gov.sb", 2, false}, + {1, "net.sb", 2, false}, + {1, "org.sb", 2, false}, + {1, "sc", 1, false}, + {1, "com.sc", 2, false}, + {1, "gov.sc", 2, false}, + {1, "net.sc", 2, false}, + {1, "org.sc", 2, false}, + {1, "edu.sc", 2, false}, + {1, "sd", 1, false}, + {1, "com.sd", 2, false}, + {1, "net.sd", 2, false}, + {1, "org.sd", 2, false}, + {1, "edu.sd", 2, false}, + {1, "med.sd", 2, false}, + {1, "tv.sd", 2, false}, + {1, "gov.sd", 2, false}, + {1, "info.sd", 2, false}, + {1, "se", 1, false}, + {1, "a.se", 2, false}, + {1, "ac.se", 2, false}, + {1, "b.se", 2, false}, + {1, "bd.se", 2, false}, + {1, "brand.se", 2, false}, + {1, "c.se", 2, false}, + {1, "d.se", 2, false}, + {1, "e.se", 2, false}, + {1, "f.se", 2, false}, + {1, "fh.se", 2, false}, + {1, "fhsk.se", 2, false}, + {1, "fhv.se", 2, false}, + {1, "g.se", 2, false}, + {1, "h.se", 2, false}, + {1, "i.se", 2, false}, + {1, "k.se", 2, false}, + {1, "komforb.se", 2, false}, + {1, "kommunalforbund.se", 2, false}, + {1, "komvux.se", 2, false}, + {1, "l.se", 2, false}, + {1, "lanbib.se", 2, false}, + {1, "m.se", 2, false}, + {1, "n.se", 2, false}, + {1, "naturbruksgymn.se", 2, false}, + {1, "o.se", 2, false}, + {1, "org.se", 2, false}, + {1, "p.se", 2, false}, + {1, "parti.se", 2, false}, + {1, "pp.se", 2, false}, + {1, "press.se", 2, false}, + {1, "r.se", 2, false}, + {1, "s.se", 2, false}, + {1, "t.se", 2, false}, + {1, "tm.se", 2, false}, + {1, "u.se", 2, false}, + {1, "w.se", 2, false}, + {1, "x.se", 2, false}, + {1, "y.se", 2, false}, + {1, "z.se", 2, false}, + {1, "sg", 1, false}, + {1, "com.sg", 2, false}, + {1, "net.sg", 2, false}, + {1, "org.sg", 2, false}, + {1, "gov.sg", 2, false}, + {1, "edu.sg", 2, false}, + {1, "per.sg", 2, false}, + {1, "sh", 1, false}, + {1, "com.sh", 2, false}, + {1, "net.sh", 2, false}, + {1, "gov.sh", 2, false}, + {1, "org.sh", 2, false}, + {1, "mil.sh", 2, false}, + {1, "si", 1, false}, + {1, "sj", 1, false}, + {1, "sk", 1, false}, + {1, "sl", 1, false}, + {1, "com.sl", 2, false}, + {1, "net.sl", 2, false}, + {1, "edu.sl", 2, false}, + {1, "gov.sl", 2, false}, + {1, "org.sl", 2, false}, + {1, "sm", 1, false}, + {1, "sn", 1, false}, + {1, "art.sn", 2, false}, + {1, "com.sn", 2, false}, + {1, "edu.sn", 2, false}, + {1, "gouv.sn", 2, false}, + {1, "org.sn", 2, false}, + {1, "perso.sn", 2, false}, + {1, "univ.sn", 2, false}, + {1, "so", 1, false}, + {1, "com.so", 2, false}, + {1, "edu.so", 2, false}, + {1, "gov.so", 2, false}, + {1, "me.so", 2, false}, + {1, "net.so", 2, false}, + {1, "org.so", 2, false}, + {1, "sr", 1, false}, + {1, "ss", 1, false}, + {1, "biz.ss", 2, false}, + {1, "com.ss", 2, false}, + {1, "edu.ss", 2, false}, + {1, "gov.ss", 2, false}, + {1, "net.ss", 2, false}, + {1, "org.ss", 2, false}, + {1, "st", 1, false}, + {1, "co.st", 2, false}, + {1, "com.st", 2, false}, + {1, "consulado.st", 2, false}, + {1, "edu.st", 2, false}, + {1, "embaixada.st", 2, false}, + {1, "gov.st", 2, false}, + {1, "mil.st", 2, false}, + {1, "net.st", 2, false}, + {1, "org.st", 2, false}, + {1, "principe.st", 2, false}, + {1, "saotome.st", 2, false}, + {1, "store.st", 2, false}, + {1, "su", 1, false}, + {1, "sv", 1, false}, + {1, "com.sv", 2, false}, + {1, "edu.sv", 2, false}, + {1, "gob.sv", 2, false}, + {1, "org.sv", 2, false}, + {1, "red.sv", 2, false}, + {1, "sx", 1, false}, + {1, "gov.sx", 2, false}, + {1, "sy", 1, false}, + {1, "edu.sy", 2, false}, + {1, "gov.sy", 2, false}, + {1, "net.sy", 2, false}, + {1, "mil.sy", 2, false}, + {1, "com.sy", 2, false}, + {1, "org.sy", 2, false}, + {1, "sz", 1, false}, + {1, "co.sz", 2, false}, + {1, "ac.sz", 2, false}, + {1, "org.sz", 2, false}, + {1, "tc", 1, false}, + {1, "td", 1, false}, + {1, "tel", 1, false}, + {1, "tf", 1, false}, + {1, "tg", 1, false}, + {1, "th", 1, false}, + {1, "ac.th", 2, false}, + {1, "co.th", 2, false}, + {1, "go.th", 2, false}, + {1, "in.th", 2, false}, + {1, "mi.th", 2, false}, + {1, "net.th", 2, false}, + {1, "or.th", 2, false}, + {1, "tj", 1, false}, + {1, "ac.tj", 2, false}, + {1, "biz.tj", 2, false}, + {1, "co.tj", 2, false}, + {1, "com.tj", 2, false}, + {1, "edu.tj", 2, false}, + {1, "go.tj", 2, false}, + {1, "gov.tj", 2, false}, + {1, "int.tj", 2, false}, + {1, "mil.tj", 2, false}, + {1, "name.tj", 2, false}, + {1, "net.tj", 2, false}, + {1, "nic.tj", 2, false}, + {1, "org.tj", 2, false}, + {1, "test.tj", 2, false}, + {1, "web.tj", 2, false}, + {1, "tk", 1, false}, + {1, "tl", 1, false}, + {1, "gov.tl", 2, false}, + {1, "tm", 1, false}, + {1, "com.tm", 2, false}, + {1, "co.tm", 2, false}, + {1, "org.tm", 2, false}, + {1, "net.tm", 2, false}, + {1, "nom.tm", 2, false}, + {1, "gov.tm", 2, false}, + {1, "mil.tm", 2, false}, + {1, "edu.tm", 2, false}, + {1, "tn", 1, false}, + {1, "com.tn", 2, false}, + {1, "ens.tn", 2, false}, + {1, "fin.tn", 2, false}, + {1, "gov.tn", 2, false}, + {1, "ind.tn", 2, false}, + {1, "intl.tn", 2, false}, + {1, "nat.tn", 2, false}, + {1, "net.tn", 2, false}, + {1, "org.tn", 2, false}, + {1, "info.tn", 2, false}, + {1, "perso.tn", 2, false}, + {1, "tourism.tn", 2, false}, + {1, "edunet.tn", 2, false}, + {1, "rnrt.tn", 2, false}, + {1, "rns.tn", 2, false}, + {1, "rnu.tn", 2, false}, + {1, "mincom.tn", 2, false}, + {1, "agrinet.tn", 2, false}, + {1, "defense.tn", 2, false}, + {1, "turen.tn", 2, false}, + {1, "to", 1, false}, + {1, "com.to", 2, false}, + {1, "gov.to", 2, false}, + {1, "net.to", 2, false}, + {1, "org.to", 2, false}, + {1, "edu.to", 2, false}, + {1, "mil.to", 2, false}, + {1, "tr", 1, false}, + {1, "av.tr", 2, false}, + {1, "bbs.tr", 2, false}, + {1, "bel.tr", 2, false}, + {1, "biz.tr", 2, false}, + {1, "com.tr", 2, false}, + {1, "dr.tr", 2, false}, + {1, "edu.tr", 2, false}, + {1, "gen.tr", 2, false}, + {1, "gov.tr", 2, false}, + {1, "info.tr", 2, false}, + {1, "mil.tr", 2, false}, + {1, "k12.tr", 2, false}, + {1, "kep.tr", 2, false}, + {1, "name.tr", 2, false}, + {1, "net.tr", 2, false}, + {1, "org.tr", 2, false}, + {1, "pol.tr", 2, false}, + {1, "tel.tr", 2, false}, + {1, "tsk.tr", 2, false}, + {1, "tv.tr", 2, false}, + {1, "web.tr", 2, false}, + {1, "nc.tr", 2, false}, + {1, "gov.nc.tr", 3, false}, + {1, "tt", 1, false}, + {1, "co.tt", 2, false}, + {1, "com.tt", 2, false}, + {1, "org.tt", 2, false}, + {1, "net.tt", 2, false}, + {1, "biz.tt", 2, false}, + {1, "info.tt", 2, false}, + {1, "pro.tt", 2, false}, + {1, "int.tt", 2, false}, + {1, "coop.tt", 2, false}, + {1, "jobs.tt", 2, false}, + {1, "mobi.tt", 2, false}, + {1, "travel.tt", 2, false}, + {1, "museum.tt", 2, false}, + {1, "aero.tt", 2, false}, + {1, "name.tt", 2, false}, + {1, "gov.tt", 2, false}, + {1, "edu.tt", 2, false}, + {1, "tv", 1, false}, + {1, "tw", 1, false}, + {1, "edu.tw", 2, false}, + {1, "gov.tw", 2, false}, + {1, "mil.tw", 2, false}, + {1, "com.tw", 2, false}, + {1, "net.tw", 2, false}, + {1, "org.tw", 2, false}, + {1, "idv.tw", 2, false}, + {1, "game.tw", 2, false}, + {1, "ebiz.tw", 2, false}, + {1, "club.tw", 2, false}, + {1, "xn--zf0ao64a.tw", 2, false}, + {1, "xn--uc0atv.tw", 2, false}, + {1, "xn--czrw28b.tw", 2, false}, + {1, "tz", 1, false}, + {1, "ac.tz", 2, false}, + {1, "co.tz", 2, false}, + {1, "go.tz", 2, false}, + {1, "hotel.tz", 2, false}, + {1, "info.tz", 2, false}, + {1, "me.tz", 2, false}, + {1, "mil.tz", 2, false}, + {1, "mobi.tz", 2, false}, + {1, "ne.tz", 2, false}, + {1, "or.tz", 2, false}, + {1, "sc.tz", 2, false}, + {1, "tv.tz", 2, false}, + {1, "ua", 1, false}, + {1, "com.ua", 2, false}, + {1, "edu.ua", 2, false}, + {1, "gov.ua", 2, false}, + {1, "in.ua", 2, false}, + {1, "net.ua", 2, false}, + {1, "org.ua", 2, false}, + {1, "cherkassy.ua", 2, false}, + {1, "cherkasy.ua", 2, false}, + {1, "chernigov.ua", 2, false}, + {1, "chernihiv.ua", 2, false}, + {1, "chernivtsi.ua", 2, false}, + {1, "chernovtsy.ua", 2, false}, + {1, "ck.ua", 2, false}, + {1, "cn.ua", 2, false}, + {1, "cr.ua", 2, false}, + {1, "crimea.ua", 2, false}, + {1, "cv.ua", 2, false}, + {1, "dn.ua", 2, false}, + {1, "dnepropetrovsk.ua", 2, false}, + {1, "dnipropetrovsk.ua", 2, false}, + {1, "dominic.ua", 2, false}, + {1, "donetsk.ua", 2, false}, + {1, "dp.ua", 2, false}, + {1, "if.ua", 2, false}, + {1, "ivano-frankivsk.ua", 2, false}, + {1, "kh.ua", 2, false}, + {1, "kharkiv.ua", 2, false}, + {1, "kharkov.ua", 2, false}, + {1, "kherson.ua", 2, false}, + {1, "khmelnitskiy.ua", 2, false}, + {1, "khmelnytskyi.ua", 2, false}, + {1, "kiev.ua", 2, false}, + {1, "kirovograd.ua", 2, false}, + {1, "km.ua", 2, false}, + {1, "kr.ua", 2, false}, + {1, "krym.ua", 2, false}, + {1, "ks.ua", 2, false}, + {1, "kv.ua", 2, false}, + {1, "kyiv.ua", 2, false}, + {1, "lg.ua", 2, false}, + {1, "lt.ua", 2, false}, + {1, "lugansk.ua", 2, false}, + {1, "lutsk.ua", 2, false}, + {1, "lv.ua", 2, false}, + {1, "lviv.ua", 2, false}, + {1, "mk.ua", 2, false}, + {1, "mykolaiv.ua", 2, false}, + {1, "nikolaev.ua", 2, false}, + {1, "od.ua", 2, false}, + {1, "odesa.ua", 2, false}, + {1, "odessa.ua", 2, false}, + {1, "pl.ua", 2, false}, + {1, "poltava.ua", 2, false}, + {1, "rivne.ua", 2, false}, + {1, "rovno.ua", 2, false}, + {1, "rv.ua", 2, false}, + {1, "sb.ua", 2, false}, + {1, "sebastopol.ua", 2, false}, + {1, "sevastopol.ua", 2, false}, + {1, "sm.ua", 2, false}, + {1, "sumy.ua", 2, false}, + {1, "te.ua", 2, false}, + {1, "ternopil.ua", 2, false}, + {1, "uz.ua", 2, false}, + {1, "uzhgorod.ua", 2, false}, + {1, "vinnica.ua", 2, false}, + {1, "vinnytsia.ua", 2, false}, + {1, "vn.ua", 2, false}, + {1, "volyn.ua", 2, false}, + {1, "yalta.ua", 2, false}, + {1, "zaporizhzhe.ua", 2, false}, + {1, "zaporizhzhia.ua", 2, false}, + {1, "zhitomir.ua", 2, false}, + {1, "zhytomyr.ua", 2, false}, + {1, "zp.ua", 2, false}, + {1, "zt.ua", 2, false}, + {1, "ug", 1, false}, + {1, "co.ug", 2, false}, + {1, "or.ug", 2, false}, + {1, "ac.ug", 2, false}, + {1, "sc.ug", 2, false}, + {1, "go.ug", 2, false}, + {1, "ne.ug", 2, false}, + {1, "com.ug", 2, false}, + {1, "org.ug", 2, false}, + {1, "uk", 1, false}, + {1, "ac.uk", 2, false}, + {1, "co.uk", 2, false}, + {1, "gov.uk", 2, false}, + {1, "ltd.uk", 2, false}, + {1, "me.uk", 2, false}, + {1, "net.uk", 2, false}, + {1, "nhs.uk", 2, false}, + {1, "org.uk", 2, false}, + {1, "plc.uk", 2, false}, + {1, "police.uk", 2, false}, + {2, "sch.uk", 3, false}, + {1, "us", 1, false}, + {1, "dni.us", 2, false}, + {1, "fed.us", 2, false}, + {1, "isa.us", 2, false}, + {1, "kids.us", 2, false}, + {1, "nsn.us", 2, false}, + {1, "ak.us", 2, false}, + {1, "al.us", 2, false}, + {1, "ar.us", 2, false}, + {1, "as.us", 2, false}, + {1, "az.us", 2, false}, + {1, "ca.us", 2, false}, + {1, "co.us", 2, false}, + {1, "ct.us", 2, false}, + {1, "dc.us", 2, false}, + {1, "de.us", 2, false}, + {1, "fl.us", 2, false}, + {1, "ga.us", 2, false}, + {1, "gu.us", 2, false}, + {1, "hi.us", 2, false}, + {1, "ia.us", 2, false}, + {1, "id.us", 2, false}, + {1, "il.us", 2, false}, + {1, "in.us", 2, false}, + {1, "ks.us", 2, false}, + {1, "ky.us", 2, false}, + {1, "la.us", 2, false}, + {1, "ma.us", 2, false}, + {1, "md.us", 2, false}, + {1, "me.us", 2, false}, + {1, "mi.us", 2, false}, + {1, "mn.us", 2, false}, + {1, "mo.us", 2, false}, + {1, "ms.us", 2, false}, + {1, "mt.us", 2, false}, + {1, "nc.us", 2, false}, + {1, "nd.us", 2, false}, + {1, "ne.us", 2, false}, + {1, "nh.us", 2, false}, + {1, "nj.us", 2, false}, + {1, "nm.us", 2, false}, + {1, "nv.us", 2, false}, + {1, "ny.us", 2, false}, + {1, "oh.us", 2, false}, + {1, "ok.us", 2, false}, + {1, "or.us", 2, false}, + {1, "pa.us", 2, false}, + {1, "pr.us", 2, false}, + {1, "ri.us", 2, false}, + {1, "sc.us", 2, false}, + {1, "sd.us", 2, false}, + {1, "tn.us", 2, false}, + {1, "tx.us", 2, false}, + {1, "ut.us", 2, false}, + {1, "vi.us", 2, false}, + {1, "vt.us", 2, false}, + {1, "va.us", 2, false}, + {1, "wa.us", 2, false}, + {1, "wi.us", 2, false}, + {1, "wv.us", 2, false}, + {1, "wy.us", 2, false}, + {1, "k12.ak.us", 3, false}, + {1, "k12.al.us", 3, false}, + {1, "k12.ar.us", 3, false}, + {1, "k12.as.us", 3, false}, + {1, "k12.az.us", 3, false}, + {1, "k12.ca.us", 3, false}, + {1, "k12.co.us", 3, false}, + {1, "k12.ct.us", 3, false}, + {1, "k12.dc.us", 3, false}, + {1, "k12.de.us", 3, false}, + {1, "k12.fl.us", 3, false}, + {1, "k12.ga.us", 3, false}, + {1, "k12.gu.us", 3, false}, + {1, "k12.ia.us", 3, false}, + {1, "k12.id.us", 3, false}, + {1, "k12.il.us", 3, false}, + {1, "k12.in.us", 3, false}, + {1, "k12.ks.us", 3, false}, + {1, "k12.ky.us", 3, false}, + {1, "k12.la.us", 3, false}, + {1, "k12.ma.us", 3, false}, + {1, "k12.md.us", 3, false}, + {1, "k12.me.us", 3, false}, + {1, "k12.mi.us", 3, false}, + {1, "k12.mn.us", 3, false}, + {1, "k12.mo.us", 3, false}, + {1, "k12.ms.us", 3, false}, + {1, "k12.mt.us", 3, false}, + {1, "k12.nc.us", 3, false}, + {1, "k12.ne.us", 3, false}, + {1, "k12.nh.us", 3, false}, + {1, "k12.nj.us", 3, false}, + {1, "k12.nm.us", 3, false}, + {1, "k12.nv.us", 3, false}, + {1, "k12.ny.us", 3, false}, + {1, "k12.oh.us", 3, false}, + {1, "k12.ok.us", 3, false}, + {1, "k12.or.us", 3, false}, + {1, "k12.pa.us", 3, false}, + {1, "k12.pr.us", 3, false}, + {1, "k12.ri.us", 3, false}, + {1, "k12.sc.us", 3, false}, + {1, "k12.tn.us", 3, false}, + {1, "k12.tx.us", 3, false}, + {1, "k12.ut.us", 3, false}, + {1, "k12.vi.us", 3, false}, + {1, "k12.vt.us", 3, false}, + {1, "k12.va.us", 3, false}, + {1, "k12.wa.us", 3, false}, + {1, "k12.wi.us", 3, false}, + {1, "k12.wy.us", 3, false}, + {1, "cc.ak.us", 3, false}, + {1, "cc.al.us", 3, false}, + {1, "cc.ar.us", 3, false}, + {1, "cc.as.us", 3, false}, + {1, "cc.az.us", 3, false}, + {1, "cc.ca.us", 3, false}, + {1, "cc.co.us", 3, false}, + {1, "cc.ct.us", 3, false}, + {1, "cc.dc.us", 3, false}, + {1, "cc.de.us", 3, false}, + {1, "cc.fl.us", 3, false}, + {1, "cc.ga.us", 3, false}, + {1, "cc.gu.us", 3, false}, + {1, "cc.hi.us", 3, false}, + {1, "cc.ia.us", 3, false}, + {1, "cc.id.us", 3, false}, + {1, "cc.il.us", 3, false}, + {1, "cc.in.us", 3, false}, + {1, "cc.ks.us", 3, false}, + {1, "cc.ky.us", 3, false}, + {1, "cc.la.us", 3, false}, + {1, "cc.ma.us", 3, false}, + {1, "cc.md.us", 3, false}, + {1, "cc.me.us", 3, false}, + {1, "cc.mi.us", 3, false}, + {1, "cc.mn.us", 3, false}, + {1, "cc.mo.us", 3, false}, + {1, "cc.ms.us", 3, false}, + {1, "cc.mt.us", 3, false}, + {1, "cc.nc.us", 3, false}, + {1, "cc.nd.us", 3, false}, + {1, "cc.ne.us", 3, false}, + {1, "cc.nh.us", 3, false}, + {1, "cc.nj.us", 3, false}, + {1, "cc.nm.us", 3, false}, + {1, "cc.nv.us", 3, false}, + {1, "cc.ny.us", 3, false}, + {1, "cc.oh.us", 3, false}, + {1, "cc.ok.us", 3, false}, + {1, "cc.or.us", 3, false}, + {1, "cc.pa.us", 3, false}, + {1, "cc.pr.us", 3, false}, + {1, "cc.ri.us", 3, false}, + {1, "cc.sc.us", 3, false}, + {1, "cc.sd.us", 3, false}, + {1, "cc.tn.us", 3, false}, + {1, "cc.tx.us", 3, false}, + {1, "cc.ut.us", 3, false}, + {1, "cc.vi.us", 3, false}, + {1, "cc.vt.us", 3, false}, + {1, "cc.va.us", 3, false}, + {1, "cc.wa.us", 3, false}, + {1, "cc.wi.us", 3, false}, + {1, "cc.wv.us", 3, false}, + {1, "cc.wy.us", 3, false}, + {1, "lib.ak.us", 3, false}, + {1, "lib.al.us", 3, false}, + {1, "lib.ar.us", 3, false}, + {1, "lib.as.us", 3, false}, + {1, "lib.az.us", 3, false}, + {1, "lib.ca.us", 3, false}, + {1, "lib.co.us", 3, false}, + {1, "lib.ct.us", 3, false}, + {1, "lib.dc.us", 3, false}, + {1, "lib.fl.us", 3, false}, + {1, "lib.ga.us", 3, false}, + {1, "lib.gu.us", 3, false}, + {1, "lib.hi.us", 3, false}, + {1, "lib.ia.us", 3, false}, + {1, "lib.id.us", 3, false}, + {1, "lib.il.us", 3, false}, + {1, "lib.in.us", 3, false}, + {1, "lib.ks.us", 3, false}, + {1, "lib.ky.us", 3, false}, + {1, "lib.la.us", 3, false}, + {1, "lib.ma.us", 3, false}, + {1, "lib.md.us", 3, false}, + {1, "lib.me.us", 3, false}, + {1, "lib.mi.us", 3, false}, + {1, "lib.mn.us", 3, false}, + {1, "lib.mo.us", 3, false}, + {1, "lib.ms.us", 3, false}, + {1, "lib.mt.us", 3, false}, + {1, "lib.nc.us", 3, false}, + {1, "lib.nd.us", 3, false}, + {1, "lib.ne.us", 3, false}, + {1, "lib.nh.us", 3, false}, + {1, "lib.nj.us", 3, false}, + {1, "lib.nm.us", 3, false}, + {1, "lib.nv.us", 3, false}, + {1, "lib.ny.us", 3, false}, + {1, "lib.oh.us", 3, false}, + {1, "lib.ok.us", 3, false}, + {1, "lib.or.us", 3, false}, + {1, "lib.pa.us", 3, false}, + {1, "lib.pr.us", 3, false}, + {1, "lib.ri.us", 3, false}, + {1, "lib.sc.us", 3, false}, + {1, "lib.sd.us", 3, false}, + {1, "lib.tn.us", 3, false}, + {1, "lib.tx.us", 3, false}, + {1, "lib.ut.us", 3, false}, + {1, "lib.vi.us", 3, false}, + {1, "lib.vt.us", 3, false}, + {1, "lib.va.us", 3, false}, + {1, "lib.wa.us", 3, false}, + {1, "lib.wi.us", 3, false}, + {1, "lib.wy.us", 3, false}, + {1, "pvt.k12.ma.us", 4, false}, + {1, "chtr.k12.ma.us", 4, false}, + {1, "paroch.k12.ma.us", 4, false}, + {1, "ann-arbor.mi.us", 3, false}, + {1, "cog.mi.us", 3, false}, + {1, "dst.mi.us", 3, false}, + {1, "eaton.mi.us", 3, false}, + {1, "gen.mi.us", 3, false}, + {1, "mus.mi.us", 3, false}, + {1, "tec.mi.us", 3, false}, + {1, "washtenaw.mi.us", 3, false}, + {1, "uy", 1, false}, + {1, "com.uy", 2, false}, + {1, "edu.uy", 2, false}, + {1, "gub.uy", 2, false}, + {1, "mil.uy", 2, false}, + {1, "net.uy", 2, false}, + {1, "org.uy", 2, false}, + {1, "uz", 1, false}, + {1, "co.uz", 2, false}, + {1, "com.uz", 2, false}, + {1, "net.uz", 2, false}, + {1, "org.uz", 2, false}, + {1, "va", 1, false}, + {1, "vc", 1, false}, + {1, "com.vc", 2, false}, + {1, "net.vc", 2, false}, + {1, "org.vc", 2, false}, + {1, "gov.vc", 2, false}, + {1, "mil.vc", 2, false}, + {1, "edu.vc", 2, false}, + {1, "ve", 1, false}, + {1, "arts.ve", 2, false}, + {1, "co.ve", 2, false}, + {1, "com.ve", 2, false}, + {1, "e12.ve", 2, false}, + {1, "edu.ve", 2, false}, + {1, "firm.ve", 2, false}, + {1, "gob.ve", 2, false}, + {1, "gov.ve", 2, false}, + {1, "info.ve", 2, false}, + {1, "int.ve", 2, false}, + {1, "mil.ve", 2, false}, + {1, "net.ve", 2, false}, + {1, "org.ve", 2, false}, + {1, "rec.ve", 2, false}, + {1, "store.ve", 2, false}, + {1, "tec.ve", 2, false}, + {1, "web.ve", 2, false}, + {1, "vg", 1, false}, + {1, "vi", 1, false}, + {1, "co.vi", 2, false}, + {1, "com.vi", 2, false}, + {1, "k12.vi", 2, false}, + {1, "net.vi", 2, false}, + {1, "org.vi", 2, false}, + {1, "vn", 1, false}, + {1, "com.vn", 2, false}, + {1, "net.vn", 2, false}, + {1, "org.vn", 2, false}, + {1, "edu.vn", 2, false}, + {1, "gov.vn", 2, false}, + {1, "int.vn", 2, false}, + {1, "ac.vn", 2, false}, + {1, "biz.vn", 2, false}, + {1, "info.vn", 2, false}, + {1, "name.vn", 2, false}, + {1, "pro.vn", 2, false}, + {1, "health.vn", 2, false}, + {1, "vu", 1, false}, + {1, "com.vu", 2, false}, + {1, "edu.vu", 2, false}, + {1, "net.vu", 2, false}, + {1, "org.vu", 2, false}, + {1, "wf", 1, false}, + {1, "ws", 1, false}, + {1, "com.ws", 2, false}, + {1, "net.ws", 2, false}, + {1, "org.ws", 2, false}, + {1, "gov.ws", 2, false}, + {1, "edu.ws", 2, false}, + {1, "yt", 1, false}, + {1, "xn--mgbaam7a8h", 1, false}, + {1, "xn--y9a3aq", 1, false}, + {1, "xn--54b7fta0cc", 1, false}, + {1, "xn--90ae", 1, false}, + {1, "xn--90ais", 1, false}, + {1, "xn--fiqs8s", 1, false}, + {1, "xn--fiqz9s", 1, false}, + {1, "xn--lgbbat1ad8j", 1, false}, + {1, "xn--wgbh1c", 1, false}, + {1, "xn--e1a4c", 1, false}, + {1, "xn--mgbah1a3hjkrd", 1, false}, + {1, "xn--node", 1, false}, + {1, "xn--qxam", 1, false}, + {1, "xn--j6w193g", 1, false}, + {1, "xn--55qx5d.xn--j6w193g", 2, false}, + {1, "xn--wcvs22d.xn--j6w193g", 2, false}, + {1, "xn--mxtq1m.xn--j6w193g", 2, false}, + {1, "xn--gmqw5a.xn--j6w193g", 2, false}, + {1, "xn--od0alg.xn--j6w193g", 2, false}, + {1, "xn--uc0atv.xn--j6w193g", 2, false}, + {1, "xn--2scrj9c", 1, false}, + {1, "xn--3hcrj9c", 1, false}, + {1, "xn--45br5cyl", 1, false}, + {1, "xn--h2breg3eve", 1, false}, + {1, "xn--h2brj9c8c", 1, false}, + {1, "xn--mgbgu82a", 1, false}, + {1, "xn--rvc1e0am3e", 1, false}, + {1, "xn--h2brj9c", 1, false}, + {1, "xn--mgbbh1a", 1, false}, + {1, "xn--mgbbh1a71e", 1, false}, + {1, "xn--fpcrj9c3d", 1, false}, + {1, "xn--gecrj9c", 1, false}, + {1, "xn--s9brj9c", 1, false}, + {1, "xn--45brj9c", 1, false}, + {1, "xn--xkc2dl3a5ee0h", 1, false}, + {1, "xn--mgba3a4f16a", 1, false}, + {1, "xn--mgba3a4fra", 1, false}, + {1, "xn--mgbtx2b", 1, false}, + {1, "xn--mgbayh7gpa", 1, false}, + {1, "xn--3e0b707e", 1, false}, + {1, "xn--80ao21a", 1, false}, + {1, "xn--fzc2c9e2c", 1, false}, + {1, "xn--xkc2al3hye2a", 1, false}, + {1, "xn--mgbc0a9azcg", 1, false}, + {1, "xn--d1alf", 1, false}, + {1, "xn--l1acc", 1, false}, + {1, "xn--mix891f", 1, false}, + {1, "xn--mix082f", 1, false}, + {1, "xn--mgbx4cd0ab", 1, false}, + {1, "xn--mgb9awbf", 1, false}, + {1, "xn--mgbai9azgqp6j", 1, false}, + {1, "xn--mgbai9a5eva00b", 1, false}, + {1, "xn--ygbi2ammx", 1, false}, + {1, "xn--90a3ac", 1, false}, + {1, "xn--o1ac.xn--90a3ac", 2, false}, + {1, "xn--c1avg.xn--90a3ac", 2, false}, + {1, "xn--90azh.xn--90a3ac", 2, false}, + {1, "xn--d1at.xn--90a3ac", 2, false}, + {1, "xn--o1ach.xn--90a3ac", 2, false}, + {1, "xn--80au.xn--90a3ac", 2, false}, + {1, "xn--p1ai", 1, false}, + {1, "xn--wgbl6a", 1, false}, + {1, "xn--mgberp4a5d4ar", 1, false}, + {1, "xn--mgberp4a5d4a87g", 1, false}, + {1, "xn--mgbqly7c0a67fbc", 1, false}, + {1, "xn--mgbqly7cvafr", 1, false}, + {1, "xn--mgbpl2fh", 1, false}, + {1, "xn--yfro4i67o", 1, false}, + {1, "xn--clchc0ea0b2g2a9gcd", 1, false}, + {1, "xn--ogbpf8fl", 1, false}, + {1, "xn--mgbtf8fl", 1, false}, + {1, "xn--o3cw4h", 1, false}, + {1, "xn--12c1fe0br.xn--o3cw4h", 2, false}, + {1, "xn--12co0c3b4eva.xn--o3cw4h", 2, false}, + {1, "xn--h3cuzk1di.xn--o3cw4h", 2, false}, + {1, "xn--o3cyx2a.xn--o3cw4h", 2, false}, + {1, "xn--m3ch0j3a.xn--o3cw4h", 2, false}, + {1, "xn--12cfi8ixb8l.xn--o3cw4h", 2, false}, + {1, "xn--pgbs0dh", 1, false}, + {1, "xn--kpry57d", 1, false}, + {1, "xn--kprw13d", 1, false}, + {1, "xn--nnx388a", 1, false}, + {1, "xn--j1amh", 1, false}, + {1, "xn--mgb2ddes", 1, false}, + {1, "xxx", 1, false}, + {2, "ye", 2, false}, + {1, "ac.za", 2, false}, + {1, "agric.za", 2, false}, + {1, "alt.za", 2, false}, + {1, "co.za", 2, false}, + {1, "edu.za", 2, false}, + {1, "gov.za", 2, false}, + {1, "grondar.za", 2, false}, + {1, "law.za", 2, false}, + {1, "mil.za", 2, false}, + {1, "net.za", 2, false}, + {1, "ngo.za", 2, false}, + {1, "nic.za", 2, false}, + {1, "nis.za", 2, false}, + {1, "nom.za", 2, false}, + {1, "org.za", 2, false}, + {1, "school.za", 2, false}, + {1, "tm.za", 2, false}, + {1, "web.za", 2, false}, + {1, "zm", 1, false}, + {1, "ac.zm", 2, false}, + {1, "biz.zm", 2, false}, + {1, "co.zm", 2, false}, + {1, "com.zm", 2, false}, + {1, "edu.zm", 2, false}, + {1, "gov.zm", 2, false}, + {1, "info.zm", 2, false}, + {1, "mil.zm", 2, false}, + {1, "net.zm", 2, false}, + {1, "org.zm", 2, false}, + {1, "sch.zm", 2, false}, + {1, "zw", 1, false}, + {1, "ac.zw", 2, false}, + {1, "co.zw", 2, false}, + {1, "gov.zw", 2, false}, + {1, "mil.zw", 2, false}, + {1, "org.zw", 2, false}, + {1, "aaa", 1, false}, + {1, "aarp", 1, false}, + {1, "abarth", 1, false}, + {1, "abb", 1, false}, + {1, "abbott", 1, false}, + {1, "abbvie", 1, false}, + {1, "abc", 1, false}, + {1, "able", 1, false}, + {1, "abogado", 1, false}, + {1, "abudhabi", 1, false}, + {1, "academy", 1, false}, + {1, "accenture", 1, false}, + {1, "accountant", 1, false}, + {1, "accountants", 1, false}, + {1, "aco", 1, false}, + {1, "actor", 1, false}, + {1, "adac", 1, false}, + {1, "ads", 1, false}, + {1, "adult", 1, false}, + {1, "aeg", 1, false}, + {1, "aetna", 1, false}, + {1, "afamilycompany", 1, false}, + {1, "afl", 1, false}, + {1, "africa", 1, false}, + {1, "agakhan", 1, false}, + {1, "agency", 1, false}, + {1, "aig", 1, false}, + {1, "aigo", 1, false}, + {1, "airbus", 1, false}, + {1, "airforce", 1, false}, + {1, "airtel", 1, false}, + {1, "akdn", 1, false}, + {1, "alfaromeo", 1, false}, + {1, "alibaba", 1, false}, + {1, "alipay", 1, false}, + {1, "allfinanz", 1, false}, + {1, "allstate", 1, false}, + {1, "ally", 1, false}, + {1, "alsace", 1, false}, + {1, "alstom", 1, false}, + {1, "amazon", 1, false}, + {1, "americanexpress", 1, false}, + {1, "americanfamily", 1, false}, + {1, "amex", 1, false}, + {1, "amfam", 1, false}, + {1, "amica", 1, false}, + {1, "amsterdam", 1, false}, + {1, "analytics", 1, false}, + {1, "android", 1, false}, + {1, "anquan", 1, false}, + {1, "anz", 1, false}, + {1, "aol", 1, false}, + {1, "apartments", 1, false}, + {1, "app", 1, false}, + {1, "apple", 1, false}, + {1, "aquarelle", 1, false}, + {1, "arab", 1, false}, + {1, "aramco", 1, false}, + {1, "archi", 1, false}, + {1, "army", 1, false}, + {1, "art", 1, false}, + {1, "arte", 1, false}, + {1, "asda", 1, false}, + {1, "associates", 1, false}, + {1, "athleta", 1, false}, + {1, "attorney", 1, false}, + {1, "auction", 1, false}, + {1, "audi", 1, false}, + {1, "audible", 1, false}, + {1, "audio", 1, false}, + {1, "auspost", 1, false}, + {1, "author", 1, false}, + {1, "auto", 1, false}, + {1, "autos", 1, false}, + {1, "avianca", 1, false}, + {1, "aws", 1, false}, + {1, "axa", 1, false}, + {1, "azure", 1, false}, + {1, "baby", 1, false}, + {1, "baidu", 1, false}, + {1, "banamex", 1, false}, + {1, "bananarepublic", 1, false}, + {1, "band", 1, false}, + {1, "bank", 1, false}, + {1, "bar", 1, false}, + {1, "barcelona", 1, false}, + {1, "barclaycard", 1, false}, + {1, "barclays", 1, false}, + {1, "barefoot", 1, false}, + {1, "bargains", 1, false}, + {1, "baseball", 1, false}, + {1, "basketball", 1, false}, + {1, "bauhaus", 1, false}, + {1, "bayern", 1, false}, + {1, "bbc", 1, false}, + {1, "bbt", 1, false}, + {1, "bbva", 1, false}, + {1, "bcg", 1, false}, + {1, "bcn", 1, false}, + {1, "beats", 1, false}, + {1, "beauty", 1, false}, + {1, "beer", 1, false}, + {1, "bentley", 1, false}, + {1, "berlin", 1, false}, + {1, "best", 1, false}, + {1, "bestbuy", 1, false}, + {1, "bet", 1, false}, + {1, "bharti", 1, false}, + {1, "bible", 1, false}, + {1, "bid", 1, false}, + {1, "bike", 1, false}, + {1, "bing", 1, false}, + {1, "bingo", 1, false}, + {1, "bio", 1, false}, + {1, "black", 1, false}, + {1, "blackfriday", 1, false}, + {1, "blockbuster", 1, false}, + {1, "blog", 1, false}, + {1, "bloomberg", 1, false}, + {1, "blue", 1, false}, + {1, "bms", 1, false}, + {1, "bmw", 1, false}, + {1, "bnpparibas", 1, false}, + {1, "boats", 1, false}, + {1, "boehringer", 1, false}, + {1, "bofa", 1, false}, + {1, "bom", 1, false}, + {1, "bond", 1, false}, + {1, "boo", 1, false}, + {1, "book", 1, false}, + {1, "booking", 1, false}, + {1, "bosch", 1, false}, + {1, "bostik", 1, false}, + {1, "boston", 1, false}, + {1, "bot", 1, false}, + {1, "boutique", 1, false}, + {1, "box", 1, false}, + {1, "bradesco", 1, false}, + {1, "bridgestone", 1, false}, + {1, "broadway", 1, false}, + {1, "broker", 1, false}, + {1, "brother", 1, false}, + {1, "brussels", 1, false}, + {1, "budapest", 1, false}, + {1, "bugatti", 1, false}, + {1, "build", 1, false}, + {1, "builders", 1, false}, + {1, "business", 1, false}, + {1, "buy", 1, false}, + {1, "buzz", 1, false}, + {1, "bzh", 1, false}, + {1, "cab", 1, false}, + {1, "cafe", 1, false}, + {1, "cal", 1, false}, + {1, "call", 1, false}, + {1, "calvinklein", 1, false}, + {1, "cam", 1, false}, + {1, "camera", 1, false}, + {1, "camp", 1, false}, + {1, "cancerresearch", 1, false}, + {1, "canon", 1, false}, + {1, "capetown", 1, false}, + {1, "capital", 1, false}, + {1, "capitalone", 1, false}, + {1, "car", 1, false}, + {1, "caravan", 1, false}, + {1, "cards", 1, false}, + {1, "care", 1, false}, + {1, "career", 1, false}, + {1, "careers", 1, false}, + {1, "cars", 1, false}, + {1, "casa", 1, false}, + {1, "case", 1, false}, + {1, "caseih", 1, false}, + {1, "cash", 1, false}, + {1, "casino", 1, false}, + {1, "catering", 1, false}, + {1, "catholic", 1, false}, + {1, "cba", 1, false}, + {1, "cbn", 1, false}, + {1, "cbre", 1, false}, + {1, "cbs", 1, false}, + {1, "ceb", 1, false}, + {1, "center", 1, false}, + {1, "ceo", 1, false}, + {1, "cern", 1, false}, + {1, "cfa", 1, false}, + {1, "cfd", 1, false}, + {1, "chanel", 1, false}, + {1, "channel", 1, false}, + {1, "charity", 1, false}, + {1, "chase", 1, false}, + {1, "chat", 1, false}, + {1, "cheap", 1, false}, + {1, "chintai", 1, false}, + {1, "christmas", 1, false}, + {1, "chrome", 1, false}, + {1, "church", 1, false}, + {1, "cipriani", 1, false}, + {1, "circle", 1, false}, + {1, "cisco", 1, false}, + {1, "citadel", 1, false}, + {1, "citi", 1, false}, + {1, "citic", 1, false}, + {1, "city", 1, false}, + {1, "cityeats", 1, false}, + {1, "claims", 1, false}, + {1, "cleaning", 1, false}, + {1, "click", 1, false}, + {1, "clinic", 1, false}, + {1, "clinique", 1, false}, + {1, "clothing", 1, false}, + {1, "cloud", 1, false}, + {1, "club", 1, false}, + {1, "clubmed", 1, false}, + {1, "coach", 1, false}, + {1, "codes", 1, false}, + {1, "coffee", 1, false}, + {1, "college", 1, false}, + {1, "cologne", 1, false}, + {1, "comcast", 1, false}, + {1, "commbank", 1, false}, + {1, "community", 1, false}, + {1, "company", 1, false}, + {1, "compare", 1, false}, + {1, "computer", 1, false}, + {1, "comsec", 1, false}, + {1, "condos", 1, false}, + {1, "construction", 1, false}, + {1, "consulting", 1, false}, + {1, "contact", 1, false}, + {1, "contractors", 1, false}, + {1, "cooking", 1, false}, + {1, "cookingchannel", 1, false}, + {1, "cool", 1, false}, + {1, "corsica", 1, false}, + {1, "country", 1, false}, + {1, "coupon", 1, false}, + {1, "coupons", 1, false}, + {1, "courses", 1, false}, + {1, "cpa", 1, false}, + {1, "credit", 1, false}, + {1, "creditcard", 1, false}, + {1, "creditunion", 1, false}, + {1, "cricket", 1, false}, + {1, "crown", 1, false}, + {1, "crs", 1, false}, + {1, "cruise", 1, false}, + {1, "cruises", 1, false}, + {1, "csc", 1, false}, + {1, "cuisinella", 1, false}, + {1, "cymru", 1, false}, + {1, "cyou", 1, false}, + {1, "dabur", 1, false}, + {1, "dad", 1, false}, + {1, "dance", 1, false}, + {1, "data", 1, false}, + {1, "date", 1, false}, + {1, "dating", 1, false}, + {1, "datsun", 1, false}, + {1, "day", 1, false}, + {1, "dclk", 1, false}, + {1, "dds", 1, false}, + {1, "deal", 1, false}, + {1, "dealer", 1, false}, + {1, "deals", 1, false}, + {1, "degree", 1, false}, + {1, "delivery", 1, false}, + {1, "dell", 1, false}, + {1, "deloitte", 1, false}, + {1, "delta", 1, false}, + {1, "democrat", 1, false}, + {1, "dental", 1, false}, + {1, "dentist", 1, false}, + {1, "desi", 1, false}, + {1, "design", 1, false}, + {1, "dev", 1, false}, + {1, "dhl", 1, false}, + {1, "diamonds", 1, false}, + {1, "diet", 1, false}, + {1, "digital", 1, false}, + {1, "direct", 1, false}, + {1, "directory", 1, false}, + {1, "discount", 1, false}, + {1, "discover", 1, false}, + {1, "dish", 1, false}, + {1, "diy", 1, false}, + {1, "dnp", 1, false}, + {1, "docs", 1, false}, + {1, "doctor", 1, false}, + {1, "dog", 1, false}, + {1, "domains", 1, false}, + {1, "dot", 1, false}, + {1, "download", 1, false}, + {1, "drive", 1, false}, + {1, "dtv", 1, false}, + {1, "dubai", 1, false}, + {1, "duck", 1, false}, + {1, "dunlop", 1, false}, + {1, "dupont", 1, false}, + {1, "durban", 1, false}, + {1, "dvag", 1, false}, + {1, "dvr", 1, false}, + {1, "earth", 1, false}, + {1, "eat", 1, false}, + {1, "eco", 1, false}, + {1, "edeka", 1, false}, + {1, "education", 1, false}, + {1, "email", 1, false}, + {1, "emerck", 1, false}, + {1, "energy", 1, false}, + {1, "engineer", 1, false}, + {1, "engineering", 1, false}, + {1, "enterprises", 1, false}, + {1, "epson", 1, false}, + {1, "equipment", 1, false}, + {1, "ericsson", 1, false}, + {1, "erni", 1, false}, + {1, "esq", 1, false}, + {1, "estate", 1, false}, + {1, "esurance", 1, false}, + {1, "etisalat", 1, false}, + {1, "eurovision", 1, false}, + {1, "eus", 1, false}, + {1, "events", 1, false}, + {1, "exchange", 1, false}, + {1, "expert", 1, false}, + {1, "exposed", 1, false}, + {1, "express", 1, false}, + {1, "extraspace", 1, false}, + {1, "fage", 1, false}, + {1, "fail", 1, false}, + {1, "fairwinds", 1, false}, + {1, "faith", 1, false}, + {1, "family", 1, false}, + {1, "fan", 1, false}, + {1, "fans", 1, false}, + {1, "farm", 1, false}, + {1, "farmers", 1, false}, + {1, "fashion", 1, false}, + {1, "fast", 1, false}, + {1, "fedex", 1, false}, + {1, "feedback", 1, false}, + {1, "ferrari", 1, false}, + {1, "ferrero", 1, false}, + {1, "fiat", 1, false}, + {1, "fidelity", 1, false}, + {1, "fido", 1, false}, + {1, "film", 1, false}, + {1, "final", 1, false}, + {1, "finance", 1, false}, + {1, "financial", 1, false}, + {1, "fire", 1, false}, + {1, "firestone", 1, false}, + {1, "firmdale", 1, false}, + {1, "fish", 1, false}, + {1, "fishing", 1, false}, + {1, "fit", 1, false}, + {1, "fitness", 1, false}, + {1, "flickr", 1, false}, + {1, "flights", 1, false}, + {1, "flir", 1, false}, + {1, "florist", 1, false}, + {1, "flowers", 1, false}, + {1, "fly", 1, false}, + {1, "foo", 1, false}, + {1, "food", 1, false}, + {1, "foodnetwork", 1, false}, + {1, "football", 1, false}, + {1, "ford", 1, false}, + {1, "forex", 1, false}, + {1, "forsale", 1, false}, + {1, "forum", 1, false}, + {1, "foundation", 1, false}, + {1, "fox", 1, false}, + {1, "free", 1, false}, + {1, "fresenius", 1, false}, + {1, "frl", 1, false}, + {1, "frogans", 1, false}, + {1, "frontdoor", 1, false}, + {1, "frontier", 1, false}, + {1, "ftr", 1, false}, + {1, "fujitsu", 1, false}, + {1, "fujixerox", 1, false}, + {1, "fun", 1, false}, + {1, "fund", 1, false}, + {1, "furniture", 1, false}, + {1, "futbol", 1, false}, + {1, "fyi", 1, false}, + {1, "gal", 1, false}, + {1, "gallery", 1, false}, + {1, "gallo", 1, false}, + {1, "gallup", 1, false}, + {1, "game", 1, false}, + {1, "games", 1, false}, + {1, "gap", 1, false}, + {1, "garden", 1, false}, + {1, "gay", 1, false}, + {1, "gbiz", 1, false}, + {1, "gdn", 1, false}, + {1, "gea", 1, false}, + {1, "gent", 1, false}, + {1, "genting", 1, false}, + {1, "george", 1, false}, + {1, "ggee", 1, false}, + {1, "gift", 1, false}, + {1, "gifts", 1, false}, + {1, "gives", 1, false}, + {1, "giving", 1, false}, + {1, "glade", 1, false}, + {1, "glass", 1, false}, + {1, "gle", 1, false}, + {1, "global", 1, false}, + {1, "globo", 1, false}, + {1, "gmail", 1, false}, + {1, "gmbh", 1, false}, + {1, "gmo", 1, false}, + {1, "gmx", 1, false}, + {1, "godaddy", 1, false}, + {1, "gold", 1, false}, + {1, "goldpoint", 1, false}, + {1, "golf", 1, false}, + {1, "goo", 1, false}, + {1, "goodyear", 1, false}, + {1, "goog", 1, false}, + {1, "google", 1, false}, + {1, "gop", 1, false}, + {1, "got", 1, false}, + {1, "grainger", 1, false}, + {1, "graphics", 1, false}, + {1, "gratis", 1, false}, + {1, "green", 1, false}, + {1, "gripe", 1, false}, + {1, "grocery", 1, false}, + {1, "group", 1, false}, + {1, "guardian", 1, false}, + {1, "gucci", 1, false}, + {1, "guge", 1, false}, + {1, "guide", 1, false}, + {1, "guitars", 1, false}, + {1, "guru", 1, false}, + {1, "hair", 1, false}, + {1, "hamburg", 1, false}, + {1, "hangout", 1, false}, + {1, "haus", 1, false}, + {1, "hbo", 1, false}, + {1, "hdfc", 1, false}, + {1, "hdfcbank", 1, false}, + {1, "health", 1, false}, + {1, "healthcare", 1, false}, + {1, "help", 1, false}, + {1, "helsinki", 1, false}, + {1, "here", 1, false}, + {1, "hermes", 1, false}, + {1, "hgtv", 1, false}, + {1, "hiphop", 1, false}, + {1, "hisamitsu", 1, false}, + {1, "hitachi", 1, false}, + {1, "hiv", 1, false}, + {1, "hkt", 1, false}, + {1, "hockey", 1, false}, + {1, "holdings", 1, false}, + {1, "holiday", 1, false}, + {1, "homedepot", 1, false}, + {1, "homegoods", 1, false}, + {1, "homes", 1, false}, + {1, "homesense", 1, false}, + {1, "honda", 1, false}, + {1, "horse", 1, false}, + {1, "hospital", 1, false}, + {1, "host", 1, false}, + {1, "hosting", 1, false}, + {1, "hot", 1, false}, + {1, "hoteles", 1, false}, + {1, "hotels", 1, false}, + {1, "hotmail", 1, false}, + {1, "house", 1, false}, + {1, "how", 1, false}, + {1, "hsbc", 1, false}, + {1, "hughes", 1, false}, + {1, "hyatt", 1, false}, + {1, "hyundai", 1, false}, + {1, "ibm", 1, false}, + {1, "icbc", 1, false}, + {1, "ice", 1, false}, + {1, "icu", 1, false}, + {1, "ieee", 1, false}, + {1, "ifm", 1, false}, + {1, "ikano", 1, false}, + {1, "imamat", 1, false}, + {1, "imdb", 1, false}, + {1, "immo", 1, false}, + {1, "immobilien", 1, false}, + {1, "inc", 1, false}, + {1, "industries", 1, false}, + {1, "infiniti", 1, false}, + {1, "ing", 1, false}, + {1, "ink", 1, false}, + {1, "institute", 1, false}, + {1, "insurance", 1, false}, + {1, "insure", 1, false}, + {1, "intel", 1, false}, + {1, "international", 1, false}, + {1, "intuit", 1, false}, + {1, "investments", 1, false}, + {1, "ipiranga", 1, false}, + {1, "irish", 1, false}, + {1, "ismaili", 1, false}, + {1, "ist", 1, false}, + {1, "istanbul", 1, false}, + {1, "itau", 1, false}, + {1, "itv", 1, false}, + {1, "iveco", 1, false}, + {1, "jaguar", 1, false}, + {1, "java", 1, false}, + {1, "jcb", 1, false}, + {1, "jcp", 1, false}, + {1, "jeep", 1, false}, + {1, "jetzt", 1, false}, + {1, "jewelry", 1, false}, + {1, "jio", 1, false}, + {1, "jll", 1, false}, + {1, "jmp", 1, false}, + {1, "jnj", 1, false}, + {1, "joburg", 1, false}, + {1, "jot", 1, false}, + {1, "joy", 1, false}, + {1, "jpmorgan", 1, false}, + {1, "jprs", 1, false}, + {1, "juegos", 1, false}, + {1, "juniper", 1, false}, + {1, "kaufen", 1, false}, + {1, "kddi", 1, false}, + {1, "kerryhotels", 1, false}, + {1, "kerrylogistics", 1, false}, + {1, "kerryproperties", 1, false}, + {1, "kfh", 1, false}, + {1, "kia", 1, false}, + {1, "kim", 1, false}, + {1, "kinder", 1, false}, + {1, "kindle", 1, false}, + {1, "kitchen", 1, false}, + {1, "kiwi", 1, false}, + {1, "koeln", 1, false}, + {1, "komatsu", 1, false}, + {1, "kosher", 1, false}, + {1, "kpmg", 1, false}, + {1, "kpn", 1, false}, + {1, "krd", 1, false}, + {1, "kred", 1, false}, + {1, "kuokgroup", 1, false}, + {1, "kyoto", 1, false}, + {1, "lacaixa", 1, false}, + {1, "lamborghini", 1, false}, + {1, "lamer", 1, false}, + {1, "lancaster", 1, false}, + {1, "lancia", 1, false}, + {1, "land", 1, false}, + {1, "landrover", 1, false}, + {1, "lanxess", 1, false}, + {1, "lasalle", 1, false}, + {1, "lat", 1, false}, + {1, "latino", 1, false}, + {1, "latrobe", 1, false}, + {1, "law", 1, false}, + {1, "lawyer", 1, false}, + {1, "lds", 1, false}, + {1, "lease", 1, false}, + {1, "leclerc", 1, false}, + {1, "lefrak", 1, false}, + {1, "legal", 1, false}, + {1, "lego", 1, false}, + {1, "lexus", 1, false}, + {1, "lgbt", 1, false}, + {1, "lidl", 1, false}, + {1, "life", 1, false}, + {1, "lifeinsurance", 1, false}, + {1, "lifestyle", 1, false}, + {1, "lighting", 1, false}, + {1, "like", 1, false}, + {1, "lilly", 1, false}, + {1, "limited", 1, false}, + {1, "limo", 1, false}, + {1, "lincoln", 1, false}, + {1, "linde", 1, false}, + {1, "link", 1, false}, + {1, "lipsy", 1, false}, + {1, "live", 1, false}, + {1, "living", 1, false}, + {1, "lixil", 1, false}, + {1, "llc", 1, false}, + {1, "llp", 1, false}, + {1, "loan", 1, false}, + {1, "loans", 1, false}, + {1, "locker", 1, false}, + {1, "locus", 1, false}, + {1, "loft", 1, false}, + {1, "lol", 1, false}, + {1, "london", 1, false}, + {1, "lotte", 1, false}, + {1, "lotto", 1, false}, + {1, "love", 1, false}, + {1, "lpl", 1, false}, + {1, "lplfinancial", 1, false}, + {1, "ltd", 1, false}, + {1, "ltda", 1, false}, + {1, "lundbeck", 1, false}, + {1, "lupin", 1, false}, + {1, "luxe", 1, false}, + {1, "luxury", 1, false}, + {1, "macys", 1, false}, + {1, "madrid", 1, false}, + {1, "maif", 1, false}, + {1, "maison", 1, false}, + {1, "makeup", 1, false}, + {1, "man", 1, false}, + {1, "management", 1, false}, + {1, "mango", 1, false}, + {1, "map", 1, false}, + {1, "market", 1, false}, + {1, "marketing", 1, false}, + {1, "markets", 1, false}, + {1, "marriott", 1, false}, + {1, "marshalls", 1, false}, + {1, "maserati", 1, false}, + {1, "mattel", 1, false}, + {1, "mba", 1, false}, + {1, "mckinsey", 1, false}, + {1, "med", 1, false}, + {1, "media", 1, false}, + {1, "meet", 1, false}, + {1, "melbourne", 1, false}, + {1, "meme", 1, false}, + {1, "memorial", 1, false}, + {1, "men", 1, false}, + {1, "menu", 1, false}, + {1, "merckmsd", 1, false}, + {1, "metlife", 1, false}, + {1, "miami", 1, false}, + {1, "microsoft", 1, false}, + {1, "mini", 1, false}, + {1, "mint", 1, false}, + {1, "mit", 1, false}, + {1, "mitsubishi", 1, false}, + {1, "mlb", 1, false}, + {1, "mls", 1, false}, + {1, "mma", 1, false}, + {1, "mobile", 1, false}, + {1, "moda", 1, false}, + {1, "moe", 1, false}, + {1, "moi", 1, false}, + {1, "mom", 1, false}, + {1, "monash", 1, false}, + {1, "money", 1, false}, + {1, "monster", 1, false}, + {1, "mormon", 1, false}, + {1, "mortgage", 1, false}, + {1, "moscow", 1, false}, + {1, "moto", 1, false}, + {1, "motorcycles", 1, false}, + {1, "mov", 1, false}, + {1, "movie", 1, false}, + {1, "msd", 1, false}, + {1, "mtn", 1, false}, + {1, "mtr", 1, false}, + {1, "mutual", 1, false}, + {1, "nab", 1, false}, + {1, "nadex", 1, false}, + {1, "nagoya", 1, false}, + {1, "nationwide", 1, false}, + {1, "natura", 1, false}, + {1, "navy", 1, false}, + {1, "nba", 1, false}, + {1, "nec", 1, false}, + {1, "netbank", 1, false}, + {1, "netflix", 1, false}, + {1, "network", 1, false}, + {1, "neustar", 1, false}, + {1, "new", 1, false}, + {1, "newholland", 1, false}, + {1, "news", 1, false}, + {1, "next", 1, false}, + {1, "nextdirect", 1, false}, + {1, "nexus", 1, false}, + {1, "nfl", 1, false}, + {1, "ngo", 1, false}, + {1, "nhk", 1, false}, + {1, "nico", 1, false}, + {1, "nike", 1, false}, + {1, "nikon", 1, false}, + {1, "ninja", 1, false}, + {1, "nissan", 1, false}, + {1, "nissay", 1, false}, + {1, "nokia", 1, false}, + {1, "northwesternmutual", 1, false}, + {1, "norton", 1, false}, + {1, "now", 1, false}, + {1, "nowruz", 1, false}, + {1, "nowtv", 1, false}, + {1, "nra", 1, false}, + {1, "nrw", 1, false}, + {1, "ntt", 1, false}, + {1, "nyc", 1, false}, + {1, "obi", 1, false}, + {1, "observer", 1, false}, + {1, "off", 1, false}, + {1, "office", 1, false}, + {1, "okinawa", 1, false}, + {1, "olayan", 1, false}, + {1, "olayangroup", 1, false}, + {1, "oldnavy", 1, false}, + {1, "ollo", 1, false}, + {1, "omega", 1, false}, + {1, "one", 1, false}, + {1, "ong", 1, false}, + {1, "onl", 1, false}, + {1, "online", 1, false}, + {1, "onyourside", 1, false}, + {1, "ooo", 1, false}, + {1, "open", 1, false}, + {1, "oracle", 1, false}, + {1, "orange", 1, false}, + {1, "organic", 1, false}, + {1, "origins", 1, false}, + {1, "osaka", 1, false}, + {1, "otsuka", 1, false}, + {1, "ott", 1, false}, + {1, "ovh", 1, false}, + {1, "page", 1, false}, + {1, "panasonic", 1, false}, + {1, "paris", 1, false}, + {1, "pars", 1, false}, + {1, "partners", 1, false}, + {1, "parts", 1, false}, + {1, "party", 1, false}, + {1, "passagens", 1, false}, + {1, "pay", 1, false}, + {1, "pccw", 1, false}, + {1, "pet", 1, false}, + {1, "pfizer", 1, false}, + {1, "pharmacy", 1, false}, + {1, "phd", 1, false}, + {1, "philips", 1, false}, + {1, "phone", 1, false}, + {1, "photo", 1, false}, + {1, "photography", 1, false}, + {1, "photos", 1, false}, + {1, "physio", 1, false}, + {1, "pics", 1, false}, + {1, "pictet", 1, false}, + {1, "pictures", 1, false}, + {1, "pid", 1, false}, + {1, "pin", 1, false}, + {1, "ping", 1, false}, + {1, "pink", 1, false}, + {1, "pioneer", 1, false}, + {1, "pizza", 1, false}, + {1, "place", 1, false}, + {1, "play", 1, false}, + {1, "playstation", 1, false}, + {1, "plumbing", 1, false}, + {1, "plus", 1, false}, + {1, "pnc", 1, false}, + {1, "pohl", 1, false}, + {1, "poker", 1, false}, + {1, "politie", 1, false}, + {1, "porn", 1, false}, + {1, "pramerica", 1, false}, + {1, "praxi", 1, false}, + {1, "press", 1, false}, + {1, "prime", 1, false}, + {1, "prod", 1, false}, + {1, "productions", 1, false}, + {1, "prof", 1, false}, + {1, "progressive", 1, false}, + {1, "promo", 1, false}, + {1, "properties", 1, false}, + {1, "property", 1, false}, + {1, "protection", 1, false}, + {1, "pru", 1, false}, + {1, "prudential", 1, false}, + {1, "pub", 1, false}, + {1, "pwc", 1, false}, + {1, "qpon", 1, false}, + {1, "quebec", 1, false}, + {1, "quest", 1, false}, + {1, "qvc", 1, false}, + {1, "racing", 1, false}, + {1, "radio", 1, false}, + {1, "raid", 1, false}, + {1, "read", 1, false}, + {1, "realestate", 1, false}, + {1, "realtor", 1, false}, + {1, "realty", 1, false}, + {1, "recipes", 1, false}, + {1, "red", 1, false}, + {1, "redstone", 1, false}, + {1, "redumbrella", 1, false}, + {1, "rehab", 1, false}, + {1, "reise", 1, false}, + {1, "reisen", 1, false}, + {1, "reit", 1, false}, + {1, "reliance", 1, false}, + {1, "ren", 1, false}, + {1, "rent", 1, false}, + {1, "rentals", 1, false}, + {1, "repair", 1, false}, + {1, "report", 1, false}, + {1, "republican", 1, false}, + {1, "rest", 1, false}, + {1, "restaurant", 1, false}, + {1, "review", 1, false}, + {1, "reviews", 1, false}, + {1, "rexroth", 1, false}, + {1, "rich", 1, false}, + {1, "richardli", 1, false}, + {1, "ricoh", 1, false}, + {1, "rightathome", 1, false}, + {1, "ril", 1, false}, + {1, "rio", 1, false}, + {1, "rip", 1, false}, + {1, "rmit", 1, false}, + {1, "rocher", 1, false}, + {1, "rocks", 1, false}, + {1, "rodeo", 1, false}, + {1, "rogers", 1, false}, + {1, "room", 1, false}, + {1, "rsvp", 1, false}, + {1, "rugby", 1, false}, + {1, "ruhr", 1, false}, + {1, "run", 1, false}, + {1, "rwe", 1, false}, + {1, "ryukyu", 1, false}, + {1, "saarland", 1, false}, + {1, "safe", 1, false}, + {1, "safety", 1, false}, + {1, "sakura", 1, false}, + {1, "sale", 1, false}, + {1, "salon", 1, false}, + {1, "samsclub", 1, false}, + {1, "samsung", 1, false}, + {1, "sandvik", 1, false}, + {1, "sandvikcoromant", 1, false}, + {1, "sanofi", 1, false}, + {1, "sap", 1, false}, + {1, "sarl", 1, false}, + {1, "sas", 1, false}, + {1, "save", 1, false}, + {1, "saxo", 1, false}, + {1, "sbi", 1, false}, + {1, "sbs", 1, false}, + {1, "sca", 1, false}, + {1, "scb", 1, false}, + {1, "schaeffler", 1, false}, + {1, "schmidt", 1, false}, + {1, "scholarships", 1, false}, + {1, "school", 1, false}, + {1, "schule", 1, false}, + {1, "schwarz", 1, false}, + {1, "science", 1, false}, + {1, "scjohnson", 1, false}, + {1, "scor", 1, false}, + {1, "scot", 1, false}, + {1, "search", 1, false}, + {1, "seat", 1, false}, + {1, "secure", 1, false}, + {1, "security", 1, false}, + {1, "seek", 1, false}, + {1, "select", 1, false}, + {1, "sener", 1, false}, + {1, "services", 1, false}, + {1, "ses", 1, false}, + {1, "seven", 1, false}, + {1, "sew", 1, false}, + {1, "sex", 1, false}, + {1, "sexy", 1, false}, + {1, "sfr", 1, false}, + {1, "shangrila", 1, false}, + {1, "sharp", 1, false}, + {1, "shaw", 1, false}, + {1, "shell", 1, false}, + {1, "shia", 1, false}, + {1, "shiksha", 1, false}, + {1, "shoes", 1, false}, + {1, "shop", 1, false}, + {1, "shopping", 1, false}, + {1, "shouji", 1, false}, + {1, "show", 1, false}, + {1, "showtime", 1, false}, + {1, "shriram", 1, false}, + {1, "silk", 1, false}, + {1, "sina", 1, false}, + {1, "singles", 1, false}, + {1, "site", 1, false}, + {1, "ski", 1, false}, + {1, "skin", 1, false}, + {1, "sky", 1, false}, + {1, "skype", 1, false}, + {1, "sling", 1, false}, + {1, "smart", 1, false}, + {1, "smile", 1, false}, + {1, "sncf", 1, false}, + {1, "soccer", 1, false}, + {1, "social", 1, false}, + {1, "softbank", 1, false}, + {1, "software", 1, false}, + {1, "sohu", 1, false}, + {1, "solar", 1, false}, + {1, "solutions", 1, false}, + {1, "song", 1, false}, + {1, "sony", 1, false}, + {1, "soy", 1, false}, + {1, "spa", 1, false}, + {1, "space", 1, false}, + {1, "sport", 1, false}, + {1, "spot", 1, false}, + {1, "spreadbetting", 1, false}, + {1, "srl", 1, false}, + {1, "stada", 1, false}, + {1, "staples", 1, false}, + {1, "star", 1, false}, + {1, "statebank", 1, false}, + {1, "statefarm", 1, false}, + {1, "stc", 1, false}, + {1, "stcgroup", 1, false}, + {1, "stockholm", 1, false}, + {1, "storage", 1, false}, + {1, "store", 1, false}, + {1, "stream", 1, false}, + {1, "studio", 1, false}, + {1, "study", 1, false}, + {1, "style", 1, false}, + {1, "sucks", 1, false}, + {1, "supplies", 1, false}, + {1, "supply", 1, false}, + {1, "support", 1, false}, + {1, "surf", 1, false}, + {1, "surgery", 1, false}, + {1, "suzuki", 1, false}, + {1, "swatch", 1, false}, + {1, "swiftcover", 1, false}, + {1, "swiss", 1, false}, + {1, "sydney", 1, false}, + {1, "symantec", 1, false}, + {1, "systems", 1, false}, + {1, "tab", 1, false}, + {1, "taipei", 1, false}, + {1, "talk", 1, false}, + {1, "taobao", 1, false}, + {1, "target", 1, false}, + {1, "tatamotors", 1, false}, + {1, "tatar", 1, false}, + {1, "tattoo", 1, false}, + {1, "tax", 1, false}, + {1, "taxi", 1, false}, + {1, "tci", 1, false}, + {1, "tdk", 1, false}, + {1, "team", 1, false}, + {1, "tech", 1, false}, + {1, "technology", 1, false}, + {1, "temasek", 1, false}, + {1, "tennis", 1, false}, + {1, "teva", 1, false}, + {1, "thd", 1, false}, + {1, "theater", 1, false}, + {1, "theatre", 1, false}, + {1, "tiaa", 1, false}, + {1, "tickets", 1, false}, + {1, "tienda", 1, false}, + {1, "tiffany", 1, false}, + {1, "tips", 1, false}, + {1, "tires", 1, false}, + {1, "tirol", 1, false}, + {1, "tjmaxx", 1, false}, + {1, "tjx", 1, false}, + {1, "tkmaxx", 1, false}, + {1, "tmall", 1, false}, + {1, "today", 1, false}, + {1, "tokyo", 1, false}, + {1, "tools", 1, false}, + {1, "top", 1, false}, + {1, "toray", 1, false}, + {1, "toshiba", 1, false}, + {1, "total", 1, false}, + {1, "tours", 1, false}, + {1, "town", 1, false}, + {1, "toyota", 1, false}, + {1, "toys", 1, false}, + {1, "trade", 1, false}, + {1, "trading", 1, false}, + {1, "training", 1, false}, + {1, "travel", 1, false}, + {1, "travelchannel", 1, false}, + {1, "travelers", 1, false}, + {1, "travelersinsurance", 1, false}, + {1, "trust", 1, false}, + {1, "trv", 1, false}, + {1, "tube", 1, false}, + {1, "tui", 1, false}, + {1, "tunes", 1, false}, + {1, "tushu", 1, false}, + {1, "tvs", 1, false}, + {1, "ubank", 1, false}, + {1, "ubs", 1, false}, + {1, "unicom", 1, false}, + {1, "university", 1, false}, + {1, "uno", 1, false}, + {1, "uol", 1, false}, + {1, "ups", 1, false}, + {1, "vacations", 1, false}, + {1, "vana", 1, false}, + {1, "vanguard", 1, false}, + {1, "vegas", 1, false}, + {1, "ventures", 1, false}, + {1, "verisign", 1, false}, + {1, "versicherung", 1, false}, + {1, "vet", 1, false}, + {1, "viajes", 1, false}, + {1, "video", 1, false}, + {1, "vig", 1, false}, + {1, "viking", 1, false}, + {1, "villas", 1, false}, + {1, "vin", 1, false}, + {1, "vip", 1, false}, + {1, "virgin", 1, false}, + {1, "visa", 1, false}, + {1, "vision", 1, false}, + {1, "vistaprint", 1, false}, + {1, "viva", 1, false}, + {1, "vivo", 1, false}, + {1, "vlaanderen", 1, false}, + {1, "vodka", 1, false}, + {1, "volkswagen", 1, false}, + {1, "volvo", 1, false}, + {1, "vote", 1, false}, + {1, "voting", 1, false}, + {1, "voto", 1, false}, + {1, "voyage", 1, false}, + {1, "vuelos", 1, false}, + {1, "wales", 1, false}, + {1, "walmart", 1, false}, + {1, "walter", 1, false}, + {1, "wang", 1, false}, + {1, "wanggou", 1, false}, + {1, "watch", 1, false}, + {1, "watches", 1, false}, + {1, "weather", 1, false}, + {1, "weatherchannel", 1, false}, + {1, "webcam", 1, false}, + {1, "weber", 1, false}, + {1, "website", 1, false}, + {1, "wed", 1, false}, + {1, "wedding", 1, false}, + {1, "weibo", 1, false}, + {1, "weir", 1, false}, + {1, "whoswho", 1, false}, + {1, "wien", 1, false}, + {1, "wiki", 1, false}, + {1, "williamhill", 1, false}, + {1, "win", 1, false}, + {1, "windows", 1, false}, + {1, "wine", 1, false}, + {1, "winners", 1, false}, + {1, "wme", 1, false}, + {1, "wolterskluwer", 1, false}, + {1, "woodside", 1, false}, + {1, "work", 1, false}, + {1, "works", 1, false}, + {1, "world", 1, false}, + {1, "wow", 1, false}, + {1, "wtc", 1, false}, + {1, "wtf", 1, false}, + {1, "xbox", 1, false}, + {1, "xerox", 1, false}, + {1, "xfinity", 1, false}, + {1, "xihuan", 1, false}, + {1, "xin", 1, false}, + {1, "xn--11b4c3d", 1, false}, + {1, "xn--1ck2e1b", 1, false}, + {1, "xn--1qqw23a", 1, false}, + {1, "xn--30rr7y", 1, false}, + {1, "xn--3bst00m", 1, false}, + {1, "xn--3ds443g", 1, false}, + {1, "xn--3oq18vl8pn36a", 1, false}, + {1, "xn--3pxu8k", 1, false}, + {1, "xn--42c2d9a", 1, false}, + {1, "xn--45q11c", 1, false}, + {1, "xn--4gbrim", 1, false}, + {1, "xn--55qw42g", 1, false}, + {1, "xn--55qx5d", 1, false}, + {1, "xn--5su34j936bgsg", 1, false}, + {1, "xn--5tzm5g", 1, false}, + {1, "xn--6frz82g", 1, false}, + {1, "xn--6qq986b3xl", 1, false}, + {1, "xn--80adxhks", 1, false}, + {1, "xn--80aqecdr1a", 1, false}, + {1, "xn--80asehdb", 1, false}, + {1, "xn--80aswg", 1, false}, + {1, "xn--8y0a063a", 1, false}, + {1, "xn--9dbq2a", 1, false}, + {1, "xn--9et52u", 1, false}, + {1, "xn--9krt00a", 1, false}, + {1, "xn--b4w605ferd", 1, false}, + {1, "xn--bck1b9a5dre4c", 1, false}, + {1, "xn--c1avg", 1, false}, + {1, "xn--c2br7g", 1, false}, + {1, "xn--cck2b3b", 1, false}, + {1, "xn--cckwcxetd", 1, false}, + {1, "xn--cg4bki", 1, false}, + {1, "xn--czr694b", 1, false}, + {1, "xn--czrs0t", 1, false}, + {1, "xn--czru2d", 1, false}, + {1, "xn--d1acj3b", 1, false}, + {1, "xn--eckvdtc9d", 1, false}, + {1, "xn--efvy88h", 1, false}, + {1, "xn--estv75g", 1, false}, + {1, "xn--fct429k", 1, false}, + {1, "xn--fhbei", 1, false}, + {1, "xn--fiq228c5hs", 1, false}, + {1, "xn--fiq64b", 1, false}, + {1, "xn--fjq720a", 1, false}, + {1, "xn--flw351e", 1, false}, + {1, "xn--fzys8d69uvgm", 1, false}, + {1, "xn--g2xx48c", 1, false}, + {1, "xn--gckr3f0f", 1, false}, + {1, "xn--gk3at1e", 1, false}, + {1, "xn--hxt814e", 1, false}, + {1, "xn--i1b6b1a6a2e", 1, false}, + {1, "xn--imr513n", 1, false}, + {1, "xn--io0a7i", 1, false}, + {1, "xn--j1aef", 1, false}, + {1, "xn--jlq480n2rg", 1, false}, + {1, "xn--jlq61u9w7b", 1, false}, + {1, "xn--jvr189m", 1, false}, + {1, "xn--kcrx77d1x4a", 1, false}, + {1, "xn--kpu716f", 1, false}, + {1, "xn--kput3i", 1, false}, + {1, "xn--mgba3a3ejt", 1, false}, + {1, "xn--mgba7c0bbn0a", 1, false}, + {1, "xn--mgbaakc7dvf", 1, false}, + {1, "xn--mgbab2bd", 1, false}, + {1, "xn--mgbca7dzdo", 1, false}, + {1, "xn--mgbi4ecexp", 1, false}, + {1, "xn--mgbt3dhd", 1, false}, + {1, "xn--mk1bu44c", 1, false}, + {1, "xn--mxtq1m", 1, false}, + {1, "xn--ngbc5azd", 1, false}, + {1, "xn--ngbe9e0a", 1, false}, + {1, "xn--ngbrx", 1, false}, + {1, "xn--nqv7f", 1, false}, + {1, "xn--nqv7fs00ema", 1, false}, + {1, "xn--nyqy26a", 1, false}, + {1, "xn--otu796d", 1, false}, + {1, "xn--p1acf", 1, false}, + {1, "xn--pbt977c", 1, false}, + {1, "xn--pssy2u", 1, false}, + {1, "xn--q9jyb4c", 1, false}, + {1, "xn--qcka1pmc", 1, false}, + {1, "xn--rhqv96g", 1, false}, + {1, "xn--rovu88b", 1, false}, + {1, "xn--ses554g", 1, false}, + {1, "xn--t60b56a", 1, false}, + {1, "xn--tckwe", 1, false}, + {1, "xn--tiq49xqyj", 1, false}, + {1, "xn--unup4y", 1, false}, + {1, "xn--vermgensberater-ctb", 1, false}, + {1, "xn--vermgensberatung-pwb", 1, false}, + {1, "xn--vhquv", 1, false}, + {1, "xn--vuq861b", 1, false}, + {1, "xn--w4r85el8fhu5dnra", 1, false}, + {1, "xn--w4rs40l", 1, false}, + {1, "xn--xhq521b", 1, false}, + {1, "xn--zfr164b", 1, false}, + {1, "xyz", 1, false}, + {1, "yachts", 1, false}, + {1, "yahoo", 1, false}, + {1, "yamaxun", 1, false}, + {1, "yandex", 1, false}, + {1, "yodobashi", 1, false}, + {1, "yoga", 1, false}, + {1, "yokohama", 1, false}, + {1, "you", 1, false}, + {1, "youtube", 1, false}, + {1, "yun", 1, false}, + {1, "zappos", 1, false}, + {1, "zara", 1, false}, + {1, "zero", 1, false}, + {1, "zip", 1, false}, + {1, "zone", 1, false}, + {1, "zuerich", 1, false}, + {1, "cc.ua", 2, true}, + {1, "inf.ua", 2, true}, + {1, "ltd.ua", 2, true}, + {1, "adobeaemcloud.com", 2, true}, + {1, "adobeaemcloud.net", 2, true}, + {2, "dev.adobeaemcloud.com", 4, true}, + {1, "beep.pl", 2, true}, + {1, "barsy.ca", 2, true}, + {2, "compute.estate", 3, true}, + {2, "alces.network", 3, true}, + {1, "altervista.org", 2, true}, + {1, "alwaysdata.net", 2, true}, + {1, "cloudfront.net", 2, true}, + {2, "compute.amazonaws.com", 4, true}, + {2, "compute-1.amazonaws.com", 4, true}, + {2, "compute.amazonaws.com.cn", 5, true}, + {1, "us-east-1.amazonaws.com", 3, true}, + {1, "cn-north-1.eb.amazonaws.com.cn", 5, true}, + {1, "cn-northwest-1.eb.amazonaws.com.cn", 5, true}, + {1, "elasticbeanstalk.com", 2, true}, + {1, "ap-northeast-1.elasticbeanstalk.com", 3, true}, + {1, "ap-northeast-2.elasticbeanstalk.com", 3, true}, + {1, "ap-northeast-3.elasticbeanstalk.com", 3, true}, + {1, "ap-south-1.elasticbeanstalk.com", 3, true}, + {1, "ap-southeast-1.elasticbeanstalk.com", 3, true}, + {1, "ap-southeast-2.elasticbeanstalk.com", 3, true}, + {1, "ca-central-1.elasticbeanstalk.com", 3, true}, + {1, "eu-central-1.elasticbeanstalk.com", 3, true}, + {1, "eu-west-1.elasticbeanstalk.com", 3, true}, + {1, "eu-west-2.elasticbeanstalk.com", 3, true}, + {1, "eu-west-3.elasticbeanstalk.com", 3, true}, + {1, "sa-east-1.elasticbeanstalk.com", 3, true}, + {1, "us-east-1.elasticbeanstalk.com", 3, true}, + {1, "us-east-2.elasticbeanstalk.com", 3, true}, + {1, "us-gov-west-1.elasticbeanstalk.com", 3, true}, + {1, "us-west-1.elasticbeanstalk.com", 3, true}, + {1, "us-west-2.elasticbeanstalk.com", 3, true}, + {2, "elb.amazonaws.com", 4, true}, + {2, "elb.amazonaws.com.cn", 5, true}, + {1, "s3.amazonaws.com", 3, true}, + {1, "s3-ap-northeast-1.amazonaws.com", 3, true}, + {1, "s3-ap-northeast-2.amazonaws.com", 3, true}, + {1, "s3-ap-south-1.amazonaws.com", 3, true}, + {1, "s3-ap-southeast-1.amazonaws.com", 3, true}, + {1, "s3-ap-southeast-2.amazonaws.com", 3, true}, + {1, "s3-ca-central-1.amazonaws.com", 3, true}, + {1, "s3-eu-central-1.amazonaws.com", 3, true}, + {1, "s3-eu-west-1.amazonaws.com", 3, true}, + {1, "s3-eu-west-2.amazonaws.com", 3, true}, + {1, "s3-eu-west-3.amazonaws.com", 3, true}, + {1, "s3-external-1.amazonaws.com", 3, true}, + {1, "s3-fips-us-gov-west-1.amazonaws.com", 3, true}, + {1, "s3-sa-east-1.amazonaws.com", 3, true}, + {1, "s3-us-gov-west-1.amazonaws.com", 3, true}, + {1, "s3-us-east-2.amazonaws.com", 3, true}, + {1, "s3-us-west-1.amazonaws.com", 3, true}, + {1, "s3-us-west-2.amazonaws.com", 3, true}, + {1, "s3.ap-northeast-2.amazonaws.com", 4, true}, + {1, "s3.ap-south-1.amazonaws.com", 4, true}, + {1, "s3.cn-north-1.amazonaws.com.cn", 5, true}, + {1, "s3.ca-central-1.amazonaws.com", 4, true}, + {1, "s3.eu-central-1.amazonaws.com", 4, true}, + {1, "s3.eu-west-2.amazonaws.com", 4, true}, + {1, "s3.eu-west-3.amazonaws.com", 4, true}, + {1, "s3.us-east-2.amazonaws.com", 4, true}, + {1, "s3.dualstack.ap-northeast-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.ap-northeast-2.amazonaws.com", 5, true}, + {1, "s3.dualstack.ap-south-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.ap-southeast-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.ap-southeast-2.amazonaws.com", 5, true}, + {1, "s3.dualstack.ca-central-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.eu-central-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.eu-west-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.eu-west-2.amazonaws.com", 5, true}, + {1, "s3.dualstack.eu-west-3.amazonaws.com", 5, true}, + {1, "s3.dualstack.sa-east-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.us-east-1.amazonaws.com", 5, true}, + {1, "s3.dualstack.us-east-2.amazonaws.com", 5, true}, + {1, "s3-website-us-east-1.amazonaws.com", 3, true}, + {1, "s3-website-us-west-1.amazonaws.com", 3, true}, + {1, "s3-website-us-west-2.amazonaws.com", 3, true}, + {1, "s3-website-ap-northeast-1.amazonaws.com", 3, true}, + {1, "s3-website-ap-southeast-1.amazonaws.com", 3, true}, + {1, "s3-website-ap-southeast-2.amazonaws.com", 3, true}, + {1, "s3-website-eu-west-1.amazonaws.com", 3, true}, + {1, "s3-website-sa-east-1.amazonaws.com", 3, true}, + {1, "s3-website.ap-northeast-2.amazonaws.com", 4, true}, + {1, "s3-website.ap-south-1.amazonaws.com", 4, true}, + {1, "s3-website.ca-central-1.amazonaws.com", 4, true}, + {1, "s3-website.eu-central-1.amazonaws.com", 4, true}, + {1, "s3-website.eu-west-2.amazonaws.com", 4, true}, + {1, "s3-website.eu-west-3.amazonaws.com", 4, true}, + {1, "s3-website.us-east-2.amazonaws.com", 4, true}, + {1, "amsw.nl", 2, true}, + {1, "t3l3p0rt.net", 2, true}, + {1, "tele.amune.org", 3, true}, + {1, "apigee.io", 2, true}, + {1, "on-aptible.com", 2, true}, + {1, "user.aseinet.ne.jp", 4, true}, + {1, "gv.vc", 2, true}, + {1, "d.gv.vc", 3, true}, + {1, "user.party.eus", 3, true}, + {1, "pimienta.org", 2, true}, + {1, "poivron.org", 2, true}, + {1, "potager.org", 2, true}, + {1, "sweetpepper.org", 2, true}, + {1, "myasustor.com", 2, true}, + {1, "myfritz.net", 2, true}, + {2, "awdev.ca", 3, true}, + {2, "advisor.ws", 3, true}, + {1, "b-data.io", 2, true}, + {1, "backplaneapp.io", 2, true}, + {1, "balena-devices.com", 2, true}, + {1, "app.banzaicloud.io", 3, true}, + {1, "betainabox.com", 2, true}, + {1, "bnr.la", 2, true}, + {1, "blackbaudcdn.net", 2, true}, + {1, "boomla.net", 2, true}, + {1, "boxfuse.io", 2, true}, + {1, "square7.ch", 2, true}, + {1, "bplaced.com", 2, true}, + {1, "bplaced.de", 2, true}, + {1, "square7.de", 2, true}, + {1, "bplaced.net", 2, true}, + {1, "square7.net", 2, true}, + {1, "browsersafetymark.io", 2, true}, + {1, "uk0.bigv.io", 3, true}, + {1, "dh.bytemark.co.uk", 4, true}, + {1, "vm.bytemark.co.uk", 4, true}, + {1, "mycd.eu", 2, true}, + {1, "carrd.co", 2, true}, + {1, "crd.co", 2, true}, + {1, "uwu.ai", 2, true}, + {1, "ae.org", 2, true}, + {1, "ar.com", 2, true}, + {1, "br.com", 2, true}, + {1, "cn.com", 2, true}, + {1, "com.de", 2, true}, + {1, "com.se", 2, true}, + {1, "de.com", 2, true}, + {1, "eu.com", 2, true}, + {1, "gb.com", 2, true}, + {1, "gb.net", 2, true}, + {1, "hu.com", 2, true}, + {1, "hu.net", 2, true}, + {1, "jp.net", 2, true}, + {1, "jpn.com", 2, true}, + {1, "kr.com", 2, true}, + {1, "mex.com", 2, true}, + {1, "no.com", 2, true}, + {1, "qc.com", 2, true}, + {1, "ru.com", 2, true}, + {1, "sa.com", 2, true}, + {1, "se.net", 2, true}, + {1, "uk.com", 2, true}, + {1, "uk.net", 2, true}, + {1, "us.com", 2, true}, + {1, "uy.com", 2, true}, + {1, "za.bz", 2, true}, + {1, "za.com", 2, true}, + {1, "africa.com", 2, true}, + {1, "gr.com", 2, true}, + {1, "in.net", 2, true}, + {1, "us.org", 2, true}, + {1, "co.com", 2, true}, + {1, "c.la", 2, true}, + {1, "certmgr.org", 2, true}, + {1, "xenapponazure.com", 2, true}, + {1, "discourse.group", 2, true}, + {1, "discourse.team", 2, true}, + {1, "virtueeldomein.nl", 2, true}, + {1, "cleverapps.io", 2, true}, + {2, "lcl.dev", 3, true}, + {2, "stg.dev", 3, true}, + {1, "c66.me", 2, true}, + {1, "cloud66.ws", 2, true}, + {1, "cloud66.zone", 2, true}, + {1, "jdevcloud.com", 2, true}, + {1, "wpdevcloud.com", 2, true}, + {1, "cloudaccess.host", 2, true}, + {1, "freesite.host", 2, true}, + {1, "cloudaccess.net", 2, true}, + {1, "cloudcontrolled.com", 2, true}, + {1, "cloudcontrolapp.com", 2, true}, + {1, "cloudera.site", 2, true}, + {1, "trycloudflare.com", 2, true}, + {1, "workers.dev", 2, true}, + {1, "wnext.app", 2, true}, + {1, "co.ca", 2, true}, + {2, "otap.co", 3, true}, + {1, "co.cz", 2, true}, + {1, "c.cdn77.org", 3, true}, + {1, "cdn77-ssl.net", 2, true}, + {1, "r.cdn77.net", 3, true}, + {1, "rsc.cdn77.org", 3, true}, + {1, "ssl.origin.cdn77-secure.org", 4, true}, + {1, "cloudns.asia", 2, true}, + {1, "cloudns.biz", 2, true}, + {1, "cloudns.club", 2, true}, + {1, "cloudns.cc", 2, true}, + {1, "cloudns.eu", 2, true}, + {1, "cloudns.in", 2, true}, + {1, "cloudns.info", 2, true}, + {1, "cloudns.org", 2, true}, + {1, "cloudns.pro", 2, true}, + {1, "cloudns.pw", 2, true}, + {1, "cloudns.us", 2, true}, + {1, "cloudeity.net", 2, true}, + {1, "cnpy.gdn", 2, true}, + {1, "co.nl", 2, true}, + {1, "co.no", 2, true}, + {1, "webhosting.be", 2, true}, + {1, "hosting-cluster.nl", 2, true}, + {1, "ac.ru", 2, true}, + {1, "edu.ru", 2, true}, + {1, "gov.ru", 2, true}, + {1, "int.ru", 2, true}, + {1, "mil.ru", 2, true}, + {1, "test.ru", 2, true}, + {1, "dyn.cosidns.de", 3, true}, + {1, "dynamisches-dns.de", 2, true}, + {1, "dnsupdater.de", 2, true}, + {1, "internet-dns.de", 2, true}, + {1, "l-o-g-i-n.de", 2, true}, + {1, "dynamic-dns.info", 2, true}, + {1, "feste-ip.net", 2, true}, + {1, "knx-server.net", 2, true}, + {1, "static-access.net", 2, true}, + {1, "realm.cz", 2, true}, + {2, "cryptonomic.net", 3, true}, + {1, "cupcake.is", 2, true}, + {2, "customer-oci.com", 3, true}, + {2, "oci.customer-oci.com", 4, true}, + {2, "ocp.customer-oci.com", 4, true}, + {2, "ocs.customer-oci.com", 4, true}, + {1, "cyon.link", 2, true}, + {1, "cyon.site", 2, true}, + {1, "daplie.me", 2, true}, + {1, "localhost.daplie.me", 3, true}, + {1, "dattolocal.com", 2, true}, + {1, "dattorelay.com", 2, true}, + {1, "dattoweb.com", 2, true}, + {1, "mydatto.com", 2, true}, + {1, "dattolocal.net", 2, true}, + {1, "mydatto.net", 2, true}, + {1, "biz.dk", 2, true}, + {1, "co.dk", 2, true}, + {1, "firm.dk", 2, true}, + {1, "reg.dk", 2, true}, + {1, "store.dk", 2, true}, + {2, "dapps.earth", 3, true}, + {2, "bzz.dapps.earth", 4, true}, + {1, "builtwithdark.com", 2, true}, + {1, "edgestack.me", 2, true}, + {1, "debian.net", 2, true}, + {1, "dedyn.io", 2, true}, + {1, "dnshome.de", 2, true}, + {1, "online.th", 2, true}, + {1, "shop.th", 2, true}, + {1, "drayddns.com", 2, true}, + {1, "dreamhosters.com", 2, true}, + {1, "mydrobo.com", 2, true}, + {1, "drud.io", 2, true}, + {1, "drud.us", 2, true}, + {1, "duckdns.org", 2, true}, + {1, "dy.fi", 2, true}, + {1, "tunk.org", 2, true}, + {1, "dyndns-at-home.com", 2, true}, + {1, "dyndns-at-work.com", 2, true}, + {1, "dyndns-blog.com", 2, true}, + {1, "dyndns-free.com", 2, true}, + {1, "dyndns-home.com", 2, true}, + {1, "dyndns-ip.com", 2, true}, + {1, "dyndns-mail.com", 2, true}, + {1, "dyndns-office.com", 2, true}, + {1, "dyndns-pics.com", 2, true}, + {1, "dyndns-remote.com", 2, true}, + {1, "dyndns-server.com", 2, true}, + {1, "dyndns-web.com", 2, true}, + {1, "dyndns-wiki.com", 2, true}, + {1, "dyndns-work.com", 2, true}, + {1, "dyndns.biz", 2, true}, + {1, "dyndns.info", 2, true}, + {1, "dyndns.org", 2, true}, + {1, "dyndns.tv", 2, true}, + {1, "at-band-camp.net", 2, true}, + {1, "ath.cx", 2, true}, + {1, "barrel-of-knowledge.info", 2, true}, + {1, "barrell-of-knowledge.info", 2, true}, + {1, "better-than.tv", 2, true}, + {1, "blogdns.com", 2, true}, + {1, "blogdns.net", 2, true}, + {1, "blogdns.org", 2, true}, + {1, "blogsite.org", 2, true}, + {1, "boldlygoingnowhere.org", 2, true}, + {1, "broke-it.net", 2, true}, + {1, "buyshouses.net", 2, true}, + {1, "cechire.com", 2, true}, + {1, "dnsalias.com", 2, true}, + {1, "dnsalias.net", 2, true}, + {1, "dnsalias.org", 2, true}, + {1, "dnsdojo.com", 2, true}, + {1, "dnsdojo.net", 2, true}, + {1, "dnsdojo.org", 2, true}, + {1, "does-it.net", 2, true}, + {1, "doesntexist.com", 2, true}, + {1, "doesntexist.org", 2, true}, + {1, "dontexist.com", 2, true}, + {1, "dontexist.net", 2, true}, + {1, "dontexist.org", 2, true}, + {1, "doomdns.com", 2, true}, + {1, "doomdns.org", 2, true}, + {1, "dvrdns.org", 2, true}, + {1, "dyn-o-saur.com", 2, true}, + {1, "dynalias.com", 2, true}, + {1, "dynalias.net", 2, true}, + {1, "dynalias.org", 2, true}, + {1, "dynathome.net", 2, true}, + {1, "dyndns.ws", 2, true}, + {1, "endofinternet.net", 2, true}, + {1, "endofinternet.org", 2, true}, + {1, "endoftheinternet.org", 2, true}, + {1, "est-a-la-maison.com", 2, true}, + {1, "est-a-la-masion.com", 2, true}, + {1, "est-le-patron.com", 2, true}, + {1, "est-mon-blogueur.com", 2, true}, + {1, "for-better.biz", 2, true}, + {1, "for-more.biz", 2, true}, + {1, "for-our.info", 2, true}, + {1, "for-some.biz", 2, true}, + {1, "for-the.biz", 2, true}, + {1, "forgot.her.name", 3, true}, + {1, "forgot.his.name", 3, true}, + {1, "from-ak.com", 2, true}, + {1, "from-al.com", 2, true}, + {1, "from-ar.com", 2, true}, + {1, "from-az.net", 2, true}, + {1, "from-ca.com", 2, true}, + {1, "from-co.net", 2, true}, + {1, "from-ct.com", 2, true}, + {1, "from-dc.com", 2, true}, + {1, "from-de.com", 2, true}, + {1, "from-fl.com", 2, true}, + {1, "from-ga.com", 2, true}, + {1, "from-hi.com", 2, true}, + {1, "from-ia.com", 2, true}, + {1, "from-id.com", 2, true}, + {1, "from-il.com", 2, true}, + {1, "from-in.com", 2, true}, + {1, "from-ks.com", 2, true}, + {1, "from-ky.com", 2, true}, + {1, "from-la.net", 2, true}, + {1, "from-ma.com", 2, true}, + {1, "from-md.com", 2, true}, + {1, "from-me.org", 2, true}, + {1, "from-mi.com", 2, true}, + {1, "from-mn.com", 2, true}, + {1, "from-mo.com", 2, true}, + {1, "from-ms.com", 2, true}, + {1, "from-mt.com", 2, true}, + {1, "from-nc.com", 2, true}, + {1, "from-nd.com", 2, true}, + {1, "from-ne.com", 2, true}, + {1, "from-nh.com", 2, true}, + {1, "from-nj.com", 2, true}, + {1, "from-nm.com", 2, true}, + {1, "from-nv.com", 2, true}, + {1, "from-ny.net", 2, true}, + {1, "from-oh.com", 2, true}, + {1, "from-ok.com", 2, true}, + {1, "from-or.com", 2, true}, + {1, "from-pa.com", 2, true}, + {1, "from-pr.com", 2, true}, + {1, "from-ri.com", 2, true}, + {1, "from-sc.com", 2, true}, + {1, "from-sd.com", 2, true}, + {1, "from-tn.com", 2, true}, + {1, "from-tx.com", 2, true}, + {1, "from-ut.com", 2, true}, + {1, "from-va.com", 2, true}, + {1, "from-vt.com", 2, true}, + {1, "from-wa.com", 2, true}, + {1, "from-wi.com", 2, true}, + {1, "from-wv.com", 2, true}, + {1, "from-wy.com", 2, true}, + {1, "ftpaccess.cc", 2, true}, + {1, "fuettertdasnetz.de", 2, true}, + {1, "game-host.org", 2, true}, + {1, "game-server.cc", 2, true}, + {1, "getmyip.com", 2, true}, + {1, "gets-it.net", 2, true}, + {1, "go.dyndns.org", 3, true}, + {1, "gotdns.com", 2, true}, + {1, "gotdns.org", 2, true}, + {1, "groks-the.info", 2, true}, + {1, "groks-this.info", 2, true}, + {1, "ham-radio-op.net", 2, true}, + {1, "here-for-more.info", 2, true}, + {1, "hobby-site.com", 2, true}, + {1, "hobby-site.org", 2, true}, + {1, "home.dyndns.org", 3, true}, + {1, "homedns.org", 2, true}, + {1, "homeftp.net", 2, true}, + {1, "homeftp.org", 2, true}, + {1, "homeip.net", 2, true}, + {1, "homelinux.com", 2, true}, + {1, "homelinux.net", 2, true}, + {1, "homelinux.org", 2, true}, + {1, "homeunix.com", 2, true}, + {1, "homeunix.net", 2, true}, + {1, "homeunix.org", 2, true}, + {1, "iamallama.com", 2, true}, + {1, "in-the-band.net", 2, true}, + {1, "is-a-anarchist.com", 2, true}, + {1, "is-a-blogger.com", 2, true}, + {1, "is-a-bookkeeper.com", 2, true}, + {1, "is-a-bruinsfan.org", 2, true}, + {1, "is-a-bulls-fan.com", 2, true}, + {1, "is-a-candidate.org", 2, true}, + {1, "is-a-caterer.com", 2, true}, + {1, "is-a-celticsfan.org", 2, true}, + {1, "is-a-chef.com", 2, true}, + {1, "is-a-chef.net", 2, true}, + {1, "is-a-chef.org", 2, true}, + {1, "is-a-conservative.com", 2, true}, + {1, "is-a-cpa.com", 2, true}, + {1, "is-a-cubicle-slave.com", 2, true}, + {1, "is-a-democrat.com", 2, true}, + {1, "is-a-designer.com", 2, true}, + {1, "is-a-doctor.com", 2, true}, + {1, "is-a-financialadvisor.com", 2, true}, + {1, "is-a-geek.com", 2, true}, + {1, "is-a-geek.net", 2, true}, + {1, "is-a-geek.org", 2, true}, + {1, "is-a-green.com", 2, true}, + {1, "is-a-guru.com", 2, true}, + {1, "is-a-hard-worker.com", 2, true}, + {1, "is-a-hunter.com", 2, true}, + {1, "is-a-knight.org", 2, true}, + {1, "is-a-landscaper.com", 2, true}, + {1, "is-a-lawyer.com", 2, true}, + {1, "is-a-liberal.com", 2, true}, + {1, "is-a-libertarian.com", 2, true}, + {1, "is-a-linux-user.org", 2, true}, + {1, "is-a-llama.com", 2, true}, + {1, "is-a-musician.com", 2, true}, + {1, "is-a-nascarfan.com", 2, true}, + {1, "is-a-nurse.com", 2, true}, + {1, "is-a-painter.com", 2, true}, + {1, "is-a-patsfan.org", 2, true}, + {1, "is-a-personaltrainer.com", 2, true}, + {1, "is-a-photographer.com", 2, true}, + {1, "is-a-player.com", 2, true}, + {1, "is-a-republican.com", 2, true}, + {1, "is-a-rockstar.com", 2, true}, + {1, "is-a-socialist.com", 2, true}, + {1, "is-a-soxfan.org", 2, true}, + {1, "is-a-student.com", 2, true}, + {1, "is-a-teacher.com", 2, true}, + {1, "is-a-techie.com", 2, true}, + {1, "is-a-therapist.com", 2, true}, + {1, "is-an-accountant.com", 2, true}, + {1, "is-an-actor.com", 2, true}, + {1, "is-an-actress.com", 2, true}, + {1, "is-an-anarchist.com", 2, true}, + {1, "is-an-artist.com", 2, true}, + {1, "is-an-engineer.com", 2, true}, + {1, "is-an-entertainer.com", 2, true}, + {1, "is-by.us", 2, true}, + {1, "is-certified.com", 2, true}, + {1, "is-found.org", 2, true}, + {1, "is-gone.com", 2, true}, + {1, "is-into-anime.com", 2, true}, + {1, "is-into-cars.com", 2, true}, + {1, "is-into-cartoons.com", 2, true}, + {1, "is-into-games.com", 2, true}, + {1, "is-leet.com", 2, true}, + {1, "is-lost.org", 2, true}, + {1, "is-not-certified.com", 2, true}, + {1, "is-saved.org", 2, true}, + {1, "is-slick.com", 2, true}, + {1, "is-uberleet.com", 2, true}, + {1, "is-very-bad.org", 2, true}, + {1, "is-very-evil.org", 2, true}, + {1, "is-very-good.org", 2, true}, + {1, "is-very-nice.org", 2, true}, + {1, "is-very-sweet.org", 2, true}, + {1, "is-with-theband.com", 2, true}, + {1, "isa-geek.com", 2, true}, + {1, "isa-geek.net", 2, true}, + {1, "isa-geek.org", 2, true}, + {1, "isa-hockeynut.com", 2, true}, + {1, "issmarterthanyou.com", 2, true}, + {1, "isteingeek.de", 2, true}, + {1, "istmein.de", 2, true}, + {1, "kicks-ass.net", 2, true}, + {1, "kicks-ass.org", 2, true}, + {1, "knowsitall.info", 2, true}, + {1, "land-4-sale.us", 2, true}, + {1, "lebtimnetz.de", 2, true}, + {1, "leitungsen.de", 2, true}, + {1, "likes-pie.com", 2, true}, + {1, "likescandy.com", 2, true}, + {1, "merseine.nu", 2, true}, + {1, "mine.nu", 2, true}, + {1, "misconfused.org", 2, true}, + {1, "mypets.ws", 2, true}, + {1, "myphotos.cc", 2, true}, + {1, "neat-url.com", 2, true}, + {1, "office-on-the.net", 2, true}, + {1, "on-the-web.tv", 2, true}, + {1, "podzone.net", 2, true}, + {1, "podzone.org", 2, true}, + {1, "readmyblog.org", 2, true}, + {1, "saves-the-whales.com", 2, true}, + {1, "scrapper-site.net", 2, true}, + {1, "scrapping.cc", 2, true}, + {1, "selfip.biz", 2, true}, + {1, "selfip.com", 2, true}, + {1, "selfip.info", 2, true}, + {1, "selfip.net", 2, true}, + {1, "selfip.org", 2, true}, + {1, "sells-for-less.com", 2, true}, + {1, "sells-for-u.com", 2, true}, + {1, "sells-it.net", 2, true}, + {1, "sellsyourhome.org", 2, true}, + {1, "servebbs.com", 2, true}, + {1, "servebbs.net", 2, true}, + {1, "servebbs.org", 2, true}, + {1, "serveftp.net", 2, true}, + {1, "serveftp.org", 2, true}, + {1, "servegame.org", 2, true}, + {1, "shacknet.nu", 2, true}, + {1, "simple-url.com", 2, true}, + {1, "space-to-rent.com", 2, true}, + {1, "stuff-4-sale.org", 2, true}, + {1, "stuff-4-sale.us", 2, true}, + {1, "teaches-yoga.com", 2, true}, + {1, "thruhere.net", 2, true}, + {1, "traeumtgerade.de", 2, true}, + {1, "webhop.biz", 2, true}, + {1, "webhop.info", 2, true}, + {1, "webhop.net", 2, true}, + {1, "webhop.org", 2, true}, + {1, "worse-than.tv", 2, true}, + {1, "writesthisblog.com", 2, true}, + {1, "ddnss.de", 2, true}, + {1, "dyn.ddnss.de", 3, true}, + {1, "dyndns.ddnss.de", 3, true}, + {1, "dyndns1.de", 2, true}, + {1, "dyn-ip24.de", 2, true}, + {1, "home-webserver.de", 2, true}, + {1, "dyn.home-webserver.de", 3, true}, + {1, "myhome-server.de", 2, true}, + {1, "ddnss.org", 2, true}, + {1, "definima.net", 2, true}, + {1, "definima.io", 2, true}, + {1, "bci.dnstrace.pro", 3, true}, + {1, "ddnsfree.com", 2, true}, + {1, "ddnsgeek.com", 2, true}, + {1, "giize.com", 2, true}, + {1, "gleeze.com", 2, true}, + {1, "kozow.com", 2, true}, + {1, "loseyourip.com", 2, true}, + {1, "ooguy.com", 2, true}, + {1, "theworkpc.com", 2, true}, + {1, "casacam.net", 2, true}, + {1, "dynu.net", 2, true}, + {1, "accesscam.org", 2, true}, + {1, "camdvr.org", 2, true}, + {1, "freeddns.org", 2, true}, + {1, "mywire.org", 2, true}, + {1, "webredirect.org", 2, true}, + {1, "myddns.rocks", 2, true}, + {1, "blogsite.xyz", 2, true}, + {1, "dynv6.net", 2, true}, + {1, "e4.cz", 2, true}, + {1, "en-root.fr", 2, true}, + {1, "mytuleap.com", 2, true}, + {1, "onred.one", 2, true}, + {1, "staging.onred.one", 3, true}, + {1, "enonic.io", 2, true}, + {1, "customer.enonic.io", 3, true}, + {1, "eu.org", 2, true}, + {1, "al.eu.org", 3, true}, + {1, "asso.eu.org", 3, true}, + {1, "at.eu.org", 3, true}, + {1, "au.eu.org", 3, true}, + {1, "be.eu.org", 3, true}, + {1, "bg.eu.org", 3, true}, + {1, "ca.eu.org", 3, true}, + {1, "cd.eu.org", 3, true}, + {1, "ch.eu.org", 3, true}, + {1, "cn.eu.org", 3, true}, + {1, "cy.eu.org", 3, true}, + {1, "cz.eu.org", 3, true}, + {1, "de.eu.org", 3, true}, + {1, "dk.eu.org", 3, true}, + {1, "edu.eu.org", 3, true}, + {1, "ee.eu.org", 3, true}, + {1, "es.eu.org", 3, true}, + {1, "fi.eu.org", 3, true}, + {1, "fr.eu.org", 3, true}, + {1, "gr.eu.org", 3, true}, + {1, "hr.eu.org", 3, true}, + {1, "hu.eu.org", 3, true}, + {1, "ie.eu.org", 3, true}, + {1, "il.eu.org", 3, true}, + {1, "in.eu.org", 3, true}, + {1, "int.eu.org", 3, true}, + {1, "is.eu.org", 3, true}, + {1, "it.eu.org", 3, true}, + {1, "jp.eu.org", 3, true}, + {1, "kr.eu.org", 3, true}, + {1, "lt.eu.org", 3, true}, + {1, "lu.eu.org", 3, true}, + {1, "lv.eu.org", 3, true}, + {1, "mc.eu.org", 3, true}, + {1, "me.eu.org", 3, true}, + {1, "mk.eu.org", 3, true}, + {1, "mt.eu.org", 3, true}, + {1, "my.eu.org", 3, true}, + {1, "net.eu.org", 3, true}, + {1, "ng.eu.org", 3, true}, + {1, "nl.eu.org", 3, true}, + {1, "no.eu.org", 3, true}, + {1, "nz.eu.org", 3, true}, + {1, "paris.eu.org", 3, true}, + {1, "pl.eu.org", 3, true}, + {1, "pt.eu.org", 3, true}, + {1, "q-a.eu.org", 3, true}, + {1, "ro.eu.org", 3, true}, + {1, "ru.eu.org", 3, true}, + {1, "se.eu.org", 3, true}, + {1, "si.eu.org", 3, true}, + {1, "sk.eu.org", 3, true}, + {1, "tr.eu.org", 3, true}, + {1, "uk.eu.org", 3, true}, + {1, "us.eu.org", 3, true}, + {1, "eu-1.evennode.com", 3, true}, + {1, "eu-2.evennode.com", 3, true}, + {1, "eu-3.evennode.com", 3, true}, + {1, "eu-4.evennode.com", 3, true}, + {1, "us-1.evennode.com", 3, true}, + {1, "us-2.evennode.com", 3, true}, + {1, "us-3.evennode.com", 3, true}, + {1, "us-4.evennode.com", 3, true}, + {1, "twmail.cc", 2, true}, + {1, "twmail.net", 2, true}, + {1, "twmail.org", 2, true}, + {1, "mymailer.com.tw", 3, true}, + {1, "url.tw", 2, true}, + {1, "apps.fbsbx.com", 3, true}, + {1, "ru.net", 2, true}, + {1, "adygeya.ru", 2, true}, + {1, "bashkiria.ru", 2, true}, + {1, "bir.ru", 2, true}, + {1, "cbg.ru", 2, true}, + {1, "com.ru", 2, true}, + {1, "dagestan.ru", 2, true}, + {1, "grozny.ru", 2, true}, + {1, "kalmykia.ru", 2, true}, + {1, "kustanai.ru", 2, true}, + {1, "marine.ru", 2, true}, + {1, "mordovia.ru", 2, true}, + {1, "msk.ru", 2, true}, + {1, "mytis.ru", 2, true}, + {1, "nalchik.ru", 2, true}, + {1, "nov.ru", 2, true}, + {1, "pyatigorsk.ru", 2, true}, + {1, "spb.ru", 2, true}, + {1, "vladikavkaz.ru", 2, true}, + {1, "vladimir.ru", 2, true}, + {1, "abkhazia.su", 2, true}, + {1, "adygeya.su", 2, true}, + {1, "aktyubinsk.su", 2, true}, + {1, "arkhangelsk.su", 2, true}, + {1, "armenia.su", 2, true}, + {1, "ashgabad.su", 2, true}, + {1, "azerbaijan.su", 2, true}, + {1, "balashov.su", 2, true}, + {1, "bashkiria.su", 2, true}, + {1, "bryansk.su", 2, true}, + {1, "bukhara.su", 2, true}, + {1, "chimkent.su", 2, true}, + {1, "dagestan.su", 2, true}, + {1, "east-kazakhstan.su", 2, true}, + {1, "exnet.su", 2, true}, + {1, "georgia.su", 2, true}, + {1, "grozny.su", 2, true}, + {1, "ivanovo.su", 2, true}, + {1, "jambyl.su", 2, true}, + {1, "kalmykia.su", 2, true}, + {1, "kaluga.su", 2, true}, + {1, "karacol.su", 2, true}, + {1, "karaganda.su", 2, true}, + {1, "karelia.su", 2, true}, + {1, "khakassia.su", 2, true}, + {1, "krasnodar.su", 2, true}, + {1, "kurgan.su", 2, true}, + {1, "kustanai.su", 2, true}, + {1, "lenug.su", 2, true}, + {1, "mangyshlak.su", 2, true}, + {1, "mordovia.su", 2, true}, + {1, "msk.su", 2, true}, + {1, "murmansk.su", 2, true}, + {1, "nalchik.su", 2, true}, + {1, "navoi.su", 2, true}, + {1, "north-kazakhstan.su", 2, true}, + {1, "nov.su", 2, true}, + {1, "obninsk.su", 2, true}, + {1, "penza.su", 2, true}, + {1, "pokrovsk.su", 2, true}, + {1, "sochi.su", 2, true}, + {1, "spb.su", 2, true}, + {1, "tashkent.su", 2, true}, + {1, "termez.su", 2, true}, + {1, "togliatti.su", 2, true}, + {1, "troitsk.su", 2, true}, + {1, "tselinograd.su", 2, true}, + {1, "tula.su", 2, true}, + {1, "tuva.su", 2, true}, + {1, "vladikavkaz.su", 2, true}, + {1, "vladimir.su", 2, true}, + {1, "vologda.su", 2, true}, + {1, "channelsdvr.net", 2, true}, + {1, "u.channelsdvr.net", 3, true}, + {1, "fastly-terrarium.com", 2, true}, + {1, "fastlylb.net", 2, true}, + {1, "map.fastlylb.net", 3, true}, + {1, "freetls.fastly.net", 3, true}, + {1, "map.fastly.net", 3, true}, + {1, "a.prod.fastly.net", 4, true}, + {1, "global.prod.fastly.net", 4, true}, + {1, "a.ssl.fastly.net", 4, true}, + {1, "b.ssl.fastly.net", 4, true}, + {1, "global.ssl.fastly.net", 4, true}, + {1, "fastpanel.direct", 2, true}, + {1, "fastvps-server.com", 2, true}, + {1, "fhapp.xyz", 2, true}, + {1, "fedorainfracloud.org", 2, true}, + {1, "fedorapeople.org", 2, true}, + {1, "cloud.fedoraproject.org", 3, true}, + {1, "app.os.fedoraproject.org", 4, true}, + {1, "app.os.stg.fedoraproject.org", 5, true}, + {1, "mydobiss.com", 2, true}, + {1, "filegear.me", 2, true}, + {1, "filegear-au.me", 2, true}, + {1, "filegear-de.me", 2, true}, + {1, "filegear-gb.me", 2, true}, + {1, "filegear-ie.me", 2, true}, + {1, "filegear-jp.me", 2, true}, + {1, "filegear-sg.me", 2, true}, + {1, "firebaseapp.com", 2, true}, + {1, "flynnhub.com", 2, true}, + {1, "flynnhosting.net", 2, true}, + {1, "0e.vc", 2, true}, + {1, "freebox-os.com", 2, true}, + {1, "freeboxos.com", 2, true}, + {1, "fbx-os.fr", 2, true}, + {1, "fbxos.fr", 2, true}, + {1, "freebox-os.fr", 2, true}, + {1, "freeboxos.fr", 2, true}, + {1, "freedesktop.org", 2, true}, + {2, "futurecms.at", 3, true}, + {2, "ex.futurecms.at", 4, true}, + {2, "in.futurecms.at", 4, true}, + {1, "futurehosting.at", 2, true}, + {1, "futuremailing.at", 2, true}, + {2, "ex.ortsinfo.at", 4, true}, + {2, "kunden.ortsinfo.at", 4, true}, + {2, "statics.cloud", 3, true}, + {1, "service.gov.uk", 3, true}, + {1, "gehirn.ne.jp", 3, true}, + {1, "usercontent.jp", 2, true}, + {1, "gentapps.com", 2, true}, + {1, "lab.ms", 2, true}, + {1, "github.io", 2, true}, + {1, "githubusercontent.com", 2, true}, + {1, "gitlab.io", 2, true}, + {1, "glitch.me", 2, true}, + {1, "lolipop.io", 2, true}, + {1, "cloudapps.digital", 2, true}, + {1, "london.cloudapps.digital", 3, true}, + {1, "homeoffice.gov.uk", 3, true}, + {1, "ro.im", 2, true}, + {1, "shop.ro", 2, true}, + {1, "goip.de", 2, true}, + {1, "run.app", 2, true}, + {1, "a.run.app", 3, true}, + {1, "web.app", 2, true}, + {2, "0emm.com", 3, true}, + {1, "appspot.com", 2, true}, + {2, "r.appspot.com", 4, true}, + {1, "blogspot.ae", 2, true}, + {1, "blogspot.al", 2, true}, + {1, "blogspot.am", 2, true}, + {1, "blogspot.ba", 2, true}, + {1, "blogspot.be", 2, true}, + {1, "blogspot.bg", 2, true}, + {1, "blogspot.bj", 2, true}, + {1, "blogspot.ca", 2, true}, + {1, "blogspot.cf", 2, true}, + {1, "blogspot.ch", 2, true}, + {1, "blogspot.cl", 2, true}, + {1, "blogspot.co.at", 3, true}, + {1, "blogspot.co.id", 3, true}, + {1, "blogspot.co.il", 3, true}, + {1, "blogspot.co.ke", 3, true}, + {1, "blogspot.co.nz", 3, true}, + {1, "blogspot.co.uk", 3, true}, + {1, "blogspot.co.za", 3, true}, + {1, "blogspot.com", 2, true}, + {1, "blogspot.com.ar", 3, true}, + {1, "blogspot.com.au", 3, true}, + {1, "blogspot.com.br", 3, true}, + {1, "blogspot.com.by", 3, true}, + {1, "blogspot.com.co", 3, true}, + {1, "blogspot.com.cy", 3, true}, + {1, "blogspot.com.ee", 3, true}, + {1, "blogspot.com.eg", 3, true}, + {1, "blogspot.com.es", 3, true}, + {1, "blogspot.com.mt", 3, true}, + {1, "blogspot.com.ng", 3, true}, + {1, "blogspot.com.tr", 3, true}, + {1, "blogspot.com.uy", 3, true}, + {1, "blogspot.cv", 2, true}, + {1, "blogspot.cz", 2, true}, + {1, "blogspot.de", 2, true}, + {1, "blogspot.dk", 2, true}, + {1, "blogspot.fi", 2, true}, + {1, "blogspot.fr", 2, true}, + {1, "blogspot.gr", 2, true}, + {1, "blogspot.hk", 2, true}, + {1, "blogspot.hr", 2, true}, + {1, "blogspot.hu", 2, true}, + {1, "blogspot.ie", 2, true}, + {1, "blogspot.in", 2, true}, + {1, "blogspot.is", 2, true}, + {1, "blogspot.it", 2, true}, + {1, "blogspot.jp", 2, true}, + {1, "blogspot.kr", 2, true}, + {1, "blogspot.li", 2, true}, + {1, "blogspot.lt", 2, true}, + {1, "blogspot.lu", 2, true}, + {1, "blogspot.md", 2, true}, + {1, "blogspot.mk", 2, true}, + {1, "blogspot.mr", 2, true}, + {1, "blogspot.mx", 2, true}, + {1, "blogspot.my", 2, true}, + {1, "blogspot.nl", 2, true}, + {1, "blogspot.no", 2, true}, + {1, "blogspot.pe", 2, true}, + {1, "blogspot.pt", 2, true}, + {1, "blogspot.qa", 2, true}, + {1, "blogspot.re", 2, true}, + {1, "blogspot.ro", 2, true}, + {1, "blogspot.rs", 2, true}, + {1, "blogspot.ru", 2, true}, + {1, "blogspot.se", 2, true}, + {1, "blogspot.sg", 2, true}, + {1, "blogspot.si", 2, true}, + {1, "blogspot.sk", 2, true}, + {1, "blogspot.sn", 2, true}, + {1, "blogspot.td", 2, true}, + {1, "blogspot.tw", 2, true}, + {1, "blogspot.ug", 2, true}, + {1, "blogspot.vn", 2, true}, + {1, "cloudfunctions.net", 2, true}, + {1, "cloud.goog", 2, true}, + {1, "codespot.com", 2, true}, + {1, "googleapis.com", 2, true}, + {1, "googlecode.com", 2, true}, + {1, "pagespeedmobilizer.com", 2, true}, + {1, "publishproxy.com", 2, true}, + {1, "withgoogle.com", 2, true}, + {1, "withyoutube.com", 2, true}, + {1, "awsmppl.com", 2, true}, + {1, "fin.ci", 2, true}, + {1, "free.hr", 2, true}, + {1, "caa.li", 2, true}, + {1, "ua.rs", 2, true}, + {1, "conf.se", 2, true}, + {1, "hs.zone", 2, true}, + {1, "hs.run", 2, true}, + {1, "hashbang.sh", 2, true}, + {1, "hasura.app", 2, true}, + {1, "hasura-app.io", 2, true}, + {1, "hepforge.org", 2, true}, + {1, "herokuapp.com", 2, true}, + {1, "herokussl.com", 2, true}, + {1, "myravendb.com", 2, true}, + {1, "ravendb.community", 2, true}, + {1, "ravendb.me", 2, true}, + {1, "development.run", 2, true}, + {1, "ravendb.run", 2, true}, + {1, "bpl.biz", 2, true}, + {1, "orx.biz", 2, true}, + {1, "ng.city", 2, true}, + {1, "biz.gl", 2, true}, + {1, "ng.ink", 2, true}, + {1, "col.ng", 2, true}, + {1, "firm.ng", 2, true}, + {1, "gen.ng", 2, true}, + {1, "ltd.ng", 2, true}, + {1, "ngo.ng", 2, true}, + {1, "ng.school", 2, true}, + {1, "sch.so", 2, true}, + {1, "xn--hkkinen-5wa.fi", 2, true}, + {2, "moonscale.io", 3, true}, + {1, "moonscale.net", 2, true}, + {1, "iki.fi", 2, true}, + {1, "dyn-berlin.de", 2, true}, + {1, "in-berlin.de", 2, true}, + {1, "in-brb.de", 2, true}, + {1, "in-butter.de", 2, true}, + {1, "in-dsl.de", 2, true}, + {1, "in-dsl.net", 2, true}, + {1, "in-dsl.org", 2, true}, + {1, "in-vpn.de", 2, true}, + {1, "in-vpn.net", 2, true}, + {1, "in-vpn.org", 2, true}, + {1, "biz.at", 2, true}, + {1, "info.at", 2, true}, + {1, "info.cx", 2, true}, + {1, "ac.leg.br", 3, true}, + {1, "al.leg.br", 3, true}, + {1, "am.leg.br", 3, true}, + {1, "ap.leg.br", 3, true}, + {1, "ba.leg.br", 3, true}, + {1, "ce.leg.br", 3, true}, + {1, "df.leg.br", 3, true}, + {1, "es.leg.br", 3, true}, + {1, "go.leg.br", 3, true}, + {1, "ma.leg.br", 3, true}, + {1, "mg.leg.br", 3, true}, + {1, "ms.leg.br", 3, true}, + {1, "mt.leg.br", 3, true}, + {1, "pa.leg.br", 3, true}, + {1, "pb.leg.br", 3, true}, + {1, "pe.leg.br", 3, true}, + {1, "pi.leg.br", 3, true}, + {1, "pr.leg.br", 3, true}, + {1, "rj.leg.br", 3, true}, + {1, "rn.leg.br", 3, true}, + {1, "ro.leg.br", 3, true}, + {1, "rr.leg.br", 3, true}, + {1, "rs.leg.br", 3, true}, + {1, "sc.leg.br", 3, true}, + {1, "se.leg.br", 3, true}, + {1, "sp.leg.br", 3, true}, + {1, "to.leg.br", 3, true}, + {1, "pixolino.com", 2, true}, + {1, "ipifony.net", 2, true}, + {1, "mein-iserv.de", 2, true}, + {1, "test-iserv.de", 2, true}, + {1, "iserv.dev", 2, true}, + {1, "iobb.net", 2, true}, + {1, "myjino.ru", 2, true}, + {2, "hosting.myjino.ru", 4, true}, + {2, "landing.myjino.ru", 4, true}, + {2, "spectrum.myjino.ru", 4, true}, + {2, "vps.myjino.ru", 4, true}, + {2, "triton.zone", 3, true}, + {2, "cns.joyent.com", 4, true}, + {1, "js.org", 2, true}, + {1, "kaas.gg", 2, true}, + {1, "khplay.nl", 2, true}, + {1, "keymachine.de", 2, true}, + {1, "kinghost.net", 2, true}, + {1, "uni5.net", 2, true}, + {1, "knightpoint.systems", 2, true}, + {1, "oya.to", 2, true}, + {1, "co.krd", 2, true}, + {1, "edu.krd", 2, true}, + {1, "git-repos.de", 2, true}, + {1, "lcube-server.de", 2, true}, + {1, "svn-repos.de", 2, true}, + {1, "leadpages.co", 2, true}, + {1, "lpages.co", 2, true}, + {1, "lpusercontent.com", 2, true}, + {1, "lelux.site", 2, true}, + {1, "co.business", 2, true}, + {1, "co.education", 2, true}, + {1, "co.events", 2, true}, + {1, "co.financial", 2, true}, + {1, "co.network", 2, true}, + {1, "co.place", 2, true}, + {1, "co.technology", 2, true}, + {1, "app.lmpm.com", 3, true}, + {1, "linkitools.space", 2, true}, + {1, "linkyard.cloud", 2, true}, + {1, "linkyard-cloud.ch", 2, true}, + {1, "members.linode.com", 3, true}, + {1, "nodebalancer.linode.com", 3, true}, + {1, "we.bs", 2, true}, + {1, "loginline.app", 2, true}, + {1, "loginline.dev", 2, true}, + {1, "loginline.io", 2, true}, + {1, "loginline.services", 2, true}, + {1, "loginline.site", 2, true}, + {1, "krasnik.pl", 2, true}, + {1, "leczna.pl", 2, true}, + {1, "lubartow.pl", 2, true}, + {1, "lublin.pl", 2, true}, + {1, "poniatowa.pl", 2, true}, + {1, "swidnik.pl", 2, true}, + {1, "uklugs.org", 2, true}, + {1, "glug.org.uk", 3, true}, + {1, "lug.org.uk", 3, true}, + {1, "lugs.org.uk", 3, true}, + {1, "barsy.bg", 2, true}, + {1, "barsy.co.uk", 3, true}, + {1, "barsyonline.co.uk", 3, true}, + {1, "barsycenter.com", 2, true}, + {1, "barsyonline.com", 2, true}, + {1, "barsy.club", 2, true}, + {1, "barsy.de", 2, true}, + {1, "barsy.eu", 2, true}, + {1, "barsy.in", 2, true}, + {1, "barsy.info", 2, true}, + {1, "barsy.io", 2, true}, + {1, "barsy.me", 2, true}, + {1, "barsy.menu", 2, true}, + {1, "barsy.mobi", 2, true}, + {1, "barsy.net", 2, true}, + {1, "barsy.online", 2, true}, + {1, "barsy.org", 2, true}, + {1, "barsy.pro", 2, true}, + {1, "barsy.pub", 2, true}, + {1, "barsy.shop", 2, true}, + {1, "barsy.site", 2, true}, + {1, "barsy.support", 2, true}, + {1, "barsy.uk", 2, true}, + {2, "magentosite.cloud", 3, true}, + {1, "mayfirst.info", 2, true}, + {1, "mayfirst.org", 2, true}, + {1, "hb.cldmail.ru", 3, true}, + {1, "miniserver.com", 2, true}, + {1, "memset.net", 2, true}, + {1, "cloud.metacentrum.cz", 3, true}, + {1, "custom.metacentrum.cz", 3, true}, + {1, "flt.cloud.muni.cz", 4, true}, + {1, "usr.cloud.muni.cz", 4, true}, + {1, "meteorapp.com", 2, true}, + {1, "eu.meteorapp.com", 3, true}, + {1, "co.pl", 2, true}, + {1, "azurecontainer.io", 2, true}, + {1, "azurewebsites.net", 2, true}, + {1, "azure-mobile.net", 2, true}, + {1, "cloudapp.net", 2, true}, + {1, "mozilla-iot.org", 2, true}, + {1, "bmoattachments.org", 2, true}, + {1, "net.ru", 2, true}, + {1, "org.ru", 2, true}, + {1, "pp.ru", 2, true}, + {1, "ui.nabu.casa", 3, true}, + {1, "pony.club", 2, true}, + {1, "of.fashion", 2, true}, + {1, "on.fashion", 2, true}, + {1, "of.football", 2, true}, + {1, "in.london", 2, true}, + {1, "of.london", 2, true}, + {1, "for.men", 2, true}, + {1, "and.mom", 2, true}, + {1, "for.mom", 2, true}, + {1, "for.one", 2, true}, + {1, "for.sale", 2, true}, + {1, "of.work", 2, true}, + {1, "to.work", 2, true}, + {1, "nctu.me", 2, true}, + {1, "bitballoon.com", 2, true}, + {1, "netlify.com", 2, true}, + {1, "4u.com", 2, true}, + {1, "ngrok.io", 2, true}, + {1, "nh-serv.co.uk", 3, true}, + {1, "nfshost.com", 2, true}, + {1, "dnsking.ch", 2, true}, + {1, "mypi.co", 2, true}, + {1, "n4t.co", 2, true}, + {1, "001www.com", 2, true}, + {1, "ddnslive.com", 2, true}, + {1, "myiphost.com", 2, true}, + {1, "forumz.info", 2, true}, + {1, "16-b.it", 2, true}, + {1, "32-b.it", 2, true}, + {1, "64-b.it", 2, true}, + {1, "soundcast.me", 2, true}, + {1, "tcp4.me", 2, true}, + {1, "dnsup.net", 2, true}, + {1, "hicam.net", 2, true}, + {1, "now-dns.net", 2, true}, + {1, "ownip.net", 2, true}, + {1, "vpndns.net", 2, true}, + {1, "dynserv.org", 2, true}, + {1, "now-dns.org", 2, true}, + {1, "x443.pw", 2, true}, + {1, "now-dns.top", 2, true}, + {1, "ntdll.top", 2, true}, + {1, "freeddns.us", 2, true}, + {1, "crafting.xyz", 2, true}, + {1, "zapto.xyz", 2, true}, + {1, "nsupdate.info", 2, true}, + {1, "nerdpol.ovh", 2, true}, + {1, "blogsyte.com", 2, true}, + {1, "brasilia.me", 2, true}, + {1, "cable-modem.org", 2, true}, + {1, "ciscofreak.com", 2, true}, + {1, "collegefan.org", 2, true}, + {1, "couchpotatofries.org", 2, true}, + {1, "damnserver.com", 2, true}, + {1, "ddns.me", 2, true}, + {1, "ditchyourip.com", 2, true}, + {1, "dnsfor.me", 2, true}, + {1, "dnsiskinky.com", 2, true}, + {1, "dvrcam.info", 2, true}, + {1, "dynns.com", 2, true}, + {1, "eating-organic.net", 2, true}, + {1, "fantasyleague.cc", 2, true}, + {1, "geekgalaxy.com", 2, true}, + {1, "golffan.us", 2, true}, + {1, "health-carereform.com", 2, true}, + {1, "homesecuritymac.com", 2, true}, + {1, "homesecuritypc.com", 2, true}, + {1, "hopto.me", 2, true}, + {1, "ilovecollege.info", 2, true}, + {1, "loginto.me", 2, true}, + {1, "mlbfan.org", 2, true}, + {1, "mmafan.biz", 2, true}, + {1, "myactivedirectory.com", 2, true}, + {1, "mydissent.net", 2, true}, + {1, "myeffect.net", 2, true}, + {1, "mymediapc.net", 2, true}, + {1, "mypsx.net", 2, true}, + {1, "mysecuritycamera.com", 2, true}, + {1, "mysecuritycamera.net", 2, true}, + {1, "mysecuritycamera.org", 2, true}, + {1, "net-freaks.com", 2, true}, + {1, "nflfan.org", 2, true}, + {1, "nhlfan.net", 2, true}, + {1, "no-ip.ca", 2, true}, + {1, "no-ip.co.uk", 3, true}, + {1, "no-ip.net", 2, true}, + {1, "noip.us", 2, true}, + {1, "onthewifi.com", 2, true}, + {1, "pgafan.net", 2, true}, + {1, "point2this.com", 2, true}, + {1, "pointto.us", 2, true}, + {1, "privatizehealthinsurance.net", 2, true}, + {1, "quicksytes.com", 2, true}, + {1, "read-books.org", 2, true}, + {1, "securitytactics.com", 2, true}, + {1, "serveexchange.com", 2, true}, + {1, "servehumour.com", 2, true}, + {1, "servep2p.com", 2, true}, + {1, "servesarcasm.com", 2, true}, + {1, "stufftoread.com", 2, true}, + {1, "ufcfan.org", 2, true}, + {1, "unusualperson.com", 2, true}, + {1, "workisboring.com", 2, true}, + {1, "3utilities.com", 2, true}, + {1, "bounceme.net", 2, true}, + {1, "ddns.net", 2, true}, + {1, "ddnsking.com", 2, true}, + {1, "gotdns.ch", 2, true}, + {1, "hopto.org", 2, true}, + {1, "myftp.biz", 2, true}, + {1, "myftp.org", 2, true}, + {1, "myvnc.com", 2, true}, + {1, "no-ip.biz", 2, true}, + {1, "no-ip.info", 2, true}, + {1, "no-ip.org", 2, true}, + {1, "noip.me", 2, true}, + {1, "redirectme.net", 2, true}, + {1, "servebeer.com", 2, true}, + {1, "serveblog.net", 2, true}, + {1, "servecounterstrike.com", 2, true}, + {1, "serveftp.com", 2, true}, + {1, "servegame.com", 2, true}, + {1, "servehalflife.com", 2, true}, + {1, "servehttp.com", 2, true}, + {1, "serveirc.com", 2, true}, + {1, "serveminecraft.net", 2, true}, + {1, "servemp3.com", 2, true}, + {1, "servepics.com", 2, true}, + {1, "servequake.com", 2, true}, + {1, "sytes.net", 2, true}, + {1, "webhop.me", 2, true}, + {1, "zapto.org", 2, true}, + {1, "stage.nodeart.io", 3, true}, + {1, "nodum.co", 2, true}, + {1, "nodum.io", 2, true}, + {1, "pcloud.host", 2, true}, + {1, "nyc.mn", 2, true}, + {1, "nom.ae", 2, true}, + {1, "nom.af", 2, true}, + {1, "nom.ai", 2, true}, + {1, "nom.al", 2, true}, + {1, "nym.by", 2, true}, + {1, "nym.bz", 2, true}, + {1, "nom.cl", 2, true}, + {1, "nym.ec", 2, true}, + {1, "nom.gd", 2, true}, + {1, "nom.ge", 2, true}, + {1, "nom.gl", 2, true}, + {1, "nym.gr", 2, true}, + {1, "nom.gt", 2, true}, + {1, "nym.gy", 2, true}, + {1, "nym.hk", 2, true}, + {1, "nom.hn", 2, true}, + {1, "nym.ie", 2, true}, + {1, "nom.im", 2, true}, + {1, "nom.ke", 2, true}, + {1, "nym.kz", 2, true}, + {1, "nym.la", 2, true}, + {1, "nym.lc", 2, true}, + {1, "nom.li", 2, true}, + {1, "nym.li", 2, true}, + {1, "nym.lt", 2, true}, + {1, "nym.lu", 2, true}, + {1, "nym.me", 2, true}, + {1, "nom.mk", 2, true}, + {1, "nym.mn", 2, true}, + {1, "nym.mx", 2, true}, + {1, "nom.nu", 2, true}, + {1, "nym.nz", 2, true}, + {1, "nym.pe", 2, true}, + {1, "nym.pt", 2, true}, + {1, "nom.pw", 2, true}, + {1, "nom.qa", 2, true}, + {1, "nym.ro", 2, true}, + {1, "nom.rs", 2, true}, + {1, "nom.si", 2, true}, + {1, "nym.sk", 2, true}, + {1, "nom.st", 2, true}, + {1, "nym.su", 2, true}, + {1, "nym.sx", 2, true}, + {1, "nom.tj", 2, true}, + {1, "nym.tw", 2, true}, + {1, "nom.ug", 2, true}, + {1, "nom.uy", 2, true}, + {1, "nom.vc", 2, true}, + {1, "nom.vg", 2, true}, + {1, "static.observableusercontent.com", 3, true}, + {1, "cya.gg", 2, true}, + {1, "cloudycluster.net", 2, true}, + {1, "nid.io", 2, true}, + {1, "opencraft.hosting", 2, true}, + {1, "operaunite.com", 2, true}, + {1, "skygearapp.com", 2, true}, + {1, "outsystemscloud.com", 2, true}, + {1, "ownprovider.com", 2, true}, + {1, "own.pm", 2, true}, + {1, "ox.rs", 2, true}, + {1, "oy.lc", 2, true}, + {1, "pgfog.com", 2, true}, + {1, "pagefrontapp.com", 2, true}, + {1, "art.pl", 2, true}, + {1, "gliwice.pl", 2, true}, + {1, "krakow.pl", 2, true}, + {1, "poznan.pl", 2, true}, + {1, "wroc.pl", 2, true}, + {1, "zakopane.pl", 2, true}, + {1, "pantheonsite.io", 2, true}, + {1, "gotpantheon.com", 2, true}, + {1, "mypep.link", 2, true}, + {1, "perspecta.cloud", 2, true}, + {1, "on-web.fr", 2, true}, + {2, "platform.sh", 3, true}, + {2, "platformsh.site", 3, true}, + {1, "dyn53.io", 2, true}, + {1, "co.bn", 2, true}, + {1, "xen.prgmr.com", 3, true}, + {1, "priv.at", 2, true}, + {1, "prvcy.page", 2, true}, + {2, "dweb.link", 3, true}, + {1, "protonet.io", 2, true}, + {1, "chirurgiens-dentistes-en-france.fr", 2, true}, + {1, "byen.site", 2, true}, + {1, "pubtls.org", 2, true}, + {1, "qualifioapp.com", 2, true}, + {1, "qbuser.com", 2, true}, + {1, "instantcloud.cn", 2, true}, + {1, "ras.ru", 2, true}, + {1, "qa2.com", 2, true}, + {1, "qcx.io", 2, true}, + {2, "sys.qcx.io", 4, true}, + {1, "dev-myqnapcloud.com", 2, true}, + {1, "alpha-myqnapcloud.com", 2, true}, + {1, "myqnapcloud.com", 2, true}, + {2, "quipelements.com", 3, true}, + {1, "vapor.cloud", 2, true}, + {1, "vaporcloud.io", 2, true}, + {1, "rackmaze.com", 2, true}, + {1, "rackmaze.net", 2, true}, + {2, "on-k3s.io", 3, true}, + {2, "on-rancher.cloud", 3, true}, + {2, "on-rio.io", 3, true}, + {1, "readthedocs.io", 2, true}, + {1, "rhcloud.com", 2, true}, + {1, "app.render.com", 3, true}, + {1, "onrender.com", 2, true}, + {1, "repl.co", 2, true}, + {1, "repl.run", 2, true}, + {1, "resindevice.io", 2, true}, + {1, "devices.resinstaging.io", 3, true}, + {1, "hzc.io", 2, true}, + {1, "wellbeingzone.eu", 2, true}, + {1, "ptplus.fit", 2, true}, + {1, "wellbeingzone.co.uk", 3, true}, + {1, "git-pages.rit.edu", 3, true}, + {1, "sandcats.io", 2, true}, + {1, "logoip.de", 2, true}, + {1, "logoip.com", 2, true}, + {1, "schokokeks.net", 2, true}, + {1, "gov.scot", 2, true}, + {1, "scrysec.com", 2, true}, + {1, "firewall-gateway.com", 2, true}, + {1, "firewall-gateway.de", 2, true}, + {1, "my-gateway.de", 2, true}, + {1, "my-router.de", 2, true}, + {1, "spdns.de", 2, true}, + {1, "spdns.eu", 2, true}, + {1, "firewall-gateway.net", 2, true}, + {1, "my-firewall.org", 2, true}, + {1, "myfirewall.org", 2, true}, + {1, "spdns.org", 2, true}, + {1, "senseering.net", 2, true}, + {1, "biz.ua", 2, true}, + {1, "co.ua", 2, true}, + {1, "pp.ua", 2, true}, + {1, "shiftedit.io", 2, true}, + {1, "myshopblocks.com", 2, true}, + {1, "shopitsite.com", 2, true}, + {1, "mo-siemens.io", 2, true}, + {1, "1kapp.com", 2, true}, + {1, "appchizi.com", 2, true}, + {1, "applinzi.com", 2, true}, + {1, "sinaapp.com", 2, true}, + {1, "vipsinaapp.com", 2, true}, + {1, "siteleaf.net", 2, true}, + {1, "bounty-full.com", 2, true}, + {1, "alpha.bounty-full.com", 3, true}, + {1, "beta.bounty-full.com", 3, true}, + {1, "stackhero-network.com", 2, true}, + {1, "static.land", 2, true}, + {1, "dev.static.land", 3, true}, + {1, "sites.static.land", 3, true}, + {1, "apps.lair.io", 3, true}, + {2, "stolos.io", 3, true}, + {1, "spacekit.io", 2, true}, + {1, "customer.speedpartner.de", 3, true}, + {1, "api.stdlib.com", 3, true}, + {1, "storj.farm", 2, true}, + {1, "utwente.io", 2, true}, + {1, "soc.srcf.net", 3, true}, + {1, "user.srcf.net", 3, true}, + {1, "temp-dns.com", 2, true}, + {1, "applicationcloud.io", 2, true}, + {1, "scapp.io", 2, true}, + {2, "s5y.io", 3, true}, + {2, "sensiosite.cloud", 3, true}, + {1, "syncloud.it", 2, true}, + {1, "diskstation.me", 2, true}, + {1, "dscloud.biz", 2, true}, + {1, "dscloud.me", 2, true}, + {1, "dscloud.mobi", 2, true}, + {1, "dsmynas.com", 2, true}, + {1, "dsmynas.net", 2, true}, + {1, "dsmynas.org", 2, true}, + {1, "familyds.com", 2, true}, + {1, "familyds.net", 2, true}, + {1, "familyds.org", 2, true}, + {1, "i234.me", 2, true}, + {1, "myds.me", 2, true}, + {1, "synology.me", 2, true}, + {1, "vpnplus.to", 2, true}, + {1, "direct.quickconnect.to", 3, true}, + {1, "taifun-dns.de", 2, true}, + {1, "gda.pl", 2, true}, + {1, "gdansk.pl", 2, true}, + {1, "gdynia.pl", 2, true}, + {1, "med.pl", 2, true}, + {1, "sopot.pl", 2, true}, + {1, "edugit.org", 2, true}, + {1, "telebit.app", 2, true}, + {1, "telebit.io", 2, true}, + {2, "telebit.xyz", 3, true}, + {1, "gwiddle.co.uk", 3, true}, + {1, "thingdustdata.com", 2, true}, + {1, "cust.dev.thingdust.io", 4, true}, + {1, "cust.disrec.thingdust.io", 4, true}, + {1, "cust.prod.thingdust.io", 4, true}, + {1, "cust.testing.thingdust.io", 4, true}, + {1, "arvo.network", 2, true}, + {1, "azimuth.network", 2, true}, + {1, "bloxcms.com", 2, true}, + {1, "townnews-staging.com", 2, true}, + {1, "12hp.at", 2, true}, + {1, "2ix.at", 2, true}, + {1, "4lima.at", 2, true}, + {1, "lima-city.at", 2, true}, + {1, "12hp.ch", 2, true}, + {1, "2ix.ch", 2, true}, + {1, "4lima.ch", 2, true}, + {1, "lima-city.ch", 2, true}, + {1, "trafficplex.cloud", 2, true}, + {1, "de.cool", 2, true}, + {1, "12hp.de", 2, true}, + {1, "2ix.de", 2, true}, + {1, "4lima.de", 2, true}, + {1, "lima-city.de", 2, true}, + {1, "1337.pictures", 2, true}, + {1, "clan.rip", 2, true}, + {1, "lima-city.rocks", 2, true}, + {1, "webspace.rocks", 2, true}, + {1, "lima.zone", 2, true}, + {2, "transurl.be", 3, true}, + {2, "transurl.eu", 3, true}, + {2, "transurl.nl", 3, true}, + {1, "tuxfamily.org", 2, true}, + {1, "dd-dns.de", 2, true}, + {1, "diskstation.eu", 2, true}, + {1, "diskstation.org", 2, true}, + {1, "dray-dns.de", 2, true}, + {1, "draydns.de", 2, true}, + {1, "dyn-vpn.de", 2, true}, + {1, "dynvpn.de", 2, true}, + {1, "mein-vigor.de", 2, true}, + {1, "my-vigor.de", 2, true}, + {1, "my-wan.de", 2, true}, + {1, "syno-ds.de", 2, true}, + {1, "synology-diskstation.de", 2, true}, + {1, "synology-ds.de", 2, true}, + {1, "uber.space", 2, true}, + {2, "uberspace.de", 3, true}, + {1, "hk.com", 2, true}, + {1, "hk.org", 2, true}, + {1, "ltd.hk", 2, true}, + {1, "inc.hk", 2, true}, + {1, "virtualuser.de", 2, true}, + {1, "virtual-user.de", 2, true}, + {1, "lib.de.us", 3, true}, + {1, "2038.io", 2, true}, + {1, "router.management", 2, true}, + {1, "v-info.info", 2, true}, + {1, "voorloper.cloud", 2, true}, + {1, "v.ua", 2, true}, + {1, "wafflecell.com", 2, true}, + {2, "webhare.dev", 3, true}, + {1, "wedeploy.io", 2, true}, + {1, "wedeploy.me", 2, true}, + {1, "wedeploy.sh", 2, true}, + {1, "remotewd.com", 2, true}, + {1, "wmflabs.org", 2, true}, + {1, "myforum.community", 2, true}, + {1, "community-pro.de", 2, true}, + {1, "diskussionsbereich.de", 2, true}, + {1, "community-pro.net", 2, true}, + {1, "meinforum.net", 2, true}, + {1, "half.host", 2, true}, + {1, "xnbay.com", 2, true}, + {1, "u2.xnbay.com", 3, true}, + {1, "u2-local.xnbay.com", 3, true}, + {1, "cistron.nl", 2, true}, + {1, "demon.nl", 2, true}, + {1, "xs4all.space", 2, true}, + {1, "yandexcloud.net", 2, true}, + {1, "storage.yandexcloud.net", 3, true}, + {1, "website.yandexcloud.net", 3, true}, + {1, "official.academy", 2, true}, + {1, "yolasite.com", 2, true}, + {1, "ybo.faith", 2, true}, + {1, "yombo.me", 2, true}, + {1, "homelink.one", 2, true}, + {1, "ybo.party", 2, true}, + {1, "ybo.review", 2, true}, + {1, "ybo.science", 2, true}, + {1, "ybo.trade", 2, true}, + {1, "nohost.me", 2, true}, + {1, "noho.st", 2, true}, + {1, "za.net", 2, true}, + {1, "za.org", 2, true}, + {1, "now.sh", 2, true}, + {1, "bss.design", 2, true}, + {1, "basicserver.io", 2, true}, + {1, "virtualserver.io", 2, true}, + {1, "site.builder.nu", 3, true}, + {1, "enterprisecloud.nu", 2, true}, +} + +func init() { + for i := range r { + DefaultList.AddRule(&r[i]) + } +} diff --git a/vendor/github.com/zmap/zcrypto/LICENSE b/vendor/github.com/zmap/zcrypto/LICENSE new file mode 100644 index 0000000000..830522ba23 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/LICENSE @@ -0,0 +1,257 @@ +ZCrypto is an original work created at the University of Michigan, and is +licensed under the Apache 2.0 license. However, ZCrypto contains a fork of +several packages from Golang standard library, as well as code from the +BoringSSL test runner. Files that were created by Google, and new files in +forks of packages maintained by Google have a Google copyright and fall under +the ISC license. In addition ZCrypto includes a `util/isURL.go` file created by +Alex Saskevich and licensed under the MIT license. All other files are copyright +Regents of the University of Michigan, and fall under the Apache 2.0 license. +All three licenses are reproduced at the bottom of this file. + +-------- + +ISC License used for Google code + +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +-------- + +MIT License used for util/isURL.go adopted from https://github.com/asaskevich/govalidator + + The MIT License (MIT) + + Copyright (c) 2014 Alex Saskevich + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +-------- + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + ZCrypto Copyright 2015 Regents of the University of Michigan + + Licensed 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. diff --git a/vendor/github.com/zmap/zcrypto/json/dhe.go b/vendor/github.com/zmap/zcrypto/json/dhe.go new file mode 100644 index 0000000000..0d4770bca3 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/json/dhe.go @@ -0,0 +1,130 @@ +/* + * ZGrab Copyright 2015 Regents of the University of Michigan + * + * Licensed 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. + */ + +package json + +import ( + "encoding/json" + "math/big" +) + +// DHParams can be used to store finite-field Diffie-Hellman parameters. At any +// point in time, it is unlikely that both OurPrivate and TheirPrivate will be +// non-nil. +type DHParams struct { + Prime *big.Int + Generator *big.Int + ServerPublic *big.Int + ServerPrivate *big.Int + ClientPublic *big.Int + ClientPrivate *big.Int + SessionKey *big.Int +} + +type auxDHParams struct { + Prime *cryptoParameter `json:"prime"` + Generator *cryptoParameter `json:"generator"` + ServerPublic *cryptoParameter `json:"server_public,omitempty"` + ServerPrivate *cryptoParameter `json:"server_private,omitempty"` + ClientPublic *cryptoParameter `json:"client_public,omitempty"` + ClientPrivate *cryptoParameter `json:"client_private,omitempty"` + SessionKey *cryptoParameter `json:"session_key,omitempty"` +} + +// MarshalJSON implements the json.Marshal interface +func (p *DHParams) MarshalJSON() ([]byte, error) { + aux := auxDHParams{ + Prime: &cryptoParameter{Int: p.Prime}, + Generator: &cryptoParameter{Int: p.Generator}, + } + if p.ServerPublic != nil { + aux.ServerPublic = &cryptoParameter{Int: p.ServerPublic} + } + if p.ServerPrivate != nil { + aux.ServerPrivate = &cryptoParameter{Int: p.ServerPrivate} + } + if p.ClientPublic != nil { + aux.ClientPublic = &cryptoParameter{Int: p.ClientPublic} + } + if p.ClientPrivate != nil { + aux.ClientPrivate = &cryptoParameter{Int: p.ClientPrivate} + } + if p.SessionKey != nil { + aux.SessionKey = &cryptoParameter{Int: p.SessionKey} + } + return json.Marshal(aux) +} + +// UnmarshalJSON implement the json.Unmarshaler interface +func (p *DHParams) UnmarshalJSON(b []byte) error { + var aux auxDHParams + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + if aux.Prime != nil { + p.Prime = aux.Prime.Int + } + if aux.Generator != nil { + p.Generator = aux.Generator.Int + } + if aux.ServerPublic != nil { + p.ServerPublic = aux.ServerPublic.Int + } + if aux.ServerPrivate != nil { + p.ServerPrivate = aux.ServerPrivate.Int + } + if aux.ClientPublic != nil { + p.ClientPublic = aux.ClientPublic.Int + } + if aux.ClientPrivate != nil { + p.ClientPrivate = aux.ClientPrivate.Int + } + if aux.SessionKey != nil { + p.SessionKey = aux.SessionKey.Int + } + return nil +} + +// CryptoParameter represents a big.Int used a parameter in some cryptography. +// It serializes to json as a tupe of a base64-encoded number and a length in +// bits. +type cryptoParameter struct { + *big.Int +} + +type auxCryptoParameter struct { + Raw []byte `json:"value"` + Length int `json:"length"` +} + +// MarshalJSON implements the json.Marshaler interface +func (p *cryptoParameter) MarshalJSON() ([]byte, error) { + var aux auxCryptoParameter + if p.Int != nil { + aux.Raw = p.Bytes() + aux.Length = 8 * len(aux.Raw) + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshal interface +func (p *cryptoParameter) UnmarshalJSON(b []byte) error { + var aux auxCryptoParameter + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + p.Int = new(big.Int) + p.SetBytes(aux.Raw) + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/json/ecdhe.go b/vendor/github.com/zmap/zcrypto/json/ecdhe.go new file mode 100644 index 0000000000..5d3d19179c --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/json/ecdhe.go @@ -0,0 +1,107 @@ +/* + * ZGrab Copyright 2015 Regents of the University of Michigan + * + * Licensed 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. + */ + +package json + +import ( + "crypto/elliptic" + "encoding/json" + "math/big" +) + +// TLSCurveID is the type of a TLS identifier for an elliptic curve. See +// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 +type TLSCurveID uint16 + +// ECDHPrivateParams are the TLS key exchange parameters for ECDH keys. +type ECDHPrivateParams struct { + Value []byte `json:"value,omitempty"` + Length int `json:"length,omitempty"` +} + +// ECDHParams stores elliptic-curve Diffie-Hellman paramters.At any point in +// time, it is unlikely that both ServerPrivate and ClientPrivate will be non-nil. +type ECDHParams struct { + TLSCurveID TLSCurveID `json:"curve_id,omitempty"` + Curve elliptic.Curve `json:"-"` + ServerPublic *ECPoint `json:"server_public,omitempty"` + ServerPrivate *ECDHPrivateParams `json:"server_private,omitempty"` + ClientPublic *ECPoint `json:"client_public,omitempty"` + ClientPrivate *ECDHPrivateParams `json:"client_private,omitempty"` +} + +// ECPoint represents an elliptic curve point and serializes nicely to JSON +type ECPoint struct { + X *big.Int + Y *big.Int +} + +// MarshalJSON implements the json.Marshler interface +func (p *ECPoint) MarshalJSON() ([]byte, error) { + aux := struct { + X *cryptoParameter `json:"x"` + Y *cryptoParameter `json:"y"` + }{ + X: &cryptoParameter{Int: p.X}, + Y: &cryptoParameter{Int: p.Y}, + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshler interface +func (p *ECPoint) UnmarshalJSON(b []byte) error { + aux := struct { + X *cryptoParameter `json:"x"` + Y *cryptoParameter `json:"y"` + }{} + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + p.X = aux.X.Int + p.Y = aux.Y.Int + return nil +} + +// Description returns the description field for the given ID. See +// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 +func (c *TLSCurveID) Description() string { + if desc, ok := ecIDToName[*c]; ok { + return desc + } + return "unknown" +} + +// MarshalJSON implements the json.Marshaler interface +func (c *TLSCurveID) MarshalJSON() ([]byte, error) { + aux := struct { + Name string `json:"name"` + ID uint16 `json:"id"` + }{ + Name: c.Description(), + ID: uint16(*c), + } + return json.Marshal(&aux) +} + +//UnmarshalJSON implements the json.Unmarshaler interface +func (c *TLSCurveID) UnmarshalJSON(b []byte) error { + aux := struct { + ID uint16 `json:"id"` + }{} + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + *c = TLSCurveID(aux.ID) + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/json/names.go b/vendor/github.com/zmap/zcrypto/json/names.go new file mode 100644 index 0000000000..3882824867 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/json/names.go @@ -0,0 +1,113 @@ +/* + * ZGrab Copyright 2015 Regents of the University of Michigan + * + * Licensed 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. + */ + +package json + +// IANA-assigned curve ID values, see +// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 +const ( + Sect163k1 TLSCurveID = 1 + Sect163r1 TLSCurveID = 2 + Sect163r2 TLSCurveID = 3 + Sect193r1 TLSCurveID = 4 + Sect193r2 TLSCurveID = 5 + Sect233k1 TLSCurveID = 6 + Sect233r1 TLSCurveID = 7 + Sect239k1 TLSCurveID = 8 + Sect283k1 TLSCurveID = 9 + Sect283r1 TLSCurveID = 10 + Sect409k1 TLSCurveID = 11 + Sect409r1 TLSCurveID = 12 + Sect571k1 TLSCurveID = 13 + Sect571r1 TLSCurveID = 14 + Secp160k1 TLSCurveID = 15 + Secp160r1 TLSCurveID = 16 + Secp160r2 TLSCurveID = 17 + Secp192k1 TLSCurveID = 18 + Secp192r1 TLSCurveID = 19 + Secp224k1 TLSCurveID = 20 + Secp224r1 TLSCurveID = 21 + Secp256k1 TLSCurveID = 22 + Secp256r1 TLSCurveID = 23 + Secp384r1 TLSCurveID = 24 + Secp521r1 TLSCurveID = 25 + BrainpoolP256r1 TLSCurveID = 26 + BrainpoolP384r1 TLSCurveID = 27 + BrainpoolP512r1 TLSCurveID = 28 +) + +var ecIDToName map[TLSCurveID]string +var ecNameToID map[string]TLSCurveID + +func init() { + ecIDToName = make(map[TLSCurveID]string, 64) + ecIDToName[Sect163k1] = "sect163k1" + ecIDToName[Sect163r1] = "sect163r1" + ecIDToName[Sect163r2] = "sect163r2" + ecIDToName[Sect193r1] = "sect193r1" + ecIDToName[Sect193r2] = "sect193r2" + ecIDToName[Sect233k1] = "sect233k1" + ecIDToName[Sect233r1] = "sect233r1" + ecIDToName[Sect239k1] = "sect239k1" + ecIDToName[Sect283k1] = "sect283k1" + ecIDToName[Sect283r1] = "sect283r1" + ecIDToName[Sect409k1] = "sect409k1" + ecIDToName[Sect409r1] = "sect409r1" + ecIDToName[Sect571k1] = "sect571k1" + ecIDToName[Sect571r1] = "sect571r1" + ecIDToName[Secp160k1] = "secp160k1" + ecIDToName[Secp160r1] = "secp160r1" + ecIDToName[Secp160r2] = "secp160r2" + ecIDToName[Secp192k1] = "secp192k1" + ecIDToName[Secp192r1] = "secp192r1" + ecIDToName[Secp224k1] = "secp224k1" + ecIDToName[Secp224r1] = "secp224r1" + ecIDToName[Secp256k1] = "secp256k1" + ecIDToName[Secp256r1] = "secp256r1" + ecIDToName[Secp384r1] = "secp384r1" + ecIDToName[Secp521r1] = "secp521r1" + ecIDToName[BrainpoolP256r1] = "brainpoolp256r1" + ecIDToName[BrainpoolP384r1] = "brainpoolp384r1" + ecIDToName[BrainpoolP512r1] = "brainpoolp512r1" + + ecNameToID = make(map[string]TLSCurveID, 64) + ecNameToID["sect163k1"] = Sect163k1 + ecNameToID["sect163r1"] = Sect163r1 + ecNameToID["sect163r2"] = Sect163r2 + ecNameToID["sect193r1"] = Sect193r1 + ecNameToID["sect193r2"] = Sect193r2 + ecNameToID["sect233k1"] = Sect233k1 + ecNameToID["sect233r1"] = Sect233r1 + ecNameToID["sect239k1"] = Sect239k1 + ecNameToID["sect283k1"] = Sect283k1 + ecNameToID["sect283r1"] = Sect283r1 + ecNameToID["sect409k1"] = Sect409k1 + ecNameToID["sect409r1"] = Sect409r1 + ecNameToID["sect571k1"] = Sect571k1 + ecNameToID["sect571r1"] = Sect571r1 + ecNameToID["secp160k1"] = Secp160k1 + ecNameToID["secp160r1"] = Secp160r1 + ecNameToID["secp160r2"] = Secp160r2 + ecNameToID["secp192k1"] = Secp192k1 + ecNameToID["secp192r1"] = Secp192r1 + ecNameToID["secp224k1"] = Secp224k1 + ecNameToID["secp224r1"] = Secp224r1 + ecNameToID["secp256k1"] = Secp256k1 + ecNameToID["secp256r1"] = Secp256r1 + ecNameToID["secp384r1"] = Secp384r1 + ecNameToID["secp521r1"] = Secp521r1 + ecNameToID["brainpoolp256r1"] = BrainpoolP256r1 + ecNameToID["brainpoolp384r1"] = BrainpoolP384r1 + ecNameToID["brainpoolp512r1"] = BrainpoolP512r1 +} diff --git a/vendor/github.com/zmap/zcrypto/json/rsa.go b/vendor/github.com/zmap/zcrypto/json/rsa.go new file mode 100644 index 0000000000..270256973b --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/json/rsa.go @@ -0,0 +1,67 @@ +/* + * ZGrab Copyright 2015 Regents of the University of Michigan + * + * Licensed 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. + */ + +package json + +import ( + "crypto/rsa" + "encoding/json" + "fmt" + "math/big" +) + +// RSAPublicKey provides JSON methods for the standard rsa.PublicKey. +type RSAPublicKey struct { + *rsa.PublicKey +} + +type auxRSAPublicKey struct { + Exponent int `json:"exponent"` + Modulus []byte `json:"modulus"` + Length int `json:"length"` +} + +// RSAClientParams are the TLS key exchange parameters for RSA keys. +type RSAClientParams struct { + Length uint16 `json:"length,omitempty"` + EncryptedPMS []byte `json:"encrypted_pre_master_secret,omitempty"` +} + +// MarshalJSON implements the json.Marshal interface +func (rp *RSAPublicKey) MarshalJSON() ([]byte, error) { + var aux auxRSAPublicKey + if rp.PublicKey != nil { + aux.Exponent = rp.E + aux.Modulus = rp.N.Bytes() + aux.Length = len(aux.Modulus) * 8 + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshal interface +func (rp *RSAPublicKey) UnmarshalJSON(b []byte) error { + var aux auxRSAPublicKey + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + if rp.PublicKey == nil { + rp.PublicKey = new(rsa.PublicKey) + } + rp.E = aux.Exponent + rp.N = big.NewInt(0).SetBytes(aux.Modulus) + if len(aux.Modulus)*8 != aux.Length { + return fmt.Errorf("mismatched length (got %d, field specified %d)", len(aux.Modulus), aux.Length) + } + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/util/isURL.go b/vendor/github.com/zmap/zcrypto/util/isURL.go new file mode 100644 index 0000000000..6a09a471a0 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/util/isURL.go @@ -0,0 +1,77 @@ +/* +The MIT License (MIT) + +Copyright (c) 2014 Alex Saskevich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +package util + +import ( + "net/url" + "regexp" + "strings" + "unicode/utf8" +) + +const ( + maxURLRuneCount = 2083 + minURLRuneCount = 3 + + IP = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))` + URLSchema = `((ftp|tcp|udp|wss?|https?):\/\/)` + URLUsername = `(\S+(:\S*)?@)` + URLPath = `((\/|\?|#)[^\s]*)` + URLPort = `(:(\d{1,5}))` + URLIP = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))` + URLSubdomain = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` +) + +var ( + URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$` + rxURL = regexp.MustCompile(URL) +) + +// IsURL check if the string is an URL. +// This function is (graciously) adopted from +// https://github.com/asaskevich/govalidator to avoid needing a full dependency on +// `govalidator` for the one `IsURL` function. +func IsURL(str string) bool { + if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { + return false + } + strTemp := str + if strings.Contains(str, ":") && !strings.Contains(str, "://") { + // support no indicated urlscheme but with colon for port number + // http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString + strTemp = "http://" + str + } + u, err := url.Parse(strTemp) + if err != nil { + return false + } + if strings.HasPrefix(u.Host, ".") { + return false + } + if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) { + return false + } + return rxURL.MatchString(str) +} diff --git a/vendor/github.com/zmap/zcrypto/x509/README.md b/vendor/github.com/zmap/zcrypto/x509/README.md new file mode 100644 index 0000000000..e2a2883508 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/README.md @@ -0,0 +1,8 @@ +Originally based on the go/crypto/x509 standard library, +this package has now diverged enough that it is no longer +updated with direct correspondence to new go releases. + +Approximately supports all the features of +github.com/golang/go/crypto/x509 package at: +branch: release-branch.go1.10 +revision: dea961ebd9f871b39b3bdaab32f952037f28cd71 diff --git a/vendor/github.com/zmap/zcrypto/x509/cert_pool.go b/vendor/github.com/zmap/zcrypto/x509/cert_pool.go new file mode 100644 index 0000000000..a6c6d2b036 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/cert_pool.go @@ -0,0 +1,171 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "encoding/pem" +) + +// CertPool is a set of certificates. +type CertPool struct { + bySubjectKeyId map[string][]int + byName map[string][]int + bySHA256 map[string]int + certs []*Certificate +} + +// NewCertPool returns a new, empty CertPool. +func NewCertPool() *CertPool { + return &CertPool{ + bySubjectKeyId: make(map[string][]int), + byName: make(map[string][]int), + bySHA256: make(map[string]int), + } +} + +// findVerifiedParents attempts to find certificates in s which have signed the +// given certificate. If any candidates were rejected then errCert will be set +// to one of them, arbitrarily, and err will contain the reason that it was +// rejected. +func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCert *Certificate, err error) { + if s == nil { + return + } + var candidates []int + + if len(cert.AuthorityKeyId) > 0 { + candidates, _ = s.bySubjectKeyId[string(cert.AuthorityKeyId)] + } + if len(candidates) == 0 { + candidates, _ = s.byName[string(cert.RawIssuer)] + } + + for _, c := range candidates { + if err = cert.CheckSignatureFrom(s.certs[c]); err == nil { + cert.validSignature = true + parents = append(parents, c) + } else { + errCert = s.certs[c] + } + } + + return +} + +// Contains returns true if c is in s. +func (s *CertPool) Contains(c *Certificate) bool { + if s == nil { + return false + } + _, ok := s.bySHA256[string(c.FingerprintSHA256)] + return ok +} + +// Covers returns true if all certs in pool are in s. +func (s *CertPool) Covers(pool *CertPool) bool { + if pool == nil { + return true + } + for _, c := range pool.certs { + if !s.Contains(c) { + return false + } + } + return true +} + +// Certificates returns a list of parsed certificates in the pool. +func (s *CertPool) Certificates() []*Certificate { + out := make([]*Certificate, 0, len(s.certs)) + out = append(out, s.certs...) + return out +} + +// Size returns the number of unique certificates in the CertPool. +func (s *CertPool) Size() int { + if s == nil { + return 0 + } + return len(s.certs) +} + +// Sum returns the union of two certificate pools as a new certificate pool. +func (s *CertPool) Sum(other *CertPool) (sum *CertPool) { + sum = NewCertPool() + if s != nil { + for _, c := range s.certs { + sum.AddCert(c) + } + } + if other != nil { + for _, c := range other.certs { + sum.AddCert(c) + } + } + return +} + +// AddCert adds a certificate to a pool. +func (s *CertPool) AddCert(cert *Certificate) { + if cert == nil { + panic("adding nil Certificate to CertPool") + } + + // Check that the certificate isn't being added twice. + sha256fp := string(cert.FingerprintSHA256) + if _, ok := s.bySHA256[sha256fp]; ok { + return + } + + n := len(s.certs) + s.certs = append(s.certs, cert) + + if len(cert.SubjectKeyId) > 0 { + keyId := string(cert.SubjectKeyId) + s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n) + } + name := string(cert.RawSubject) + s.byName[name] = append(s.byName[name], n) + s.bySHA256[sha256fp] = n +} + +// AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. +// It appends any certificates found to s and reports whether any certificates +// were successfully parsed. +// +// On many Linux systems, /etc/ssl/cert.pem will contain the system wide set +// of root CAs in a format suitable for this function. +func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) { + for len(pemCerts) > 0 { + var block *pem.Block + block, pemCerts = pem.Decode(pemCerts) + if block == nil { + break + } + if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { + continue + } + + cert, err := ParseCertificate(block.Bytes) + if err != nil { + continue + } + + s.AddCert(cert) + ok = true + } + + return +} + +// Subjects returns a list of the DER-encoded subjects of +// all of the certificates in the pool. +func (s *CertPool) Subjects() [][]byte { + res := make([][]byte, len(s.certs)) + for i, c := range s.certs { + res[i] = c.RawSubject + } + return res +} diff --git a/vendor/github.com/zmap/zcrypto/x509/certificate_type.go b/vendor/github.com/zmap/zcrypto/x509/certificate_type.go new file mode 100644 index 0000000000..7bb7f32476 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/certificate_type.go @@ -0,0 +1,64 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import "encoding/json" + +// TODO: Automatically generate this file from a CSV + +// CertificateType represents whether a certificate is a root, intermediate, or +// leaf. +type CertificateType int + +// CertificateType constants. Values should not be considered significant aside +// from CertificateTypeUnknown is the zero value. +const ( + CertificateTypeUnknown CertificateType = 0 + CertificateTypeLeaf CertificateType = 1 + CertificateTypeIntermediate CertificateType = 2 + CertificateTypeRoot CertificateType = 3 +) + +const ( + certificateTypeStringLeaf = "leaf" + certificateTypeStringIntermediate = "intermediate" + certificateTypeStringRoot = "root" + certificateTypeStringUnknown = "unknown" +) + +// MarshalJSON implements the json.Marshaler interface. Any unknown integer +// value is considered the same as CertificateTypeUnknown. +func (t CertificateType) MarshalJSON() ([]byte, error) { + switch t { + case CertificateTypeLeaf: + return json.Marshal(certificateTypeStringLeaf) + case CertificateTypeIntermediate: + return json.Marshal(certificateTypeStringIntermediate) + case CertificateTypeRoot: + return json.Marshal(certificateTypeStringRoot) + default: + return json.Marshal(certificateTypeStringUnknown) + } +} + +// UnmarshalJSON implements the json.Unmarshaler interface. Any unknown string +// is considered the same CertificateTypeUnknown. +func (t *CertificateType) UnmarshalJSON(b []byte) error { + var certificateTypeString string + if err := json.Unmarshal(b, &certificateTypeString); err != nil { + return err + } + switch certificateTypeString { + case certificateTypeStringLeaf: + *t = CertificateTypeLeaf + case certificateTypeStringIntermediate: + *t = CertificateTypeIntermediate + case certificateTypeStringRoot: + *t = CertificateTypeRoot + default: + *t = CertificateTypeUnknown + } + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/chain.go b/vendor/github.com/zmap/zcrypto/x509/chain.go new file mode 100644 index 0000000000..bca0f278ce --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/chain.go @@ -0,0 +1,70 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "bytes" + "strings" +) + +// CertificateChain is a slice of certificates. The 0'th element is the leaf, +// and the last element is a root. Successive elements have a child-parent +// relationship. +type CertificateChain []*Certificate + +// Range runs a function on each element of chain. It can modify each +// certificate in place. +func (chain CertificateChain) Range(f func(int, *Certificate)) { + for i, c := range chain { + f(i, c) + } +} + +// SubjectAndKeyInChain returns true if the given SubjectAndKey is found in any +// certificate in the chain. +func (chain CertificateChain) SubjectAndKeyInChain(sk *SubjectAndKey) bool { + for _, cert := range chain { + if bytes.Equal(sk.RawSubject, cert.RawSubject) && bytes.Equal(sk.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) { + return true + } + } + return false +} + +// CertificateSubjectAndKeyInChain returns true if the SubjectAndKey from c is +// found in any certificate in the chain. +func (chain CertificateChain) CertificateSubjectAndKeyInChain(c *Certificate) bool { + for _, cert := range chain { + if bytes.Equal(c.RawSubject, cert.RawSubject) && bytes.Equal(c.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) { + return true + } + } + return false +} + +// CertificateInChain returns true if c is in the chain. +func (chain CertificateChain) CertificateInChain(c *Certificate) bool { + for _, cert := range chain { + if bytes.Equal(c.Raw, cert.Raw) { + return true + } + } + return false +} + +func (chain CertificateChain) AppendToFreshChain(c *Certificate) CertificateChain { + n := make([]*Certificate, len(chain)+1) + copy(n, chain) + n[len(chain)] = c + return n +} + +func (chain CertificateChain) chainID() string { + var parts []string + for _, c := range chain { + parts = append(parts, string(c.FingerprintSHA256)) + } + return strings.Join(parts, "") +} diff --git a/vendor/github.com/zmap/zcrypto/x509/ct/serialization.go b/vendor/github.com/zmap/zcrypto/x509/ct/serialization.go new file mode 100644 index 0000000000..aac17dc2c7 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/ct/serialization.go @@ -0,0 +1,168 @@ +package ct + +// This file contains selectively chosen snippets of +// github.com/google/certificate-transparency-go@ 5cfe585726ad9d990d4db524d6ce2567b13e2f80 +// +// These snippets only perform deserialization for SCTs and are recreated here to prevent pulling in the whole of the ct +// which contains yet another version of x509,asn1 and tls + +import ( + "encoding/binary" + "errors" + "fmt" + "io" +) + +// Variable size structure prefix-header byte lengths +const ( + CertificateLengthBytes = 3 + PreCertificateLengthBytes = 3 + ExtensionsLengthBytes = 2 + CertificateChainLengthBytes = 3 + SignatureLengthBytes = 2 +) + +func writeUint(w io.Writer, value uint64, numBytes int) error { + buf := make([]uint8, numBytes) + for i := 0; i < numBytes; i++ { + buf[numBytes-i-1] = uint8(value & 0xff) + value >>= 8 + } + if value != 0 { + return errors.New("numBytes was insufficiently large to represent value") + } + if _, err := w.Write(buf); err != nil { + return err + } + return nil +} + +func writeVarBytes(w io.Writer, value []byte, numLenBytes int) error { + if err := writeUint(w, uint64(len(value)), numLenBytes); err != nil { + return err + } + if _, err := w.Write(value); err != nil { + return err + } + return nil +} + +func readUint(r io.Reader, numBytes int) (uint64, error) { + var l uint64 + for i := 0; i < numBytes; i++ { + l <<= 8 + var t uint8 + if err := binary.Read(r, binary.BigEndian, &t); err != nil { + return 0, err + } + l |= uint64(t) + } + return l, nil +} + +// Reads a variable length array of bytes from |r|. |numLenBytes| specifies the +// number of (BigEndian) prefix-bytes which contain the length of the actual +// array data bytes that follow. +// Allocates an array to hold the contents and returns a slice view into it if +// the read was successful, or an error otherwise. +func readVarBytes(r io.Reader, numLenBytes int) ([]byte, error) { + switch { + case numLenBytes > 8: + return nil, fmt.Errorf("numLenBytes too large (%d)", numLenBytes) + case numLenBytes == 0: + return nil, errors.New("numLenBytes should be > 0") + } + l, err := readUint(r, numLenBytes) + if err != nil { + return nil, err + } + data := make([]byte, l) + if n, err := io.ReadFull(r, data); err != nil { + if err == io.EOF || err == io.ErrUnexpectedEOF { + return nil, fmt.Errorf("short read: expected %d but got %d", l, n) + } + return nil, err + } + return data, nil +} + +// UnmarshalDigitallySigned reconstructs a DigitallySigned structure from a Reader +func UnmarshalDigitallySigned(r io.Reader) (*DigitallySigned, error) { + var h byte + if err := binary.Read(r, binary.BigEndian, &h); err != nil { + return nil, fmt.Errorf("failed to read HashAlgorithm: %v", err) + } + + var s byte + if err := binary.Read(r, binary.BigEndian, &s); err != nil { + return nil, fmt.Errorf("failed to read SignatureAlgorithm: %v", err) + } + + sig, err := readVarBytes(r, SignatureLengthBytes) + if err != nil { + return nil, fmt.Errorf("failed to read Signature bytes: %v", err) + } + + return &DigitallySigned{ + HashAlgorithm: HashAlgorithm(h), + SignatureAlgorithm: SignatureAlgorithm(s), + Signature: sig, + }, nil +} + +func marshalDigitallySignedHere(ds DigitallySigned, here []byte) ([]byte, error) { + sigLen := len(ds.Signature) + dsOutLen := 2 + SignatureLengthBytes + sigLen + if here == nil { + here = make([]byte, dsOutLen) + } + if len(here) < dsOutLen { + return nil, ErrNotEnoughBuffer + } + here = here[0:dsOutLen] + + here[0] = byte(ds.HashAlgorithm) + here[1] = byte(ds.SignatureAlgorithm) + binary.BigEndian.PutUint16(here[2:4], uint16(sigLen)) + copy(here[4:], ds.Signature) + + return here, nil +} + +// MarshalDigitallySigned marshalls a DigitallySigned structure into a byte array +func MarshalDigitallySigned(ds DigitallySigned) ([]byte, error) { + return marshalDigitallySignedHere(ds, nil) +} + +func deserializeSCTV1(r io.Reader, sct *SignedCertificateTimestamp) error { + if err := binary.Read(r, binary.BigEndian, &sct.LogID); err != nil { + return err + } + if err := binary.Read(r, binary.BigEndian, &sct.Timestamp); err != nil { + return err + } + ext, err := readVarBytes(r, ExtensionsLengthBytes) + if err != nil { + return err + } + sct.Extensions = ext + ds, err := UnmarshalDigitallySigned(r) + if err != nil { + return err + } + sct.Signature = *ds + return nil +} + +func DeserializeSCT(r io.Reader) (*SignedCertificateTimestamp, error) { + var sct SignedCertificateTimestamp + if err := binary.Read(r, binary.BigEndian, &sct.SCTVersion); err != nil { + return nil, err + } + switch sct.SCTVersion { + case V1: + return &sct, deserializeSCTV1(r, &sct) + default: + return nil, fmt.Errorf("unknown SCT version %d", sct.SCTVersion) + } +} diff --git a/vendor/github.com/zmap/zcrypto/x509/ct/types.go b/vendor/github.com/zmap/zcrypto/x509/ct/types.go new file mode 100644 index 0000000000..8d894d3344 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/ct/types.go @@ -0,0 +1,229 @@ +package ct + +// This file contains selectively chosen snippets of +// github.com/google/certificate-transparency-go@ 5cfe585726ad9d990d4db524d6ce2567b13e2f80 +// +// These snippets only perform deserialization for SCTs and are recreated here to prevent pulling in the whole of the ct +// which contains yet another version of x509,asn1 and tls + +import ( + "bytes" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" +) + +// CTExtensions is a representation of the raw bytes of any CtExtension +// structure (see section 3.2) +type CTExtensions []byte + +// SHA256Hash represents the output from the SHA256 hash function. +type SHA256Hash [sha256.Size]byte + +// FromBase64String populates the SHA256 struct with the contents of the base64 data passed in. +func (s *SHA256Hash) FromBase64String(b64 string) error { + bs, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + return fmt.Errorf("failed to unbase64 LogID: %v", err) + } + if len(bs) != sha256.Size { + return fmt.Errorf("invalid SHA256 length, expected 32 but got %d", len(bs)) + } + copy(s[:], bs) + return nil +} + +// Base64String returns the base64 representation of this SHA256Hash. +func (s SHA256Hash) Base64String() string { + return base64.StdEncoding.EncodeToString(s[:]) +} + +// MarshalJSON implements the json.Marshaller interface for SHA256Hash. +func (s SHA256Hash) MarshalJSON() ([]byte, error) { + return []byte(`"` + s.Base64String() + `"`), nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface. +func (s *SHA256Hash) UnmarshalJSON(b []byte) error { + var content string + if err := json.Unmarshal(b, &content); err != nil { + return fmt.Errorf("failed to unmarshal SHA256Hash: %v", err) + } + return s.FromBase64String(content) +} + +// HashAlgorithm from the DigitallySigned struct +type HashAlgorithm byte + +// HashAlgorithm constants +const ( + None HashAlgorithm = 0 + MD5 HashAlgorithm = 1 + SHA1 HashAlgorithm = 2 + SHA224 HashAlgorithm = 3 + SHA256 HashAlgorithm = 4 + SHA384 HashAlgorithm = 5 + SHA512 HashAlgorithm = 6 +) + +func (h HashAlgorithm) String() string { + switch h { + case None: + return "None" + case MD5: + return "MD5" + case SHA1: + return "SHA1" + case SHA224: + return "SHA224" + case SHA256: + return "SHA256" + case SHA384: + return "SHA384" + case SHA512: + return "SHA512" + default: + return fmt.Sprintf("UNKNOWN(%d)", h) + } +} + +// SignatureAlgorithm from the the DigitallySigned struct +type SignatureAlgorithm byte + +// SignatureAlgorithm constants +const ( + Anonymous SignatureAlgorithm = 0 + RSA SignatureAlgorithm = 1 + DSA SignatureAlgorithm = 2 + ECDSA SignatureAlgorithm = 3 +) + +func (s SignatureAlgorithm) String() string { + switch s { + case Anonymous: + return "Anonymous" + case RSA: + return "RSA" + case DSA: + return "DSA" + case ECDSA: + return "ECDSA" + default: + return fmt.Sprintf("UNKNOWN(%d)", s) + } +} + +// DigitallySigned represents an RFC5246 DigitallySigned structure +type DigitallySigned struct { + HashAlgorithm HashAlgorithm + SignatureAlgorithm SignatureAlgorithm + Signature []byte +} + +// FromBase64String populates the DigitallySigned structure from the base64 data passed in. +// Returns an error if the base64 data is invalid. +func (d *DigitallySigned) FromBase64String(b64 string) error { + raw, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + return fmt.Errorf("failed to unbase64 DigitallySigned: %v", err) + } + ds, err := UnmarshalDigitallySigned(bytes.NewReader(raw)) + if err != nil { + return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err) + } + *d = *ds + return nil +} + +// Base64String returns the base64 representation of the DigitallySigned struct. +func (d DigitallySigned) Base64String() (string, error) { + b, err := MarshalDigitallySigned(d) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(b), nil +} + +// MarshalJSON implements the json.Marshaller interface. +func (d DigitallySigned) MarshalJSON() ([]byte, error) { + b64, err := d.Base64String() + if err != nil { + return []byte{}, err + } + return []byte(`"` + b64 + `"`), nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (d *DigitallySigned) UnmarshalJSON(b []byte) error { + var content string + if err := json.Unmarshal(b, &content); err != nil { + return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err) + } + return d.FromBase64String(content) +} + +// Version represents the Version enum from section 3.2 of the RFC: +// enum { v1(0), (255) } Version; +type Version uint8 + +func (v Version) String() string { + switch v { + case V1: + return "V1" + default: + return fmt.Sprintf("UnknownVersion(%d)", v) + } +} + +// CT Version constants, see section 3.2 of the RFC. +const ( + V1 Version = 0 +) + +// SignedCertificateTimestamp represents the structure returned by the +// add-chain and add-pre-chain methods after base64 decoding. (see RFC sections +// 3.2 ,4.1 and 4.2) +type SignedCertificateTimestamp struct { + SCTVersion Version `json:"version"` // The version of the protocol to which the SCT conforms + LogID SHA256Hash `json:"log_id"` // the SHA-256 hash of the log's public key, calculated over + // the DER encoding of the key represented as SubjectPublicKeyInfo. + Timestamp uint64 `json:"timestamp,omitempty"` // Timestamp (in ms since unix epoc) at which the SCT was issued. NOTE: When this is serialized, the output is in seconds, not milliseconds. + Extensions CTExtensions `json:"extensions,omitempty"` // For future extensions to the protocol + Signature DigitallySigned `json:"signature"` // The Log's signature for this SCT +} + +// Copied from ct/types.go 2018/06/15 to deal with BQ timestamp overflow; output +// is expected to be seconds, not milliseconds. +type auxSignedCertificateTimestamp SignedCertificateTimestamp + +const kMaxTimestamp = 253402300799 + +// MarshalJSON implements the JSON.Marshaller interface. +func (sct *SignedCertificateTimestamp) MarshalJSON() ([]byte, error) { + aux := auxSignedCertificateTimestamp(*sct) + aux.Timestamp = sct.Timestamp / 1000 // convert ms to sec + if aux.Timestamp > kMaxTimestamp { + aux.Timestamp = 0 + } + return json.Marshal(&aux) +} + +type sctError int + +// Preallocate errors for performance +var ( + ErrInvalidVersion error = sctError(1) + ErrNotEnoughBuffer error = sctError(2) +) + +func (e sctError) Error() string { + switch e { + case ErrInvalidVersion: + return "invalid SCT version detected" + case ErrNotEnoughBuffer: + return "provided buffer was too small" + default: + return "unknown error" + } +} diff --git a/vendor/github.com/zmap/zcrypto/x509/example.json b/vendor/github.com/zmap/zcrypto/x509/example.json new file mode 100644 index 0000000000..dd225da71d --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/example.json @@ -0,0 +1,65 @@ +{ + "domain": null, + "certificate": { + "version": 3, + "serial_number": 123893, + "signature_algorithm": { + "id": 123, + "name": "SHA1" + }, + "issuer": { + "common_name": "Starfield CA", + "attributes": [ + { "organization": "Startfield" }, + { "location": "Scottsdale" }, + { "state": "Arizona" }, + { "country": "US" } + ] + }, + "validity": { + "start": "20140102", + "end": "20150102", + "length" :8760 + }, + "subject": { + "common_name": "*.tools.ieft.org", + "attributes": [ + { "organization_unit": "Domain Control Validated" } + ] + }, + "subject_key_info": { + "algorithm": { + "id": 234, + "name": "RSA" + }, + "key": { + "modulus": "base64encodedmodulus", + "exponent": 65537 + } + }, + "extensions": [ + { + "id": 345, + "name": "Certificate Basic Constraints", + "is_ca": false + }, + { + "id": 456, + "name": "Alt Names", + "alt_names": [ + "*.tools.ietf.org", + "tools.ietf.org" + ] + } + ] + }, + "signature_algorithm": { + "id": 123, + "name": "SHA1" + }, + "signature": { + "value": "base64encodedsignature", + "is_valid": true, + "matches_domain": null + } +} diff --git a/vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go b/vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go new file mode 100644 index 0000000000..4b66fc522b --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go @@ -0,0 +1,679 @@ +// Created by extended_key_usage_gen; DO NOT EDIT + +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "encoding/asn1" +) + +const ( + OID_EKU_APPLE_CODE_SIGNING = "1.2.840.113635.100.4.1" + OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT = "1.2.840.113635.100.4.1.1" + OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING = "1.2.840.113635.100.4.1.2" + OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY = "1.2.840.113635.100.4.1.3" + OID_EKU_APPLE_RESOURCE_SIGNING = "1.2.840.113635.100.4.1.4" + OID_EKU_APPLE_ICHAT_SIGNING = "1.2.840.113635.100.4.2" + OID_EKU_APPLE_ICHAT_ENCRYPTION = "1.2.840.113635.100.4.3" + OID_EKU_APPLE_SYSTEM_IDENTITY = "1.2.840.113635.100.4.4" + OID_EKU_APPLE_CRYPTO_ENV = "1.2.840.113635.100.4.5" + OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV = "1.2.840.113635.100.4.5.1" + OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV = "1.2.840.113635.100.4.5.2" + OID_EKU_APPLE_CRYPTO_TEST_ENV = "1.2.840.113635.100.4.5.3" + OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV = "1.2.840.113635.100.4.5.4" + OID_EKU_APPLE_CRYPTO_QOS = "1.2.840.113635.100.4.6" + OID_EKU_APPLE_CRYPTO_TIER0_QOS = "1.2.840.113635.100.4.6.1" + OID_EKU_APPLE_CRYPTO_TIER1_QOS = "1.2.840.113635.100.4.6.2" + OID_EKU_APPLE_CRYPTO_TIER2_QOS = "1.2.840.113635.100.4.6.3" + OID_EKU_APPLE_CRYPTO_TIER3_QOS = "1.2.840.113635.100.4.6.4" + OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING = "1.3.6.1.4.1.311.10.3.1" + OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE = "1.3.6.1.4.1.311.10.3.10" + OID_EKU_MICROSOFT_KEY_RECOVERY_3 = "1.3.6.1.4.1.311.10.3.11" + OID_EKU_MICROSOFT_DOCUMENT_SIGNING = "1.3.6.1.4.1.311.10.3.12" + OID_EKU_MICROSOFT_LIFETIME_SIGNING = "1.3.6.1.4.1.311.10.3.13" + OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE = "1.3.6.1.4.1.311.10.3.14" + OID_EKU_MICROSOFT_SMART_DISPLAY = "1.3.6.1.4.1.311.10.3.15" + OID_EKU_MICROSOFT_CSP_SIGNATURE = "1.3.6.1.4.1.311.10.3.16" + OID_EKU_MICROSOFT_TIMESTAMP_SIGNING = "1.3.6.1.4.1.311.10.3.2" + OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO = "1.3.6.1.4.1.311.10.3.3" + OID_EKU_MICROSOFT_SGC_SERIALIZED = "1.3.6.1.4.1.311.10.3.3.1" + OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM = "1.3.6.1.4.1.311.10.3.4" + OID_EKU_MICROSOFT_EFS_RECOVERY = "1.3.6.1.4.1.311.10.3.4.1" + OID_EKU_MICROSOFT_WHQL_CRYPTO = "1.3.6.1.4.1.311.10.3.5" + OID_EKU_MICROSOFT_NT5_CRYPTO = "1.3.6.1.4.1.311.10.3.6" + OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO = "1.3.6.1.4.1.311.10.3.7" + OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO = "1.3.6.1.4.1.311.10.3.8" + OID_EKU_MICROSOFT_ROOT_LIST_SIGNER = "1.3.6.1.4.1.311.10.3.9" + OID_EKU_MICROSOFT_DRM = "1.3.6.1.4.1.311.10.5.1" + OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION = "1.3.6.1.4.1.311.10.5.2" + OID_EKU_MICROSOFT_LICENSES = "1.3.6.1.4.1.311.10.5.3" + OID_EKU_MICROSOFT_LICENSE_SERVER = "1.3.6.1.4.1.311.10.5.4" + OID_EKU_MICROSOFT_ENROLLMENT_AGENT = "1.3.6.1.4.1.311.20.2.1" + OID_EKU_MICROSOFT_SMARTCARD_LOGON = "1.3.6.1.4.1.311.20.2.2" + OID_EKU_MICROSOFT_CA_EXCHANGE = "1.3.6.1.4.1.311.21.5" + OID_EKU_MICROSOFT_KEY_RECOVERY_21 = "1.3.6.1.4.1.311.21.6" + OID_EKU_MICROSOFT_SYSTEM_HEALTH = "1.3.6.1.4.1.311.47.1.1" + OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE = "1.3.6.1.4.1.311.47.1.3" + OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING = "1.3.6.1.4.1.311.61.1.1" + OID_EKU_SERVER_AUTH = "1.3.6.1.5.5.7.3.1" + OID_EKU_DVCS = "1.3.6.1.5.5.7.3.10" + OID_EKU_SBGP_CERT_AA_SERVICE_AUTH = "1.3.6.1.5.5.7.3.11" + OID_EKU_EAP_OVER_PPP = "1.3.6.1.5.5.7.3.13" + OID_EKU_EAP_OVER_LAN = "1.3.6.1.5.5.7.3.14" + OID_EKU_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2" + OID_EKU_CODE_SIGNING = "1.3.6.1.5.5.7.3.3" + OID_EKU_EMAIL_PROTECTION = "1.3.6.1.5.5.7.3.4" + OID_EKU_IPSEC_END_SYSTEM = "1.3.6.1.5.5.7.3.5" + OID_EKU_IPSEC_TUNNEL = "1.3.6.1.5.5.7.3.6" + OID_EKU_IPSEC_USER = "1.3.6.1.5.5.7.3.7" + OID_EKU_TIME_STAMPING = "1.3.6.1.5.5.7.3.8" + OID_EKU_OCSP_SIGNING = "1.3.6.1.5.5.7.3.9" + OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE = "1.3.6.1.5.5.8.2.2" + OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO = "2.16.840.1.113730.4.1" + OID_EKU_ANY = "2.5.29.37.0" +) + +var ( + oidExtKeyUsageAppleCodeSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1} + oidExtKeyUsageAppleCodeSigningDevelopment = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 1} + oidExtKeyUsageAppleSoftwareUpdateSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 2} + oidExtKeyUsageAppleCodeSigningThirdParty = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 3} + oidExtKeyUsageAppleResourceSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 4} + oidExtKeyUsageAppleIchatSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 2} + oidExtKeyUsageAppleIchatEncryption = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 3} + oidExtKeyUsageAppleSystemIdentity = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 4} + oidExtKeyUsageAppleCryptoEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5} + oidExtKeyUsageAppleCryptoProductionEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 1} + oidExtKeyUsageAppleCryptoMaintenanceEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 2} + oidExtKeyUsageAppleCryptoTestEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 3} + oidExtKeyUsageAppleCryptoDevelopmentEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 4} + oidExtKeyUsageAppleCryptoQos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6} + oidExtKeyUsageAppleCryptoTier0Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 1} + oidExtKeyUsageAppleCryptoTier1Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 2} + oidExtKeyUsageAppleCryptoTier2Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 3} + oidExtKeyUsageAppleCryptoTier3Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 4} + oidExtKeyUsageMicrosoftCertTrustListSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 1} + oidExtKeyUsageMicrosoftQualifiedSubordinate = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 10} + oidExtKeyUsageMicrosoftKeyRecovery3 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 11} + oidExtKeyUsageMicrosoftDocumentSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 12} + oidExtKeyUsageMicrosoftLifetimeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 13} + oidExtKeyUsageMicrosoftMobileDeviceSoftware = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 14} + oidExtKeyUsageMicrosoftSmartDisplay = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 15} + oidExtKeyUsageMicrosoftCspSignature = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 16} + oidExtKeyUsageMicrosoftTimestampSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 2} + oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3} + oidExtKeyUsageMicrosoftSgcSerialized = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3, 1} + oidExtKeyUsageMicrosoftEncryptedFileSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 4} + oidExtKeyUsageMicrosoftEfsRecovery = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 4, 1} + oidExtKeyUsageMicrosoftWhqlCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 5} + oidExtKeyUsageMicrosoftNt5Crypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 6} + oidExtKeyUsageMicrosoftOemWhqlCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 7} + oidExtKeyUsageMicrosoftEmbeddedNtCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 8} + oidExtKeyUsageMicrosoftRootListSigner = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 9} + oidExtKeyUsageMicrosoftDrm = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 1} + oidExtKeyUsageMicrosoftDrmIndividualization = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 2} + oidExtKeyUsageMicrosoftLicenses = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 3} + oidExtKeyUsageMicrosoftLicenseServer = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 4} + oidExtKeyUsageMicrosoftEnrollmentAgent = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 1} + oidExtKeyUsageMicrosoftSmartcardLogon = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 2} + oidExtKeyUsageMicrosoftCaExchange = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 21, 5} + oidExtKeyUsageMicrosoftKeyRecovery21 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 21, 6} + oidExtKeyUsageMicrosoftSystemHealth = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 47, 1, 1} + oidExtKeyUsageMicrosoftSystemHealthLoophole = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 47, 1, 3} + oidExtKeyUsageMicrosoftKernelModeCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1} + oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} + oidExtKeyUsageDvcs = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 10} + oidExtKeyUsageSbgpCertAaServiceAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 11} + oidExtKeyUsageEapOverPpp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 13} + oidExtKeyUsageEapOverLan = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 14} + oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} + oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} + oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} + oidExtKeyUsageIpsecEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} + oidExtKeyUsageIpsecTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} + oidExtKeyUsageIpsecUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} + oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} + oidExtKeyUsageOcspSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} + oidExtKeyUsageIpsecIntermediateSystemUsage = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 8, 2, 2} + oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1} + oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} +) + +const ( + ExtKeyUsageAppleCodeSigning ExtKeyUsage = iota + ExtKeyUsageAppleCodeSigningDevelopment + ExtKeyUsageAppleSoftwareUpdateSigning + ExtKeyUsageAppleCodeSigningThirdParty + ExtKeyUsageAppleResourceSigning + ExtKeyUsageAppleIchatSigning + ExtKeyUsageAppleIchatEncryption + ExtKeyUsageAppleSystemIdentity + ExtKeyUsageAppleCryptoEnv + ExtKeyUsageAppleCryptoProductionEnv + ExtKeyUsageAppleCryptoMaintenanceEnv + ExtKeyUsageAppleCryptoTestEnv + ExtKeyUsageAppleCryptoDevelopmentEnv + ExtKeyUsageAppleCryptoQos + ExtKeyUsageAppleCryptoTier0Qos + ExtKeyUsageAppleCryptoTier1Qos + ExtKeyUsageAppleCryptoTier2Qos + ExtKeyUsageAppleCryptoTier3Qos + ExtKeyUsageMicrosoftCertTrustListSigning + ExtKeyUsageMicrosoftQualifiedSubordinate + ExtKeyUsageMicrosoftKeyRecovery3 + ExtKeyUsageMicrosoftDocumentSigning + ExtKeyUsageMicrosoftLifetimeSigning + ExtKeyUsageMicrosoftMobileDeviceSoftware + ExtKeyUsageMicrosoftSmartDisplay + ExtKeyUsageMicrosoftCspSignature + ExtKeyUsageMicrosoftTimestampSigning + ExtKeyUsageMicrosoftServerGatedCrypto + ExtKeyUsageMicrosoftSgcSerialized + ExtKeyUsageMicrosoftEncryptedFileSystem + ExtKeyUsageMicrosoftEfsRecovery + ExtKeyUsageMicrosoftWhqlCrypto + ExtKeyUsageMicrosoftNt5Crypto + ExtKeyUsageMicrosoftOemWhqlCrypto + ExtKeyUsageMicrosoftEmbeddedNtCrypto + ExtKeyUsageMicrosoftRootListSigner + ExtKeyUsageMicrosoftDrm + ExtKeyUsageMicrosoftDrmIndividualization + ExtKeyUsageMicrosoftLicenses + ExtKeyUsageMicrosoftLicenseServer + ExtKeyUsageMicrosoftEnrollmentAgent + ExtKeyUsageMicrosoftSmartcardLogon + ExtKeyUsageMicrosoftCaExchange + ExtKeyUsageMicrosoftKeyRecovery21 + ExtKeyUsageMicrosoftSystemHealth + ExtKeyUsageMicrosoftSystemHealthLoophole + ExtKeyUsageMicrosoftKernelModeCodeSigning + ExtKeyUsageServerAuth + ExtKeyUsageDvcs + ExtKeyUsageSbgpCertAaServiceAuth + ExtKeyUsageEapOverPpp + ExtKeyUsageEapOverLan + ExtKeyUsageClientAuth + ExtKeyUsageCodeSigning + ExtKeyUsageEmailProtection + ExtKeyUsageIpsecEndSystem + ExtKeyUsageIpsecTunnel + ExtKeyUsageIpsecUser + ExtKeyUsageTimeStamping + ExtKeyUsageOcspSigning + ExtKeyUsageIpsecIntermediateSystemUsage + ExtKeyUsageNetscapeServerGatedCrypto + ExtKeyUsageAny +) + +type auxExtendedKeyUsage struct { + AppleCodeSigning bool `json:"apple_code_signing,omitempty" oid:"1.2.840.113635.100.4.1"` + AppleCodeSigningDevelopment bool `json:"apple_code_signing_development,omitempty" oid:"1.2.840.113635.100.4.1.1"` + AppleSoftwareUpdateSigning bool `json:"apple_software_update_signing,omitempty" oid:"1.2.840.113635.100.4.1.2"` + AppleCodeSigningThirdParty bool `json:"apple_code_signing_third_party,omitempty" oid:"1.2.840.113635.100.4.1.3"` + AppleResourceSigning bool `json:"apple_resource_signing,omitempty" oid:"1.2.840.113635.100.4.1.4"` + AppleIchatSigning bool `json:"apple_ichat_signing,omitempty" oid:"1.2.840.113635.100.4.2"` + AppleIchatEncryption bool `json:"apple_ichat_encryption,omitempty" oid:"1.2.840.113635.100.4.3"` + AppleSystemIdentity bool `json:"apple_system_identity,omitempty" oid:"1.2.840.113635.100.4.4"` + AppleCryptoEnv bool `json:"apple_crypto_env,omitempty" oid:"1.2.840.113635.100.4.5"` + AppleCryptoProductionEnv bool `json:"apple_crypto_production_env,omitempty" oid:"1.2.840.113635.100.4.5.1"` + AppleCryptoMaintenanceEnv bool `json:"apple_crypto_maintenance_env,omitempty" oid:"1.2.840.113635.100.4.5.2"` + AppleCryptoTestEnv bool `json:"apple_crypto_test_env,omitempty" oid:"1.2.840.113635.100.4.5.3"` + AppleCryptoDevelopmentEnv bool `json:"apple_crypto_development_env,omitempty" oid:"1.2.840.113635.100.4.5.4"` + AppleCryptoQos bool `json:"apple_crypto_qos,omitempty" oid:"1.2.840.113635.100.4.6"` + AppleCryptoTier0Qos bool `json:"apple_crypto_tier0_qos,omitempty" oid:"1.2.840.113635.100.4.6.1"` + AppleCryptoTier1Qos bool `json:"apple_crypto_tier1_qos,omitempty" oid:"1.2.840.113635.100.4.6.2"` + AppleCryptoTier2Qos bool `json:"apple_crypto_tier2_qos,omitempty" oid:"1.2.840.113635.100.4.6.3"` + AppleCryptoTier3Qos bool `json:"apple_crypto_tier3_qos,omitempty" oid:"1.2.840.113635.100.4.6.4"` + MicrosoftCertTrustListSigning bool `json:"microsoft_cert_trust_list_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.1"` + MicrosoftQualifiedSubordinate bool `json:"microsoft_qualified_subordinate,omitempty" oid:"1.3.6.1.4.1.311.10.3.10"` + MicrosoftKeyRecovery3 bool `json:"microsoft_key_recovery_3,omitempty" oid:"1.3.6.1.4.1.311.10.3.11"` + MicrosoftDocumentSigning bool `json:"microsoft_document_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.12"` + MicrosoftLifetimeSigning bool `json:"microsoft_lifetime_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.13"` + MicrosoftMobileDeviceSoftware bool `json:"microsoft_mobile_device_software,omitempty" oid:"1.3.6.1.4.1.311.10.3.14"` + MicrosoftSmartDisplay bool `json:"microsoft_smart_display,omitempty" oid:"1.3.6.1.4.1.311.10.3.15"` + MicrosoftCspSignature bool `json:"microsoft_csp_signature,omitempty" oid:"1.3.6.1.4.1.311.10.3.16"` + MicrosoftTimestampSigning bool `json:"microsoft_timestamp_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.2"` + MicrosoftServerGatedCrypto bool `json:"microsoft_server_gated_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.3"` + MicrosoftSgcSerialized bool `json:"microsoft_sgc_serialized,omitempty" oid:"1.3.6.1.4.1.311.10.3.3.1"` + MicrosoftEncryptedFileSystem bool `json:"microsoft_encrypted_file_system,omitempty" oid:"1.3.6.1.4.1.311.10.3.4"` + MicrosoftEfsRecovery bool `json:"microsoft_efs_recovery,omitempty" oid:"1.3.6.1.4.1.311.10.3.4.1"` + MicrosoftWhqlCrypto bool `json:"microsoft_whql_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.5"` + MicrosoftNt5Crypto bool `json:"microsoft_nt5_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.6"` + MicrosoftOemWhqlCrypto bool `json:"microsoft_oem_whql_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.7"` + MicrosoftEmbeddedNtCrypto bool `json:"microsoft_embedded_nt_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.8"` + MicrosoftRootListSigner bool `json:"microsoft_root_list_signer,omitempty" oid:"1.3.6.1.4.1.311.10.3.9"` + MicrosoftDrm bool `json:"microsoft_drm,omitempty" oid:"1.3.6.1.4.1.311.10.5.1"` + MicrosoftDrmIndividualization bool `json:"microsoft_drm_individualization,omitempty" oid:"1.3.6.1.4.1.311.10.5.2"` + MicrosoftLicenses bool `json:"microsoft_licenses,omitempty" oid:"1.3.6.1.4.1.311.10.5.3"` + MicrosoftLicenseServer bool `json:"microsoft_license_server,omitempty" oid:"1.3.6.1.4.1.311.10.5.4"` + MicrosoftEnrollmentAgent bool `json:"microsoft_enrollment_agent,omitempty" oid:"1.3.6.1.4.1.311.20.2.1"` + MicrosoftSmartcardLogon bool `json:"microsoft_smartcard_logon,omitempty" oid:"1.3.6.1.4.1.311.20.2.2"` + MicrosoftCaExchange bool `json:"microsoft_ca_exchange,omitempty" oid:"1.3.6.1.4.1.311.21.5"` + MicrosoftKeyRecovery21 bool `json:"microsoft_key_recovery_21,omitempty" oid:"1.3.6.1.4.1.311.21.6"` + MicrosoftSystemHealth bool `json:"microsoft_system_health,omitempty" oid:"1.3.6.1.4.1.311.47.1.1"` + MicrosoftSystemHealthLoophole bool `json:"microsoft_system_health_loophole,omitempty" oid:"1.3.6.1.4.1.311.47.1.3"` + MicrosoftKernelModeCodeSigning bool `json:"microsoft_kernel_mode_code_signing,omitempty" oid:"1.3.6.1.4.1.311.61.1.1"` + ServerAuth bool `json:"server_auth,omitempty" oid:"1.3.6.1.5.5.7.3.1"` + Dvcs bool `json:"dvcs,omitempty" oid:"1.3.6.1.5.5.7.3.10"` + SbgpCertAaServiceAuth bool `json:"sbgp_cert_aa_service_auth,omitempty" oid:"1.3.6.1.5.5.7.3.11"` + EapOverPpp bool `json:"eap_over_ppp,omitempty" oid:"1.3.6.1.5.5.7.3.13"` + EapOverLan bool `json:"eap_over_lan,omitempty" oid:"1.3.6.1.5.5.7.3.14"` + ClientAuth bool `json:"client_auth,omitempty" oid:"1.3.6.1.5.5.7.3.2"` + CodeSigning bool `json:"code_signing,omitempty" oid:"1.3.6.1.5.5.7.3.3"` + EmailProtection bool `json:"email_protection,omitempty" oid:"1.3.6.1.5.5.7.3.4"` + IpsecEndSystem bool `json:"ipsec_end_system,omitempty" oid:"1.3.6.1.5.5.7.3.5"` + IpsecTunnel bool `json:"ipsec_tunnel,omitempty" oid:"1.3.6.1.5.5.7.3.6"` + IpsecUser bool `json:"ipsec_user,omitempty" oid:"1.3.6.1.5.5.7.3.7"` + TimeStamping bool `json:"time_stamping,omitempty" oid:"1.3.6.1.5.5.7.3.8"` + OcspSigning bool `json:"ocsp_signing,omitempty" oid:"1.3.6.1.5.5.7.3.9"` + IpsecIntermediateSystemUsage bool `json:"ipsec_intermediate_system_usage,omitempty" oid:"1.3.6.1.5.5.8.2.2"` + NetscapeServerGatedCrypto bool `json:"netscape_server_gated_crypto,omitempty" oid:"2.16.840.1.113730.4.1"` + Any bool `json:"any,omitempty" oid:"2.5.29.37.0"` + Unknown []string `json:"unknown,omitempty"` +} + +func (aux *auxExtendedKeyUsage) populateFromASN1(oid asn1.ObjectIdentifier) { + s := oid.String() + switch s { + case OID_EKU_APPLE_CODE_SIGNING: + aux.AppleCodeSigning = true + case OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT: + aux.AppleCodeSigningDevelopment = true + case OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING: + aux.AppleSoftwareUpdateSigning = true + case OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY: + aux.AppleCodeSigningThirdParty = true + case OID_EKU_APPLE_RESOURCE_SIGNING: + aux.AppleResourceSigning = true + case OID_EKU_APPLE_ICHAT_SIGNING: + aux.AppleIchatSigning = true + case OID_EKU_APPLE_ICHAT_ENCRYPTION: + aux.AppleIchatEncryption = true + case OID_EKU_APPLE_SYSTEM_IDENTITY: + aux.AppleSystemIdentity = true + case OID_EKU_APPLE_CRYPTO_ENV: + aux.AppleCryptoEnv = true + case OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV: + aux.AppleCryptoProductionEnv = true + case OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV: + aux.AppleCryptoMaintenanceEnv = true + case OID_EKU_APPLE_CRYPTO_TEST_ENV: + aux.AppleCryptoTestEnv = true + case OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV: + aux.AppleCryptoDevelopmentEnv = true + case OID_EKU_APPLE_CRYPTO_QOS: + aux.AppleCryptoQos = true + case OID_EKU_APPLE_CRYPTO_TIER0_QOS: + aux.AppleCryptoTier0Qos = true + case OID_EKU_APPLE_CRYPTO_TIER1_QOS: + aux.AppleCryptoTier1Qos = true + case OID_EKU_APPLE_CRYPTO_TIER2_QOS: + aux.AppleCryptoTier2Qos = true + case OID_EKU_APPLE_CRYPTO_TIER3_QOS: + aux.AppleCryptoTier3Qos = true + case OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING: + aux.MicrosoftCertTrustListSigning = true + case OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE: + aux.MicrosoftQualifiedSubordinate = true + case OID_EKU_MICROSOFT_KEY_RECOVERY_3: + aux.MicrosoftKeyRecovery3 = true + case OID_EKU_MICROSOFT_DOCUMENT_SIGNING: + aux.MicrosoftDocumentSigning = true + case OID_EKU_MICROSOFT_LIFETIME_SIGNING: + aux.MicrosoftLifetimeSigning = true + case OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE: + aux.MicrosoftMobileDeviceSoftware = true + case OID_EKU_MICROSOFT_SMART_DISPLAY: + aux.MicrosoftSmartDisplay = true + case OID_EKU_MICROSOFT_CSP_SIGNATURE: + aux.MicrosoftCspSignature = true + case OID_EKU_MICROSOFT_TIMESTAMP_SIGNING: + aux.MicrosoftTimestampSigning = true + case OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO: + aux.MicrosoftServerGatedCrypto = true + case OID_EKU_MICROSOFT_SGC_SERIALIZED: + aux.MicrosoftSgcSerialized = true + case OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM: + aux.MicrosoftEncryptedFileSystem = true + case OID_EKU_MICROSOFT_EFS_RECOVERY: + aux.MicrosoftEfsRecovery = true + case OID_EKU_MICROSOFT_WHQL_CRYPTO: + aux.MicrosoftWhqlCrypto = true + case OID_EKU_MICROSOFT_NT5_CRYPTO: + aux.MicrosoftNt5Crypto = true + case OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO: + aux.MicrosoftOemWhqlCrypto = true + case OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO: + aux.MicrosoftEmbeddedNtCrypto = true + case OID_EKU_MICROSOFT_ROOT_LIST_SIGNER: + aux.MicrosoftRootListSigner = true + case OID_EKU_MICROSOFT_DRM: + aux.MicrosoftDrm = true + case OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION: + aux.MicrosoftDrmIndividualization = true + case OID_EKU_MICROSOFT_LICENSES: + aux.MicrosoftLicenses = true + case OID_EKU_MICROSOFT_LICENSE_SERVER: + aux.MicrosoftLicenseServer = true + case OID_EKU_MICROSOFT_ENROLLMENT_AGENT: + aux.MicrosoftEnrollmentAgent = true + case OID_EKU_MICROSOFT_SMARTCARD_LOGON: + aux.MicrosoftSmartcardLogon = true + case OID_EKU_MICROSOFT_CA_EXCHANGE: + aux.MicrosoftCaExchange = true + case OID_EKU_MICROSOFT_KEY_RECOVERY_21: + aux.MicrosoftKeyRecovery21 = true + case OID_EKU_MICROSOFT_SYSTEM_HEALTH: + aux.MicrosoftSystemHealth = true + case OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE: + aux.MicrosoftSystemHealthLoophole = true + case OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING: + aux.MicrosoftKernelModeCodeSigning = true + case OID_EKU_SERVER_AUTH: + aux.ServerAuth = true + case OID_EKU_DVCS: + aux.Dvcs = true + case OID_EKU_SBGP_CERT_AA_SERVICE_AUTH: + aux.SbgpCertAaServiceAuth = true + case OID_EKU_EAP_OVER_PPP: + aux.EapOverPpp = true + case OID_EKU_EAP_OVER_LAN: + aux.EapOverLan = true + case OID_EKU_CLIENT_AUTH: + aux.ClientAuth = true + case OID_EKU_CODE_SIGNING: + aux.CodeSigning = true + case OID_EKU_EMAIL_PROTECTION: + aux.EmailProtection = true + case OID_EKU_IPSEC_END_SYSTEM: + aux.IpsecEndSystem = true + case OID_EKU_IPSEC_TUNNEL: + aux.IpsecTunnel = true + case OID_EKU_IPSEC_USER: + aux.IpsecUser = true + case OID_EKU_TIME_STAMPING: + aux.TimeStamping = true + case OID_EKU_OCSP_SIGNING: + aux.OcspSigning = true + case OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE: + aux.IpsecIntermediateSystemUsage = true + case OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO: + aux.NetscapeServerGatedCrypto = true + case OID_EKU_ANY: + aux.Any = true + default: + } + return +} + +func (aux *auxExtendedKeyUsage) populateFromExtKeyUsage(eku ExtKeyUsage) { + switch eku { + case ExtKeyUsageAppleCodeSigning: + aux.AppleCodeSigning = true + case ExtKeyUsageAppleCodeSigningDevelopment: + aux.AppleCodeSigningDevelopment = true + case ExtKeyUsageAppleSoftwareUpdateSigning: + aux.AppleSoftwareUpdateSigning = true + case ExtKeyUsageAppleCodeSigningThirdParty: + aux.AppleCodeSigningThirdParty = true + case ExtKeyUsageAppleResourceSigning: + aux.AppleResourceSigning = true + case ExtKeyUsageAppleIchatSigning: + aux.AppleIchatSigning = true + case ExtKeyUsageAppleIchatEncryption: + aux.AppleIchatEncryption = true + case ExtKeyUsageAppleSystemIdentity: + aux.AppleSystemIdentity = true + case ExtKeyUsageAppleCryptoEnv: + aux.AppleCryptoEnv = true + case ExtKeyUsageAppleCryptoProductionEnv: + aux.AppleCryptoProductionEnv = true + case ExtKeyUsageAppleCryptoMaintenanceEnv: + aux.AppleCryptoMaintenanceEnv = true + case ExtKeyUsageAppleCryptoTestEnv: + aux.AppleCryptoTestEnv = true + case ExtKeyUsageAppleCryptoDevelopmentEnv: + aux.AppleCryptoDevelopmentEnv = true + case ExtKeyUsageAppleCryptoQos: + aux.AppleCryptoQos = true + case ExtKeyUsageAppleCryptoTier0Qos: + aux.AppleCryptoTier0Qos = true + case ExtKeyUsageAppleCryptoTier1Qos: + aux.AppleCryptoTier1Qos = true + case ExtKeyUsageAppleCryptoTier2Qos: + aux.AppleCryptoTier2Qos = true + case ExtKeyUsageAppleCryptoTier3Qos: + aux.AppleCryptoTier3Qos = true + case ExtKeyUsageMicrosoftCertTrustListSigning: + aux.MicrosoftCertTrustListSigning = true + case ExtKeyUsageMicrosoftQualifiedSubordinate: + aux.MicrosoftQualifiedSubordinate = true + case ExtKeyUsageMicrosoftKeyRecovery3: + aux.MicrosoftKeyRecovery3 = true + case ExtKeyUsageMicrosoftDocumentSigning: + aux.MicrosoftDocumentSigning = true + case ExtKeyUsageMicrosoftLifetimeSigning: + aux.MicrosoftLifetimeSigning = true + case ExtKeyUsageMicrosoftMobileDeviceSoftware: + aux.MicrosoftMobileDeviceSoftware = true + case ExtKeyUsageMicrosoftSmartDisplay: + aux.MicrosoftSmartDisplay = true + case ExtKeyUsageMicrosoftCspSignature: + aux.MicrosoftCspSignature = true + case ExtKeyUsageMicrosoftTimestampSigning: + aux.MicrosoftTimestampSigning = true + case ExtKeyUsageMicrosoftServerGatedCrypto: + aux.MicrosoftServerGatedCrypto = true + case ExtKeyUsageMicrosoftSgcSerialized: + aux.MicrosoftSgcSerialized = true + case ExtKeyUsageMicrosoftEncryptedFileSystem: + aux.MicrosoftEncryptedFileSystem = true + case ExtKeyUsageMicrosoftEfsRecovery: + aux.MicrosoftEfsRecovery = true + case ExtKeyUsageMicrosoftWhqlCrypto: + aux.MicrosoftWhqlCrypto = true + case ExtKeyUsageMicrosoftNt5Crypto: + aux.MicrosoftNt5Crypto = true + case ExtKeyUsageMicrosoftOemWhqlCrypto: + aux.MicrosoftOemWhqlCrypto = true + case ExtKeyUsageMicrosoftEmbeddedNtCrypto: + aux.MicrosoftEmbeddedNtCrypto = true + case ExtKeyUsageMicrosoftRootListSigner: + aux.MicrosoftRootListSigner = true + case ExtKeyUsageMicrosoftDrm: + aux.MicrosoftDrm = true + case ExtKeyUsageMicrosoftDrmIndividualization: + aux.MicrosoftDrmIndividualization = true + case ExtKeyUsageMicrosoftLicenses: + aux.MicrosoftLicenses = true + case ExtKeyUsageMicrosoftLicenseServer: + aux.MicrosoftLicenseServer = true + case ExtKeyUsageMicrosoftEnrollmentAgent: + aux.MicrosoftEnrollmentAgent = true + case ExtKeyUsageMicrosoftSmartcardLogon: + aux.MicrosoftSmartcardLogon = true + case ExtKeyUsageMicrosoftCaExchange: + aux.MicrosoftCaExchange = true + case ExtKeyUsageMicrosoftKeyRecovery21: + aux.MicrosoftKeyRecovery21 = true + case ExtKeyUsageMicrosoftSystemHealth: + aux.MicrosoftSystemHealth = true + case ExtKeyUsageMicrosoftSystemHealthLoophole: + aux.MicrosoftSystemHealthLoophole = true + case ExtKeyUsageMicrosoftKernelModeCodeSigning: + aux.MicrosoftKernelModeCodeSigning = true + case ExtKeyUsageServerAuth: + aux.ServerAuth = true + case ExtKeyUsageDvcs: + aux.Dvcs = true + case ExtKeyUsageSbgpCertAaServiceAuth: + aux.SbgpCertAaServiceAuth = true + case ExtKeyUsageEapOverPpp: + aux.EapOverPpp = true + case ExtKeyUsageEapOverLan: + aux.EapOverLan = true + case ExtKeyUsageClientAuth: + aux.ClientAuth = true + case ExtKeyUsageCodeSigning: + aux.CodeSigning = true + case ExtKeyUsageEmailProtection: + aux.EmailProtection = true + case ExtKeyUsageIpsecEndSystem: + aux.IpsecEndSystem = true + case ExtKeyUsageIpsecTunnel: + aux.IpsecTunnel = true + case ExtKeyUsageIpsecUser: + aux.IpsecUser = true + case ExtKeyUsageTimeStamping: + aux.TimeStamping = true + case ExtKeyUsageOcspSigning: + aux.OcspSigning = true + case ExtKeyUsageIpsecIntermediateSystemUsage: + aux.IpsecIntermediateSystemUsage = true + case ExtKeyUsageNetscapeServerGatedCrypto: + aux.NetscapeServerGatedCrypto = true + case ExtKeyUsageAny: + aux.Any = true + default: + } + return +} + +var ekuOIDs map[string]asn1.ObjectIdentifier + +var ekuConstants map[string]ExtKeyUsage + +func init() { + ekuOIDs = make(map[string]asn1.ObjectIdentifier) + ekuOIDs[OID_EKU_APPLE_CODE_SIGNING] = oidExtKeyUsageAppleCodeSigning + ekuOIDs[OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT] = oidExtKeyUsageAppleCodeSigningDevelopment + ekuOIDs[OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING] = oidExtKeyUsageAppleSoftwareUpdateSigning + ekuOIDs[OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY] = oidExtKeyUsageAppleCodeSigningThirdParty + ekuOIDs[OID_EKU_APPLE_RESOURCE_SIGNING] = oidExtKeyUsageAppleResourceSigning + ekuOIDs[OID_EKU_APPLE_ICHAT_SIGNING] = oidExtKeyUsageAppleIchatSigning + ekuOIDs[OID_EKU_APPLE_ICHAT_ENCRYPTION] = oidExtKeyUsageAppleIchatEncryption + ekuOIDs[OID_EKU_APPLE_SYSTEM_IDENTITY] = oidExtKeyUsageAppleSystemIdentity + ekuOIDs[OID_EKU_APPLE_CRYPTO_ENV] = oidExtKeyUsageAppleCryptoEnv + ekuOIDs[OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV] = oidExtKeyUsageAppleCryptoProductionEnv + ekuOIDs[OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV] = oidExtKeyUsageAppleCryptoMaintenanceEnv + ekuOIDs[OID_EKU_APPLE_CRYPTO_TEST_ENV] = oidExtKeyUsageAppleCryptoTestEnv + ekuOIDs[OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV] = oidExtKeyUsageAppleCryptoDevelopmentEnv + ekuOIDs[OID_EKU_APPLE_CRYPTO_QOS] = oidExtKeyUsageAppleCryptoQos + ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER0_QOS] = oidExtKeyUsageAppleCryptoTier0Qos + ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER1_QOS] = oidExtKeyUsageAppleCryptoTier1Qos + ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER2_QOS] = oidExtKeyUsageAppleCryptoTier2Qos + ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER3_QOS] = oidExtKeyUsageAppleCryptoTier3Qos + ekuOIDs[OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING] = oidExtKeyUsageMicrosoftCertTrustListSigning + ekuOIDs[OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE] = oidExtKeyUsageMicrosoftQualifiedSubordinate + ekuOIDs[OID_EKU_MICROSOFT_KEY_RECOVERY_3] = oidExtKeyUsageMicrosoftKeyRecovery3 + ekuOIDs[OID_EKU_MICROSOFT_DOCUMENT_SIGNING] = oidExtKeyUsageMicrosoftDocumentSigning + ekuOIDs[OID_EKU_MICROSOFT_LIFETIME_SIGNING] = oidExtKeyUsageMicrosoftLifetimeSigning + ekuOIDs[OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE] = oidExtKeyUsageMicrosoftMobileDeviceSoftware + ekuOIDs[OID_EKU_MICROSOFT_SMART_DISPLAY] = oidExtKeyUsageMicrosoftSmartDisplay + ekuOIDs[OID_EKU_MICROSOFT_CSP_SIGNATURE] = oidExtKeyUsageMicrosoftCspSignature + ekuOIDs[OID_EKU_MICROSOFT_TIMESTAMP_SIGNING] = oidExtKeyUsageMicrosoftTimestampSigning + ekuOIDs[OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO] = oidExtKeyUsageMicrosoftServerGatedCrypto + ekuOIDs[OID_EKU_MICROSOFT_SGC_SERIALIZED] = oidExtKeyUsageMicrosoftSgcSerialized + ekuOIDs[OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM] = oidExtKeyUsageMicrosoftEncryptedFileSystem + ekuOIDs[OID_EKU_MICROSOFT_EFS_RECOVERY] = oidExtKeyUsageMicrosoftEfsRecovery + ekuOIDs[OID_EKU_MICROSOFT_WHQL_CRYPTO] = oidExtKeyUsageMicrosoftWhqlCrypto + ekuOIDs[OID_EKU_MICROSOFT_NT5_CRYPTO] = oidExtKeyUsageMicrosoftNt5Crypto + ekuOIDs[OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO] = oidExtKeyUsageMicrosoftOemWhqlCrypto + ekuOIDs[OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO] = oidExtKeyUsageMicrosoftEmbeddedNtCrypto + ekuOIDs[OID_EKU_MICROSOFT_ROOT_LIST_SIGNER] = oidExtKeyUsageMicrosoftRootListSigner + ekuOIDs[OID_EKU_MICROSOFT_DRM] = oidExtKeyUsageMicrosoftDrm + ekuOIDs[OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION] = oidExtKeyUsageMicrosoftDrmIndividualization + ekuOIDs[OID_EKU_MICROSOFT_LICENSES] = oidExtKeyUsageMicrosoftLicenses + ekuOIDs[OID_EKU_MICROSOFT_LICENSE_SERVER] = oidExtKeyUsageMicrosoftLicenseServer + ekuOIDs[OID_EKU_MICROSOFT_ENROLLMENT_AGENT] = oidExtKeyUsageMicrosoftEnrollmentAgent + ekuOIDs[OID_EKU_MICROSOFT_SMARTCARD_LOGON] = oidExtKeyUsageMicrosoftSmartcardLogon + ekuOIDs[OID_EKU_MICROSOFT_CA_EXCHANGE] = oidExtKeyUsageMicrosoftCaExchange + ekuOIDs[OID_EKU_MICROSOFT_KEY_RECOVERY_21] = oidExtKeyUsageMicrosoftKeyRecovery21 + ekuOIDs[OID_EKU_MICROSOFT_SYSTEM_HEALTH] = oidExtKeyUsageMicrosoftSystemHealth + ekuOIDs[OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE] = oidExtKeyUsageMicrosoftSystemHealthLoophole + ekuOIDs[OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING] = oidExtKeyUsageMicrosoftKernelModeCodeSigning + ekuOIDs[OID_EKU_SERVER_AUTH] = oidExtKeyUsageServerAuth + ekuOIDs[OID_EKU_DVCS] = oidExtKeyUsageDvcs + ekuOIDs[OID_EKU_SBGP_CERT_AA_SERVICE_AUTH] = oidExtKeyUsageSbgpCertAaServiceAuth + ekuOIDs[OID_EKU_EAP_OVER_PPP] = oidExtKeyUsageEapOverPpp + ekuOIDs[OID_EKU_EAP_OVER_LAN] = oidExtKeyUsageEapOverLan + ekuOIDs[OID_EKU_CLIENT_AUTH] = oidExtKeyUsageClientAuth + ekuOIDs[OID_EKU_CODE_SIGNING] = oidExtKeyUsageCodeSigning + ekuOIDs[OID_EKU_EMAIL_PROTECTION] = oidExtKeyUsageEmailProtection + ekuOIDs[OID_EKU_IPSEC_END_SYSTEM] = oidExtKeyUsageIpsecEndSystem + ekuOIDs[OID_EKU_IPSEC_TUNNEL] = oidExtKeyUsageIpsecTunnel + ekuOIDs[OID_EKU_IPSEC_USER] = oidExtKeyUsageIpsecUser + ekuOIDs[OID_EKU_TIME_STAMPING] = oidExtKeyUsageTimeStamping + ekuOIDs[OID_EKU_OCSP_SIGNING] = oidExtKeyUsageOcspSigning + ekuOIDs[OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE] = oidExtKeyUsageIpsecIntermediateSystemUsage + ekuOIDs[OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO] = oidExtKeyUsageNetscapeServerGatedCrypto + ekuOIDs[OID_EKU_ANY] = oidExtKeyUsageAny + + ekuConstants = make(map[string]ExtKeyUsage) + ekuConstants[OID_EKU_APPLE_CODE_SIGNING] = ExtKeyUsageAppleCodeSigning + ekuConstants[OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT] = ExtKeyUsageAppleCodeSigningDevelopment + ekuConstants[OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING] = ExtKeyUsageAppleSoftwareUpdateSigning + ekuConstants[OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY] = ExtKeyUsageAppleCodeSigningThirdParty + ekuConstants[OID_EKU_APPLE_RESOURCE_SIGNING] = ExtKeyUsageAppleResourceSigning + ekuConstants[OID_EKU_APPLE_ICHAT_SIGNING] = ExtKeyUsageAppleIchatSigning + ekuConstants[OID_EKU_APPLE_ICHAT_ENCRYPTION] = ExtKeyUsageAppleIchatEncryption + ekuConstants[OID_EKU_APPLE_SYSTEM_IDENTITY] = ExtKeyUsageAppleSystemIdentity + ekuConstants[OID_EKU_APPLE_CRYPTO_ENV] = ExtKeyUsageAppleCryptoEnv + ekuConstants[OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV] = ExtKeyUsageAppleCryptoProductionEnv + ekuConstants[OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV] = ExtKeyUsageAppleCryptoMaintenanceEnv + ekuConstants[OID_EKU_APPLE_CRYPTO_TEST_ENV] = ExtKeyUsageAppleCryptoTestEnv + ekuConstants[OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV] = ExtKeyUsageAppleCryptoDevelopmentEnv + ekuConstants[OID_EKU_APPLE_CRYPTO_QOS] = ExtKeyUsageAppleCryptoQos + ekuConstants[OID_EKU_APPLE_CRYPTO_TIER0_QOS] = ExtKeyUsageAppleCryptoTier0Qos + ekuConstants[OID_EKU_APPLE_CRYPTO_TIER1_QOS] = ExtKeyUsageAppleCryptoTier1Qos + ekuConstants[OID_EKU_APPLE_CRYPTO_TIER2_QOS] = ExtKeyUsageAppleCryptoTier2Qos + ekuConstants[OID_EKU_APPLE_CRYPTO_TIER3_QOS] = ExtKeyUsageAppleCryptoTier3Qos + ekuConstants[OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING] = ExtKeyUsageMicrosoftCertTrustListSigning + ekuConstants[OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE] = ExtKeyUsageMicrosoftQualifiedSubordinate + ekuConstants[OID_EKU_MICROSOFT_KEY_RECOVERY_3] = ExtKeyUsageMicrosoftKeyRecovery3 + ekuConstants[OID_EKU_MICROSOFT_DOCUMENT_SIGNING] = ExtKeyUsageMicrosoftDocumentSigning + ekuConstants[OID_EKU_MICROSOFT_LIFETIME_SIGNING] = ExtKeyUsageMicrosoftLifetimeSigning + ekuConstants[OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE] = ExtKeyUsageMicrosoftMobileDeviceSoftware + ekuConstants[OID_EKU_MICROSOFT_SMART_DISPLAY] = ExtKeyUsageMicrosoftSmartDisplay + ekuConstants[OID_EKU_MICROSOFT_CSP_SIGNATURE] = ExtKeyUsageMicrosoftCspSignature + ekuConstants[OID_EKU_MICROSOFT_TIMESTAMP_SIGNING] = ExtKeyUsageMicrosoftTimestampSigning + ekuConstants[OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO] = ExtKeyUsageMicrosoftServerGatedCrypto + ekuConstants[OID_EKU_MICROSOFT_SGC_SERIALIZED] = ExtKeyUsageMicrosoftSgcSerialized + ekuConstants[OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM] = ExtKeyUsageMicrosoftEncryptedFileSystem + ekuConstants[OID_EKU_MICROSOFT_EFS_RECOVERY] = ExtKeyUsageMicrosoftEfsRecovery + ekuConstants[OID_EKU_MICROSOFT_WHQL_CRYPTO] = ExtKeyUsageMicrosoftWhqlCrypto + ekuConstants[OID_EKU_MICROSOFT_NT5_CRYPTO] = ExtKeyUsageMicrosoftNt5Crypto + ekuConstants[OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO] = ExtKeyUsageMicrosoftOemWhqlCrypto + ekuConstants[OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO] = ExtKeyUsageMicrosoftEmbeddedNtCrypto + ekuConstants[OID_EKU_MICROSOFT_ROOT_LIST_SIGNER] = ExtKeyUsageMicrosoftRootListSigner + ekuConstants[OID_EKU_MICROSOFT_DRM] = ExtKeyUsageMicrosoftDrm + ekuConstants[OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION] = ExtKeyUsageMicrosoftDrmIndividualization + ekuConstants[OID_EKU_MICROSOFT_LICENSES] = ExtKeyUsageMicrosoftLicenses + ekuConstants[OID_EKU_MICROSOFT_LICENSE_SERVER] = ExtKeyUsageMicrosoftLicenseServer + ekuConstants[OID_EKU_MICROSOFT_ENROLLMENT_AGENT] = ExtKeyUsageMicrosoftEnrollmentAgent + ekuConstants[OID_EKU_MICROSOFT_SMARTCARD_LOGON] = ExtKeyUsageMicrosoftSmartcardLogon + ekuConstants[OID_EKU_MICROSOFT_CA_EXCHANGE] = ExtKeyUsageMicrosoftCaExchange + ekuConstants[OID_EKU_MICROSOFT_KEY_RECOVERY_21] = ExtKeyUsageMicrosoftKeyRecovery21 + ekuConstants[OID_EKU_MICROSOFT_SYSTEM_HEALTH] = ExtKeyUsageMicrosoftSystemHealth + ekuConstants[OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE] = ExtKeyUsageMicrosoftSystemHealthLoophole + ekuConstants[OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING] = ExtKeyUsageMicrosoftKernelModeCodeSigning + ekuConstants[OID_EKU_SERVER_AUTH] = ExtKeyUsageServerAuth + ekuConstants[OID_EKU_DVCS] = ExtKeyUsageDvcs + ekuConstants[OID_EKU_SBGP_CERT_AA_SERVICE_AUTH] = ExtKeyUsageSbgpCertAaServiceAuth + ekuConstants[OID_EKU_EAP_OVER_PPP] = ExtKeyUsageEapOverPpp + ekuConstants[OID_EKU_EAP_OVER_LAN] = ExtKeyUsageEapOverLan + ekuConstants[OID_EKU_CLIENT_AUTH] = ExtKeyUsageClientAuth + ekuConstants[OID_EKU_CODE_SIGNING] = ExtKeyUsageCodeSigning + ekuConstants[OID_EKU_EMAIL_PROTECTION] = ExtKeyUsageEmailProtection + ekuConstants[OID_EKU_IPSEC_END_SYSTEM] = ExtKeyUsageIpsecEndSystem + ekuConstants[OID_EKU_IPSEC_TUNNEL] = ExtKeyUsageIpsecTunnel + ekuConstants[OID_EKU_IPSEC_USER] = ExtKeyUsageIpsecUser + ekuConstants[OID_EKU_TIME_STAMPING] = ExtKeyUsageTimeStamping + ekuConstants[OID_EKU_OCSP_SIGNING] = ExtKeyUsageOcspSigning + ekuConstants[OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE] = ExtKeyUsageIpsecIntermediateSystemUsage + ekuConstants[OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO] = ExtKeyUsageNetscapeServerGatedCrypto + ekuConstants[OID_EKU_ANY] = ExtKeyUsageAny +} diff --git a/vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh b/vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh new file mode 100644 index 0000000000..b8811911e0 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e + +# TODO: This should really be generated by Go code as a subrecord, but +# importing in Python is hard. This is quick and dirty. + +FIELDS=$(\ + cat extended_key_usage.go |\ + grep json |\ + cut -d ':' -f 2 |\ + sed 's|,omitempty||g' |\ + tr -d '`') +echo "extended_key_usage = SubRecord({" +for f in $FIELDS; do + if [ $f == "\"unknown\"" ]; then + echo " $f: ListOf(OID())" + else + echo " $f: Boolean()," + fi +done +echo "})" diff --git a/vendor/github.com/zmap/zcrypto/x509/extensions.go b/vendor/github.com/zmap/zcrypto/x509/extensions.go new file mode 100644 index 0000000000..fb1c6700b9 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/extensions.go @@ -0,0 +1,800 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "encoding/asn1" + "encoding/hex" + "encoding/json" + "net" + "strconv" + "strings" + + "github.com/zmap/zcrypto/x509/ct" + "github.com/zmap/zcrypto/x509/pkix" +) + +var ( + oidExtKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 15} + oidExtBasicConstraints = asn1.ObjectIdentifier{2, 5, 29, 19} + oidExtSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17} + oidExtIssuerAltName = asn1.ObjectIdentifier{2, 5, 29, 18} + oidExtNameConstraints = asn1.ObjectIdentifier{2, 5, 29, 30} + oidCRLDistributionPoints = asn1.ObjectIdentifier{2, 5, 29, 31} + oidExtAuthKeyId = asn1.ObjectIdentifier{2, 5, 29, 35} + oidExtSubjectKeyId = asn1.ObjectIdentifier{2, 5, 29, 14} + oidExtExtendedKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37} + oidExtCertificatePolicy = asn1.ObjectIdentifier{2, 5, 29, 32} + + oidExtAuthorityInfoAccess = oidExtensionAuthorityInfoAccess + oidExtensionCTPrecertificatePoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} + oidExtSignedCertificateTimestampList = oidExtensionSignedCertificateTimestampList + + oidExtCABFOrganizationID = asn1.ObjectIdentifier{2, 23, 140, 3, 1} + oidExtQCStatements = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3} +) + +type CertificateExtensions struct { + KeyUsage KeyUsage `json:"key_usage,omitempty"` + BasicConstraints *BasicConstraints `json:"basic_constraints,omitempty"` + SubjectAltName *GeneralNames `json:"subject_alt_name,omitempty"` + IssuerAltName *GeneralNames `json:"issuer_alt_name,omitempty"` + NameConstraints *NameConstraints `json:"name_constraints,omitempty"` + CRLDistributionPoints CRLDistributionPoints `json:"crl_distribution_points,omitempty"` + AuthKeyID SubjAuthKeyId `json:"authority_key_id,omitempty"` + SubjectKeyID SubjAuthKeyId `json:"subject_key_id,omitempty"` + ExtendedKeyUsage *ExtendedKeyUsageExtension `json:"extended_key_usage,omitempty"` + CertificatePolicies *CertificatePoliciesData `json:"certificate_policies,omitempty"` + AuthorityInfoAccess *AuthorityInfoAccess `json:"authority_info_access,omitempty"` + IsPrecert IsPrecert `json:"ct_poison,omitempty"` + SignedCertificateTimestampList []*ct.SignedCertificateTimestamp `json:"signed_certificate_timestamps,omitempty"` + TorServiceDescriptors []*TorServiceDescriptorHash `json:"tor_service_descriptors,omitempty"` + CABFOrganizationIdentifier *CABFOrganizationIdentifier `json:"cabf_organization_id,omitempty"` + QCStatements *QCStatements `json:"qc_statements,omitempty"` +} + +type UnknownCertificateExtensions []pkix.Extension + +type IsPrecert bool + +type BasicConstraints struct { + IsCA bool `json:"is_ca"` + MaxPathLen *int `json:"max_path_len,omitempty"` +} + +type NoticeReference struct { + Organization string `json:"organization,omitempty"` + NoticeNumbers NoticeNumber `json:"notice_numbers,omitempty"` +} + +type UserNoticeData struct { + ExplicitText string `json:"explicit_text,omitempty"` + NoticeReference []NoticeReference `json:"notice_reference,omitempty"` +} + +type CertificatePoliciesJSON struct { + PolicyIdentifier string `json:"id,omitempty"` + CPSUri []string `json:"cps,omitempty"` + UserNotice []UserNoticeData `json:"user_notice,omitempty"` +} + +type CertificatePolicies []CertificatePoliciesJSON + +type CertificatePoliciesData struct { + PolicyIdentifiers []asn1.ObjectIdentifier + QualifierId [][]asn1.ObjectIdentifier + CPSUri [][]string + ExplicitTexts [][]string + NoticeRefOrganization [][]string + NoticeRefNumbers [][]NoticeNumber +} + +func (cp *CertificatePoliciesData) MarshalJSON() ([]byte, error) { + policies := CertificatePolicies{} + for idx, oid := range cp.PolicyIdentifiers { + cpsJSON := CertificatePoliciesJSON{} + cpsJSON.PolicyIdentifier = oid.String() + for _, uri := range cp.CPSUri[idx] { + cpsJSON.CPSUri = append(cpsJSON.CPSUri, uri) + } + + for idx2, explicit_text := range cp.ExplicitTexts[idx] { + uNoticeData := UserNoticeData{} + uNoticeData.ExplicitText = explicit_text + noticeRef := NoticeReference{} + if len(cp.NoticeRefOrganization[idx]) > 0 { + organization := cp.NoticeRefOrganization[idx][idx2] + noticeRef.Organization = organization + noticeRef.NoticeNumbers = cp.NoticeRefNumbers[idx][idx2] + uNoticeData.NoticeReference = append(uNoticeData.NoticeReference, noticeRef) + } + cpsJSON.UserNotice = append(cpsJSON.UserNotice, uNoticeData) + } + + policies = append(policies, cpsJSON) + } + return json.Marshal(policies) +} + +// GeneralNames corresponds an X.509 GeneralName defined in +// Section 4.2.1.6 of RFC 5280. +// +// GeneralName ::= CHOICE { +// otherName [0] AnotherName, +// 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 } +type GeneralNames struct { + DirectoryNames []pkix.Name + DNSNames []string + EDIPartyNames []pkix.EDIPartyName + EmailAddresses []string + IPAddresses []net.IP + OtherNames []pkix.OtherName + RegisteredIDs []asn1.ObjectIdentifier + URIs []string +} + +type jsonGeneralNames struct { + DirectoryNames []pkix.Name `json:"directory_names,omitempty"` + DNSNames []string `json:"dns_names,omitempty"` + EDIPartyNames []pkix.EDIPartyName `json:"edi_party_names,omitempty"` + EmailAddresses []string `json:"email_addresses,omitempty"` + IPAddresses []net.IP `json:"ip_addresses,omitempty"` + OtherNames []pkix.OtherName `json:"other_names,omitempty"` + RegisteredIDs []string `json:"registered_ids,omitempty"` + URIs []string `json:"uniform_resource_identifiers,omitempty"` +} + +func (gn *GeneralNames) MarshalJSON() ([]byte, error) { + jsan := jsonGeneralNames{ + DirectoryNames: gn.DirectoryNames, + DNSNames: gn.DNSNames, + EDIPartyNames: gn.EDIPartyNames, + EmailAddresses: gn.EmailAddresses, + IPAddresses: gn.IPAddresses, + OtherNames: gn.OtherNames, + RegisteredIDs: make([]string, 0, len(gn.RegisteredIDs)), + URIs: gn.URIs, + } + for _, id := range gn.RegisteredIDs { + jsan.RegisteredIDs = append(jsan.RegisteredIDs, id.String()) + } + return json.Marshal(jsan) +} + +func (gn *GeneralNames) UnmarshalJSON(b []byte) error { + var jsan jsonGeneralNames + err := json.Unmarshal(b, &jsan) + if err != nil { + return err + } + + gn.DirectoryNames = jsan.DirectoryNames + gn.DNSNames = jsan.DNSNames + gn.EDIPartyNames = jsan.EDIPartyNames + gn.EmailAddresses = jsan.EmailAddresses + gn.IPAddresses = jsan.IPAddresses + gn.OtherNames = jsan.OtherNames + gn.RegisteredIDs = make([]asn1.ObjectIdentifier, len(jsan.RegisteredIDs)) + gn.URIs = jsan.URIs + + for i, rID := range jsan.RegisteredIDs { + arcs := strings.Split(rID, ".") + oid := make(asn1.ObjectIdentifier, len(arcs)) + + for j, s := range arcs { + tmp, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + oid[j] = int(tmp) + } + gn.RegisteredIDs[i] = oid + } + return nil +} + +// TODO: Handle excluded names + +type NameConstraints struct { + Critical bool `json:"critical"` + + PermittedDNSNames []GeneralSubtreeString + PermittedEmailAddresses []GeneralSubtreeString + PermittedIPAddresses []GeneralSubtreeIP + PermittedDirectoryNames []GeneralSubtreeName + PermittedEdiPartyNames []GeneralSubtreeEdi + PermittedRegisteredIDs []GeneralSubtreeOid + + ExcludedEmailAddresses []GeneralSubtreeString + ExcludedDNSNames []GeneralSubtreeString + ExcludedIPAddresses []GeneralSubtreeIP + ExcludedDirectoryNames []GeneralSubtreeName + ExcludedEdiPartyNames []GeneralSubtreeEdi + ExcludedRegisteredIDs []GeneralSubtreeOid +} + +type NameConstraintsJSON struct { + Critical bool `json:"critical"` + + PermittedDNSNames []string `json:"permitted_names,omitempty"` + PermittedEmailAddresses []string `json:"permitted_email_addresses,omitempty"` + PermittedIPAddresses []GeneralSubtreeIP `json:"permitted_ip_addresses,omitempty"` + PermittedDirectoryNames []pkix.Name `json:"permitted_directory_names,omitempty"` + PermittedEdiPartyNames []pkix.EDIPartyName `json:"permitted_edi_party_names,omitempty"` + PermittedRegisteredIDs []string `json:"permitted_registred_id,omitempty"` + + ExcludedDNSNames []string `json:"excluded_names,omitempty"` + ExcludedEmailAddresses []string `json:"excluded_email_addresses,omitempty"` + ExcludedIPAddresses []GeneralSubtreeIP `json:"excluded_ip_addresses,omitempty"` + ExcludedDirectoryNames []pkix.Name `json:"excluded_directory_names,omitempty"` + ExcludedEdiPartyNames []pkix.EDIPartyName `json:"excluded_edi_party_names,omitempty"` + ExcludedRegisteredIDs []string `json:"excluded_registred_id,omitempty"` +} + +func (nc *NameConstraints) UnmarshalJSON(b []byte) error { + var ncJson NameConstraintsJSON + err := json.Unmarshal(b, &ncJson) + if err != nil { + return err + } + for _, dns := range ncJson.PermittedDNSNames { + nc.PermittedDNSNames = append(nc.PermittedDNSNames, GeneralSubtreeString{Data: dns}) + } + for _, email := range ncJson.PermittedEmailAddresses { + nc.PermittedEmailAddresses = append(nc.PermittedEmailAddresses, GeneralSubtreeString{Data: email}) + } + for _, constraint := range ncJson.PermittedIPAddresses { + nc.PermittedIPAddresses = append(nc.PermittedIPAddresses, constraint) + } + for _, directory := range ncJson.PermittedDirectoryNames { + nc.PermittedDirectoryNames = append(nc.PermittedDirectoryNames, GeneralSubtreeName{Data: directory}) + } + for _, edi := range ncJson.PermittedEdiPartyNames { + nc.PermittedEdiPartyNames = append(nc.PermittedEdiPartyNames, GeneralSubtreeEdi{Data: edi}) + } + for _, id := range ncJson.PermittedRegisteredIDs { + arcs := strings.Split(id, ".") + oid := make(asn1.ObjectIdentifier, len(arcs)) + + for j, s := range arcs { + tmp, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + oid[j] = int(tmp) + } + nc.PermittedRegisteredIDs = append(nc.PermittedRegisteredIDs, GeneralSubtreeOid{Data: oid}) + } + + for _, dns := range ncJson.ExcludedDNSNames { + nc.ExcludedDNSNames = append(nc.ExcludedDNSNames, GeneralSubtreeString{Data: dns}) + } + for _, email := range ncJson.ExcludedEmailAddresses { + nc.ExcludedEmailAddresses = append(nc.ExcludedEmailAddresses, GeneralSubtreeString{Data: email}) + } + for _, constraint := range ncJson.ExcludedIPAddresses { + nc.ExcludedIPAddresses = append(nc.ExcludedIPAddresses, constraint) + } + for _, directory := range ncJson.ExcludedDirectoryNames { + nc.ExcludedDirectoryNames = append(nc.ExcludedDirectoryNames, GeneralSubtreeName{Data: directory}) + } + for _, edi := range ncJson.ExcludedEdiPartyNames { + nc.ExcludedEdiPartyNames = append(nc.ExcludedEdiPartyNames, GeneralSubtreeEdi{Data: edi}) + } + for _, id := range ncJson.ExcludedRegisteredIDs { + arcs := strings.Split(id, ".") + oid := make(asn1.ObjectIdentifier, len(arcs)) + + for j, s := range arcs { + tmp, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + oid[j] = int(tmp) + } + nc.ExcludedRegisteredIDs = append(nc.ExcludedRegisteredIDs, GeneralSubtreeOid{Data: oid}) + } + return nil +} + +func (nc NameConstraints) MarshalJSON() ([]byte, error) { + var out NameConstraintsJSON + for _, dns := range nc.PermittedDNSNames { + out.PermittedDNSNames = append(out.PermittedDNSNames, dns.Data) + } + for _, email := range nc.PermittedEmailAddresses { + out.PermittedEmailAddresses = append(out.PermittedEmailAddresses, email.Data) + } + out.PermittedIPAddresses = nc.PermittedIPAddresses + for _, directory := range nc.PermittedDirectoryNames { + out.PermittedDirectoryNames = append(out.PermittedDirectoryNames, directory.Data) + } + for _, edi := range nc.PermittedEdiPartyNames { + out.PermittedEdiPartyNames = append(out.PermittedEdiPartyNames, edi.Data) + } + for _, id := range nc.PermittedRegisteredIDs { + out.PermittedRegisteredIDs = append(out.PermittedRegisteredIDs, id.Data.String()) + } + + for _, dns := range nc.ExcludedDNSNames { + out.ExcludedDNSNames = append(out.ExcludedDNSNames, dns.Data) + } + for _, email := range nc.ExcludedEmailAddresses { + out.ExcludedEmailAddresses = append(out.ExcludedEmailAddresses, email.Data) + } + for _, ip := range nc.ExcludedIPAddresses { + out.ExcludedIPAddresses = append(out.ExcludedIPAddresses, ip) + } + for _, directory := range nc.ExcludedDirectoryNames { + out.ExcludedDirectoryNames = append(out.ExcludedDirectoryNames, directory.Data) + } + for _, edi := range nc.ExcludedEdiPartyNames { + out.ExcludedEdiPartyNames = append(out.ExcludedEdiPartyNames, edi.Data) + } + for _, id := range nc.ExcludedRegisteredIDs { + out.ExcludedRegisteredIDs = append(out.ExcludedRegisteredIDs, id.Data.String()) + } + return json.Marshal(out) +} + +type CRLDistributionPoints []string + +type SubjAuthKeyId []byte + +func (kid SubjAuthKeyId) MarshalJSON() ([]byte, error) { + enc := hex.EncodeToString(kid) + return json.Marshal(enc) +} + +type ExtendedKeyUsage []ExtKeyUsage + +type ExtendedKeyUsageExtension struct { + Known ExtendedKeyUsage + Unknown []asn1.ObjectIdentifier +} + +// MarshalJSON implements the json.Marshal interface. The output is a struct of +// bools, with an additional `Value` field containing the actual OIDs. +func (e *ExtendedKeyUsageExtension) MarshalJSON() ([]byte, error) { + aux := new(auxExtendedKeyUsage) + for _, e := range e.Known { + aux.populateFromExtKeyUsage(e) + } + for _, oid := range e.Unknown { + aux.Unknown = append(aux.Unknown, oid.String()) + } + return json.Marshal(aux) +} + +func (e *ExtendedKeyUsageExtension) UnmarshalJSON(b []byte) error { + aux := new(auxExtendedKeyUsage) + if err := json.Unmarshal(b, aux); err != nil { + return err + } + // TODO: Generate the reverse functions. + return nil +} + +//go:generate go run extended_key_usage_gen.go + +// The string functions for CertValidationLevel are auto-generated via +// `go generate ` or running `go generate` in the package directory +//go:generate stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go +type CertValidationLevel int + +const ( + UnknownValidationLevel CertValidationLevel = 0 + DV CertValidationLevel = 1 + OV CertValidationLevel = 2 + EV CertValidationLevel = 3 +) + +func (c *CertValidationLevel) MarshalJSON() ([]byte, error) { + if *c == UnknownValidationLevel || *c < 0 || *c > EV { + return json.Marshal("unknown") + } + return json.Marshal(c.String()) +} + +// TODO: All of validation-level maps should be auto-generated from +// https://github.com/zmap/constants. + +// ExtendedValidationOIDs contains the UNION of Chromium +// (https://chromium.googlesource.com/chromium/src/net/+/master/cert/ev_root_ca_metadata.cc) +// and Firefox +// (http://hg.mozilla.org/mozilla-central/file/tip/security/certverifier/ExtendedValidation.cpp) +// EV OID lists +var ExtendedValidationOIDs = map[string]interface{}{ + // CA/Browser Forum EV OID standard + // https://cabforum.org/object-registry/ + "2.23.140.1.1": nil, + // CA/Browser Forum EV Code Signing + "2.23.140.1.3": nil, + // CA/Browser Forum .onion EV Certs + "2.23.140.1.31": nil, + // AC Camerfirma S.A. Chambers of Commerce Root - 2008 + // https://www.camerfirma.com + // AC Camerfirma uses the last two arcs to track how the private key + // is managed - the effective verification policy is the same. + "1.3.6.1.4.1.17326.10.14.2.1.2": nil, + "1.3.6.1.4.1.17326.10.14.2.2.2": nil, + // AC Camerfirma S.A. Global Chambersign Root - 2008 + // https://server2.camerfirma.com:8082 + // AC Camerfirma uses the last two arcs to track how the private key + // is managed - the effective verification policy is the same. + "1.3.6.1.4.1.17326.10.8.12.1.2": nil, + "1.3.6.1.4.1.17326.10.8.12.2.2": nil, + // Actalis Authentication Root CA + // https://ssltest-a.actalis.it:8443 + "1.3.159.1.17.1": nil, + // AffirmTrust Commercial + // https://commercial.affirmtrust.com/ + "1.3.6.1.4.1.34697.2.1": nil, + // AffirmTrust Networking + // https://networking.affirmtrust.com:4431 + "1.3.6.1.4.1.34697.2.2": nil, + // AffirmTrust Premium + // https://premium.affirmtrust.com:4432/ + "1.3.6.1.4.1.34697.2.3": nil, + // AffirmTrust Premium ECC + // https://premiumecc.affirmtrust.com:4433/ + "1.3.6.1.4.1.34697.2.4": nil, + // Autoridad de Certificacion Firmaprofesional CIF A62634068 + // https://publifirma.firmaprofesional.com/ + "1.3.6.1.4.1.13177.10.1.3.10": nil, + // Buypass Class 3 CA 1 + // https://valid.evident.ca13.ssl.buypass.no/ + "2.16.578.1.26.1.3.3": nil, + // Certification Authority of WoSign + // CA 沃通根证书 + // https://root2evtest.wosign.com/ + "1.3.6.1.4.1.36305.2": nil, + // CertPlus Class 2 Primary CA (KEYNECTIS) + // https://www.keynectis.com/ + "1.3.6.1.4.1.22234.2.5.2.3.1": nil, + // Certum Trusted Network CA + // https://juice.certum.pl/ + "1.2.616.1.113527.2.5.1.1": nil, + // China Internet Network Information Center EV Certificates Root + // https://evdemo.cnnic.cn/ + "1.3.6.1.4.1.29836.1.10": nil, + // COMODO Certification Authority & USERTrust RSA Certification Authority & UTN-USERFirst-Hardware & AddTrust External CA Root + // https://secure.comodo.com/ + // https://usertrustrsacertificationauthority-ev.comodoca.com/ + // https://addtrustexternalcaroot-ev.comodoca.com + "1.3.6.1.4.1.6449.1.2.1.5.1": nil, + // Cybertrust Global Root & GTE CyberTrust Global Root & Baltimore CyberTrust Root + // https://evup.cybertrust.ne.jp/ctj-ev-upgrader/evseal.gif + // https://www.cybertrust.ne.jp/ + // https://secure.omniroot.com/repository/ + "1.3.6.1.4.1.6334.1.100.1": nil, + // DigiCert High Assurance EV Root CA + // https://www.digicert.com + "2.16.840.1.114412.2.1": nil, + // D-TRUST Root Class 3 CA 2 EV 2009 + // https://certdemo-ev-valid.ssl.d-trust.net/ + "1.3.6.1.4.1.4788.2.202.1": nil, + // Entrust.net Secure Server Certification Authority + // https://www.entrust.net/ + "2.16.840.1.114028.10.1.2": nil, + // E-Tugra Certification Authority + // https://sslev.e-tugra.com.tr + "2.16.792.3.0.4.1.1.4": nil, + // GeoTrust Primary Certification Authority + // https://www.geotrust.com/ + "1.3.6.1.4.1.14370.1.6": nil, + // GlobalSign Root CA - R2 + // https://www.globalsign.com/ + "1.3.6.1.4.1.4146.1.1": nil, + // Go Daddy Class 2 Certification Authority & Go Daddy Root Certificate Authority - G2 + // https://www.godaddy.com/ + // https://valid.gdig2.catest.godaddy.com/ + "2.16.840.1.114413.1.7.23.3": nil, + // Izenpe.com - SHA256 root + // The first OID is for businesses and the second for government entities. + // These are the test sites, respectively: + // https://servicios.izenpe.com + // https://servicios1.izenpe.com + // Windows XP finds this, SHA1, root instead. The policy OIDs are the same + // as for the SHA256 root, above. + "1.3.6.1.4.1.14777.6.1.1": nil, + "1.3.6.1.4.1.14777.6.1.2": nil, + // Network Solutions Certificate Authority + // https://www.networksolutions.com/website-packages/index.jsp + "1.3.6.1.4.1.782.1.2.1.8.1": nil, + // QuoVadis Root CA 2 + // https://www.quovadis.bm/ + "1.3.6.1.4.1.8024.0.2.100.1.2": nil, + // SecureTrust CA, SecureTrust Corporation + // https://www.securetrust.com + // https://www.trustwave.com/ + "2.16.840.1.114404.1.1.2.4.1": nil, + // Security Communication RootCA1 + // https://www.secomtrust.net/contact/form.html + "1.2.392.200091.100.721.1": nil, + // Staat der Nederlanden EV Root CA + // https://pkioevssl-v.quovadisglobal.com/ + "2.16.528.1.1003.1.2.7": nil, + // StartCom Certification Authority + // https://www.startssl.com/ + "1.3.6.1.4.1.23223.1.1.1": nil, + // Starfield Class 2 Certification Authority + // https://www.starfieldtech.com/ + "2.16.840.1.114414.1.7.23.3": nil, + // Starfield Services Root Certificate Authority - G2 + // https://valid.sfsg2.catest.starfieldtech.com/ + "2.16.840.1.114414.1.7.24.3": nil, + // SwissSign Gold CA - G2 + // https://testevg2.swisssign.net/ + "2.16.756.1.89.1.2.1.1": nil, + // Swisscom Root EV CA 2 + // https://test-quarz-ev-ca-2.pre.swissdigicert.ch + "2.16.756.1.83.21.0": nil, + // thawte Primary Root CA + // https://www.thawte.com/ + "2.16.840.1.113733.1.7.48.1": nil, + // TWCA Global Root CA + // https://evssldemo3.twca.com.tw/index.html + "1.3.6.1.4.1.40869.1.1.22.3": nil, + // T-TeleSec GlobalRoot Class 3 + // http://www.telesec.de/ / https://root-class3.test.telesec.de/ + "1.3.6.1.4.1.7879.13.24.1": nil, + // VeriSign Class 3 Public Primary Certification Authority - G5 + // https://www.verisign.com/ + "2.16.840.1.113733.1.7.23.6": nil, + // Wells Fargo WellsSecure Public Root Certificate Authority + // https://nerys.wellsfargo.com/test.html + "2.16.840.1.114171.500.9": nil, + // CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN + // https://www.cfca.com.cn/ + "2.16.156.112554.3": nil, + // CN=OISTE WISeKey Global Root GB CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH + // https://www.wisekey.com/repository/cacertificates/ + "2.16.756.5.14.7.4.8": nil, + // CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6,O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A...,L=Ankara,C=TR + // https://www.turktrust.com.tr/ + "2.16.792.3.0.3.1.1.5": nil, +} + +// OrganizationValidationOIDs contains CA specific OV OIDs from +// https://cabforum.org/object-registry/ +var OrganizationValidationOIDs = map[string]interface{}{ + // CA/Browser Forum OV OID standard + // https://cabforum.org/object-registry/ + "2.23.140.1.2.2": nil, + // CA/Browser Forum individually validated + "2.23.140.1.2.3": nil, + // Digicert + "2.16.840.1.114412.1.1": nil, + // D-Trust + "1.3.6.1.4.1.4788.2.200.1": nil, + // GoDaddy + "2.16.840.1.114413.1.7.23.2": nil, + // Logius + "2.16.528.1.1003.1.2.5.6": nil, + // QuoVadis + "1.3.6.1.4.1.8024.0.2.100.1.1": nil, + // Starfield + "2.16.840.1.114414.1.7.23.2": nil, + // TurkTrust + "2.16.792.3.0.3.1.1.2": nil, +} + +// DomainValidationOIDs contain OIDs that identify DV certs. +var DomainValidationOIDs = map[string]interface{}{ + // Globalsign + "1.3.6.1.4.1.4146.1.10.10": nil, + // Let's Encrypt + "1.3.6.1.4.1.44947.1.1.1": nil, + // Comodo (eNom) + "1.3.6.1.4.1.6449.1.2.2.10": nil, + // Comodo (WoTrust) + "1.3.6.1.4.1.6449.1.2.2.15": nil, + // Comodo (RBC SOFT) + "1.3.6.1.4.1.6449.1.2.2.16": nil, + // Comodo (RegisterFly) + "1.3.6.1.4.1.6449.1.2.2.17": nil, + // Comodo (Central Security Patrols) + "1.3.6.1.4.1.6449.1.2.2.18": nil, + // Comodo (eBiz Networks) + "1.3.6.1.4.1.6449.1.2.2.19": nil, + // Comodo (OptimumSSL) + "1.3.6.1.4.1.6449.1.2.2.21": nil, + // Comodo (WoSign) + "1.3.6.1.4.1.6449.1.2.2.22": nil, + // Comodo (Register.com) + "1.3.6.1.4.1.6449.1.2.2.24": nil, + // Comodo (The Code Project) + "1.3.6.1.4.1.6449.1.2.2.25": nil, + // Comodo (Gandi) + "1.3.6.1.4.1.6449.1.2.2.26": nil, + // Comodo (GlobeSSL) + "1.3.6.1.4.1.6449.1.2.2.27": nil, + // Comodo (DreamHost) + "1.3.6.1.4.1.6449.1.2.2.28": nil, + // Comodo (TERENA) + "1.3.6.1.4.1.6449.1.2.2.29": nil, + // Comodo (GlobalSSL) + "1.3.6.1.4.1.6449.1.2.2.31": nil, + // Comodo (IceWarp) + "1.3.6.1.4.1.6449.1.2.2.35": nil, + // Comodo (Dotname Korea) + "1.3.6.1.4.1.6449.1.2.2.37": nil, + // Comodo (TrustSign) + "1.3.6.1.4.1.6449.1.2.2.38": nil, + // Comodo (Formidable) + "1.3.6.1.4.1.6449.1.2.2.39": nil, + // Comodo (SSL Blindado) + "1.3.6.1.4.1.6449.1.2.2.40": nil, + // Comodo (Dreamscape Networks) + "1.3.6.1.4.1.6449.1.2.2.41": nil, + // Comodo (K Software) + "1.3.6.1.4.1.6449.1.2.2.42": nil, + // Comodo (FBS) + "1.3.6.1.4.1.6449.1.2.2.44": nil, + // Comodo (ReliaSite) + "1.3.6.1.4.1.6449.1.2.2.45": nil, + // Comodo (CertAssure) + "1.3.6.1.4.1.6449.1.2.2.47": nil, + // Comodo (TrustAsia) + "1.3.6.1.4.1.6449.1.2.2.49": nil, + // Comodo (SecureCore) + "1.3.6.1.4.1.6449.1.2.2.50": nil, + // Comodo (Western Digital) + "1.3.6.1.4.1.6449.1.2.2.51": nil, + // Comodo (cPanel) + "1.3.6.1.4.1.6449.1.2.2.52": nil, + // Comodo (BlackCert) + "1.3.6.1.4.1.6449.1.2.2.53": nil, + // Comodo (KeyNet Systems) + "1.3.6.1.4.1.6449.1.2.2.54": nil, + // Comodo + "1.3.6.1.4.1.6449.1.2.2.7": nil, + // Comodo (CSC) + "1.3.6.1.4.1.6449.1.2.2.8": nil, + // Digicert + "2.16.840.1.114412.1.2": nil, + // GoDaddy + "2.16.840.1.114413.1.7.23.1": nil, + // Starfield + "2.16.840.1.114414.1.7.23.1": nil, + // CA/B Forum + "2.23.140.1.2.1": nil, +} + +// TODO pull out other types +type AuthorityInfoAccess struct { + OCSPServer []string `json:"ocsp_urls,omitempty"` + IssuingCertificateURL []string `json:"issuer_urls,omitempty"` +} + +/* + id-CABFOrganizationIdentifier OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) international-organizations(23) ca-browser-forum(140) certificate-extensions(3) cabf-organization-identifier(1) } + + ext-CABFOrganizationIdentifier EXTENSION ::= { SYNTAX CABFOrganizationIdentifier IDENTIFIED BY id-CABFOrganizationIdentifier } + + CABFOrganizationIdentifier ::= SEQUENCE { + + registrationSchemeIdentifier PrintableString (SIZE(3)), + + registrationCountry PrintableString (SIZE(2)), + + registrationStateOrProvince [0] IMPLICIT PrintableString OPTIONAL (SIZE(0..128)), + + registrationReference UTF8String + + } +*/ +type CABFOrganizationIDASN struct { + RegistrationSchemeIdentifier string `asn1:"printable"` + RegistrationCountry string `asn1:"printable"` + RegistrationStateOrProvince string `asn1:"printable,optional,tag:0"` + RegistrationReference string `asn1:"utf8"` +} + +type CABFOrganizationIdentifier struct { + Scheme string `json:"scheme,omitempty"` + Country string `json:"country,omitempty"` + State string `json:"state,omitempty"` + Reference string `json:"reference,omitempty"` +} + +func (c *Certificate) jsonifyExtensions() (*CertificateExtensions, UnknownCertificateExtensions) { + exts := new(CertificateExtensions) + unk := make([]pkix.Extension, 0, 2) + for _, e := range c.Extensions { + if e.Id.Equal(oidExtKeyUsage) { + exts.KeyUsage = c.KeyUsage + } else if e.Id.Equal(oidExtBasicConstraints) { + exts.BasicConstraints = new(BasicConstraints) + exts.BasicConstraints.IsCA = c.IsCA + if c.MaxPathLen > 0 || c.MaxPathLenZero { + exts.BasicConstraints.MaxPathLen = new(int) + *exts.BasicConstraints.MaxPathLen = c.MaxPathLen + } + } else if e.Id.Equal(oidExtSubjectAltName) { + exts.SubjectAltName = new(GeneralNames) + exts.SubjectAltName.DirectoryNames = c.DirectoryNames + exts.SubjectAltName.DNSNames = c.DNSNames + exts.SubjectAltName.EDIPartyNames = c.EDIPartyNames + exts.SubjectAltName.EmailAddresses = c.EmailAddresses + exts.SubjectAltName.IPAddresses = c.IPAddresses + exts.SubjectAltName.OtherNames = c.OtherNames + exts.SubjectAltName.RegisteredIDs = c.RegisteredIDs + exts.SubjectAltName.URIs = c.URIs + } else if e.Id.Equal(oidExtIssuerAltName) { + exts.IssuerAltName = new(GeneralNames) + exts.IssuerAltName.DirectoryNames = c.IANDirectoryNames + exts.IssuerAltName.DNSNames = c.IANDNSNames + exts.IssuerAltName.EDIPartyNames = c.IANEDIPartyNames + exts.IssuerAltName.EmailAddresses = c.IANEmailAddresses + exts.IssuerAltName.IPAddresses = c.IANIPAddresses + exts.IssuerAltName.OtherNames = c.IANOtherNames + exts.IssuerAltName.RegisteredIDs = c.IANRegisteredIDs + exts.IssuerAltName.URIs = c.IANURIs + } else if e.Id.Equal(oidExtNameConstraints) { + exts.NameConstraints = new(NameConstraints) + exts.NameConstraints.Critical = c.NameConstraintsCritical + + exts.NameConstraints.PermittedDNSNames = c.PermittedDNSNames + exts.NameConstraints.PermittedEmailAddresses = c.PermittedEmailAddresses + exts.NameConstraints.PermittedIPAddresses = c.PermittedIPAddresses + exts.NameConstraints.PermittedDirectoryNames = c.PermittedDirectoryNames + exts.NameConstraints.PermittedEdiPartyNames = c.PermittedEdiPartyNames + exts.NameConstraints.PermittedRegisteredIDs = c.PermittedRegisteredIDs + + exts.NameConstraints.ExcludedEmailAddresses = c.ExcludedEmailAddresses + exts.NameConstraints.ExcludedDNSNames = c.ExcludedDNSNames + exts.NameConstraints.ExcludedIPAddresses = c.ExcludedIPAddresses + exts.NameConstraints.ExcludedDirectoryNames = c.ExcludedDirectoryNames + exts.NameConstraints.ExcludedEdiPartyNames = c.ExcludedEdiPartyNames + exts.NameConstraints.ExcludedRegisteredIDs = c.ExcludedRegisteredIDs + } else if e.Id.Equal(oidCRLDistributionPoints) { + exts.CRLDistributionPoints = c.CRLDistributionPoints + } else if e.Id.Equal(oidExtAuthKeyId) { + exts.AuthKeyID = c.AuthorityKeyId + } else if e.Id.Equal(oidExtExtendedKeyUsage) { + exts.ExtendedKeyUsage = new(ExtendedKeyUsageExtension) + exts.ExtendedKeyUsage.Known = c.ExtKeyUsage + exts.ExtendedKeyUsage.Unknown = c.UnknownExtKeyUsage + } else if e.Id.Equal(oidExtCertificatePolicy) { + exts.CertificatePolicies = new(CertificatePoliciesData) + exts.CertificatePolicies.PolicyIdentifiers = c.PolicyIdentifiers + exts.CertificatePolicies.NoticeRefNumbers = c.NoticeRefNumbers + exts.CertificatePolicies.NoticeRefOrganization = c.ParsedNoticeRefOrganization + exts.CertificatePolicies.ExplicitTexts = c.ParsedExplicitTexts + exts.CertificatePolicies.QualifierId = c.QualifierId + exts.CertificatePolicies.CPSUri = c.CPSuri + + } else if e.Id.Equal(oidExtAuthorityInfoAccess) { + exts.AuthorityInfoAccess = new(AuthorityInfoAccess) + exts.AuthorityInfoAccess.OCSPServer = c.OCSPServer + exts.AuthorityInfoAccess.IssuingCertificateURL = c.IssuingCertificateURL + } else if e.Id.Equal(oidExtSubjectKeyId) { + exts.SubjectKeyID = c.SubjectKeyId + } else if e.Id.Equal(oidExtSignedCertificateTimestampList) { + exts.SignedCertificateTimestampList = c.SignedCertificateTimestampList + } else if e.Id.Equal(oidExtensionCTPrecertificatePoison) { + exts.IsPrecert = true + } else if e.Id.Equal(oidBRTorServiceDescriptor) { + exts.TorServiceDescriptors = c.TorServiceDescriptors + } else if e.Id.Equal(oidExtCABFOrganizationID) { + exts.CABFOrganizationIdentifier = c.CABFOrganizationIdentifier + } else if e.Id.Equal(oidExtQCStatements) { + exts.QCStatements = c.QCStatements + } else { + // Unknown extension + unk = append(unk, e) + } + } + return exts, unk +} diff --git a/vendor/github.com/zmap/zcrypto/x509/fingerprint.go b/vendor/github.com/zmap/zcrypto/x509/fingerprint.go new file mode 100644 index 0000000000..e62a701562 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/fingerprint.go @@ -0,0 +1,61 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "bytes" + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "encoding/json" +) + +// CertificateFingerprint represents a digest/fingerprint of some data. It can +// easily be encoded to hex and JSON (as a hex string). +type CertificateFingerprint []byte + +// MD5Fingerprint creates a fingerprint of data using the MD5 hash algorithm. +func MD5Fingerprint(data []byte) CertificateFingerprint { + sum := md5.Sum(data) + return sum[:] +} + +// SHA1Fingerprint creates a fingerprint of data using the SHA1 hash algorithm. +func SHA1Fingerprint(data []byte) CertificateFingerprint { + sum := sha1.Sum(data) + return sum[:] +} + +// SHA256Fingerprint creates a fingerprint of data using the SHA256 hash +// algorithm. +func SHA256Fingerprint(data []byte) CertificateFingerprint { + sum := sha256.Sum256(data) + return sum[:] +} + +// SHA512Fingerprint creates a fingerprint of data using the SHA256 hash +// algorithm. +func SHA512Fingerprint(data []byte) CertificateFingerprint { + sum := sha512.Sum512(data) + return sum[:] +} + +// Equal returns true if the fingerprints are bytewise-equal. +func (f CertificateFingerprint) Equal(other CertificateFingerprint) bool { + return bytes.Equal(f, other) +} + +// Hex returns the given fingerprint encoded as a hex string. +func (f CertificateFingerprint) Hex() string { + return hex.EncodeToString(f) +} + +// MarshalJSON implements the json.Marshaler interface, and marshals the +// fingerprint as a hex string. +func (f *CertificateFingerprint) MarshalJSON() ([]byte, error) { + return json.Marshal(f.Hex()) +} diff --git a/vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go b/vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go new file mode 100644 index 0000000000..23cd32a1ed --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go @@ -0,0 +1,16 @@ +// Code generated by "stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go"; DO NOT EDIT. + +package x509 + +import "strconv" + +const _CertValidationLevel_name = "UnknownValidationLevelDVOVEV" + +var _CertValidationLevel_index = [...]uint8{0, 22, 24, 26, 28} + +func (i CertValidationLevel) String() string { + if i < 0 || i >= CertValidationLevel(len(_CertValidationLevel_index)-1) { + return "CertValidationLevel(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _CertValidationLevel_name[_CertValidationLevel_index[i]:_CertValidationLevel_index[i+1]] +} diff --git a/vendor/github.com/zmap/zcrypto/x509/json.go b/vendor/github.com/zmap/zcrypto/x509/json.go new file mode 100644 index 0000000000..f4a3ff2b30 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/json.go @@ -0,0 +1,651 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "crypto/dsa" + "crypto/ecdsa" + "crypto/rsa" + "encoding/asn1" + "encoding/json" + "errors" + "net" + "sort" + + "strings" + "time" + + jsonKeys "github.com/zmap/zcrypto/json" + "github.com/zmap/zcrypto/util" + "github.com/zmap/zcrypto/x509/pkix" +) + +var kMinTime, kMaxTime time.Time + +func init() { + var err error + kMinTime, err = time.Parse(time.RFC3339, "1970-01-01T00:00:00Z") + if err != nil { + panic(err) + } + kMaxTime, err = time.Parse(time.RFC3339, "9999-12-31T23:59:59Z") + if err != nil { + panic(err) + } +} + +type auxKeyUsage struct { + DigitalSignature bool `json:"digital_signature,omitempty"` + ContentCommitment bool `json:"content_commitment,omitempty"` + KeyEncipherment bool `json:"key_encipherment,omitempty"` + DataEncipherment bool `json:"data_encipherment,omitempty"` + KeyAgreement bool `json:"key_agreement,omitempty"` + CertificateSign bool `json:"certificate_sign,omitempty"` + CRLSign bool `json:"crl_sign,omitempty"` + EncipherOnly bool `json:"encipher_only,omitempty"` + DecipherOnly bool `json:"decipher_only,omitempty"` + Value uint32 `json:"value"` +} + +// MarshalJSON implements the json.Marshaler interface +func (k KeyUsage) MarshalJSON() ([]byte, error) { + var enc auxKeyUsage + enc.Value = uint32(k) + if k&KeyUsageDigitalSignature > 0 { + enc.DigitalSignature = true + } + if k&KeyUsageContentCommitment > 0 { + enc.ContentCommitment = true + } + if k&KeyUsageKeyEncipherment > 0 { + enc.KeyEncipherment = true + } + if k&KeyUsageDataEncipherment > 0 { + enc.DataEncipherment = true + } + if k&KeyUsageKeyAgreement > 0 { + enc.KeyAgreement = true + } + if k&KeyUsageCertSign > 0 { + enc.CertificateSign = true + } + if k&KeyUsageCRLSign > 0 { + enc.CRLSign = true + } + if k&KeyUsageEncipherOnly > 0 { + enc.EncipherOnly = true + } + if k&KeyUsageDecipherOnly > 0 { + enc.DecipherOnly = true + } + return json.Marshal(&enc) +} + +// UnmarshalJSON implements the json.Unmarshler interface +func (k *KeyUsage) UnmarshalJSON(b []byte) error { + var aux auxKeyUsage + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + // TODO: validate the flags match + v := int(aux.Value) + *k = KeyUsage(v) + return nil +} + +// JSONSignatureAlgorithm is the intermediate type +// used when marshaling a PublicKeyAlgorithm out to JSON. +type JSONSignatureAlgorithm struct { + Name string `json:"name,omitempty"` + OID pkix.AuxOID `json:"oid"` +} + +// MarshalJSON implements the json.Marshaler interface +// MAY NOT PRESERVE ORIGINAL OID FROM CERTIFICATE - +// CONSIDER USING jsonifySignatureAlgorithm INSTEAD! +func (s *SignatureAlgorithm) MarshalJSON() ([]byte, error) { + aux := JSONSignatureAlgorithm{ + Name: s.String(), + } + for _, val := range signatureAlgorithmDetails { + if val.algo == *s { + aux.OID = make([]int, len(val.oid)) + for idx := range val.oid { + aux.OID[idx] = val.oid[idx] + } + } + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshler interface +func (s *SignatureAlgorithm) UnmarshalJSON(b []byte) error { + var aux JSONSignatureAlgorithm + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + *s = UnknownSignatureAlgorithm + oid := asn1.ObjectIdentifier(aux.OID.AsSlice()) + if oid.Equal(oidSignatureRSAPSS) { + pssAlgs := []SignatureAlgorithm{SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS} + for _, alg := range pssAlgs { + if strings.Compare(alg.String(), aux.Name) == 0 { + *s = alg + break + } + } + } else { + for _, val := range signatureAlgorithmDetails { + if val.oid.Equal(oid) { + *s = val.algo + break + } + } + } + return nil +} + +// jsonifySignatureAlgorithm gathers the necessary fields in a Certificate +// into a JSONSignatureAlgorithm, which can then use the default +// JSON marhsalers and unmarshalers. THIS FUNCTION IS PREFERED OVER +// THE CUSTOM JSON MARSHALER PRESENTED ABOVE FOR SIGNATUREALGORITHM +// BECAUSE THIS METHOD PRESERVES THE OID ORIGINALLY IN THE CERTIFICATE! +// This reason also explains why we need this function - +// the OID is unfortunately stored outside the scope of a +// SignatureAlgorithm struct and cannot be recovered without access to the +// entire Certificate if we do not know the signature algorithm. +func (c *Certificate) jsonifySignatureAlgorithm() JSONSignatureAlgorithm { + aux := JSONSignatureAlgorithm{} + if c.SignatureAlgorithm == 0 { + aux.Name = "unknown_algorithm" + } else { + aux.Name = c.SignatureAlgorithm.String() + } + aux.OID = make([]int, len(c.SignatureAlgorithmOID)) + for idx := range c.SignatureAlgorithmOID { + aux.OID[idx] = c.SignatureAlgorithmOID[idx] + } + return aux +} + +type auxPublicKeyAlgorithm struct { + Name string `json:"name,omitempty"` + OID *pkix.AuxOID `json:"oid,omitempty"` +} + +var publicKeyNameToAlgorithm = map[string]PublicKeyAlgorithm{ + "RSA": RSA, + "DSA": DSA, + "ECDSA": ECDSA, +} + +// MarshalJSON implements the json.Marshaler interface +func (p *PublicKeyAlgorithm) MarshalJSON() ([]byte, error) { + aux := auxPublicKeyAlgorithm{ + Name: p.String(), + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshaler interface +func (p *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error { + var aux auxPublicKeyAlgorithm + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + *p = publicKeyNameToAlgorithm[aux.Name] + return nil +} + +func clampTime(t time.Time) time.Time { + if t.Before(kMinTime) { + return kMinTime + } + if t.After(kMaxTime) { + return kMaxTime + } + return t +} + +type auxValidity struct { + Start string `json:"start"` + End string `json:"end"` + ValidityPeriod int `json:"length"` +} + +func (v *validity) MarshalJSON() ([]byte, error) { + aux := auxValidity{ + Start: clampTime(v.NotBefore.UTC()).Format(time.RFC3339), + End: clampTime(v.NotAfter.UTC()).Format(time.RFC3339), + ValidityPeriod: int(v.NotAfter.Sub(v.NotBefore).Seconds()), + } + return json.Marshal(&aux) +} + +func (v *validity) UnmarshalJSON(b []byte) error { + var aux auxValidity + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + var err error + if v.NotBefore, err = time.Parse(time.RFC3339, aux.Start); err != nil { + return err + } + if v.NotAfter, err = time.Parse(time.RFC3339, aux.End); err != nil { + return err + } + + return nil +} + +// ECDSAPublicKeyJSON - used to condense several fields from a +// ECDSA public key into one field for use in JSONCertificate. +// Uses default JSON marshal and unmarshal methods +type ECDSAPublicKeyJSON struct { + B []byte `json:"b"` + Curve string `json:"curve"` + Gx []byte `json:"gx"` + Gy []byte `json:"gy"` + Length int `json:"length"` + N []byte `json:"n"` + P []byte `json:"p"` + Pub []byte `json:"pub,omitempty"` + X []byte `json:"x"` + Y []byte `json:"y"` +} + +// DSAPublicKeyJSON - used to condense several fields from a +// DSA public key into one field for use in JSONCertificate. +// Uses default JSON marshal and unmarshal methods +type DSAPublicKeyJSON struct { + G []byte `json:"g"` + P []byte `json:"p"` + Q []byte `json:"q"` + Y []byte `json:"y"` +} + +// GetDSAPublicKeyJSON - get the DSAPublicKeyJSON for the given standard DSA PublicKey. +func GetDSAPublicKeyJSON(key *dsa.PublicKey) *DSAPublicKeyJSON { + return &DSAPublicKeyJSON{ + P: key.P.Bytes(), + Q: key.Q.Bytes(), + G: key.G.Bytes(), + Y: key.Y.Bytes(), + } +} + +// GetRSAPublicKeyJSON - get the jsonKeys.RSAPublicKey for the given standard RSA PublicKey. +func GetRSAPublicKeyJSON(key *rsa.PublicKey) *jsonKeys.RSAPublicKey { + rsaKey := new(jsonKeys.RSAPublicKey) + rsaKey.PublicKey = key + return rsaKey +} + +// GetECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given standard ECDSA PublicKey. +func GetECDSAPublicKeyJSON(key *ecdsa.PublicKey) *ECDSAPublicKeyJSON { + params := key.Params() + return &ECDSAPublicKeyJSON{ + P: params.P.Bytes(), + N: params.N.Bytes(), + B: params.B.Bytes(), + Gx: params.Gx.Bytes(), + Gy: params.Gy.Bytes(), + X: key.X.Bytes(), + Y: key.Y.Bytes(), + Curve: key.Curve.Params().Name, + Length: key.Curve.Params().BitSize, + } +} + +// GetAugmentedECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given "augmented" +// ECDSA PublicKey. +func GetAugmentedECDSAPublicKeyJSON(key *AugmentedECDSA) *ECDSAPublicKeyJSON { + params := key.Pub.Params() + return &ECDSAPublicKeyJSON{ + P: params.P.Bytes(), + N: params.N.Bytes(), + B: params.B.Bytes(), + Gx: params.Gx.Bytes(), + Gy: params.Gy.Bytes(), + X: key.Pub.X.Bytes(), + Y: key.Pub.Y.Bytes(), + Curve: key.Pub.Curve.Params().Name, + Length: key.Pub.Curve.Params().BitSize, + Pub: key.Raw.Bytes, + } +} + +// jsonifySubjectKey - Convert public key data in a Certificate +// into json output format for JSONCertificate +func (c *Certificate) jsonifySubjectKey() JSONSubjectKeyInfo { + j := JSONSubjectKeyInfo{ + KeyAlgorithm: c.PublicKeyAlgorithm, + SPKIFingerprint: c.SPKIFingerprint, + } + + switch key := c.PublicKey.(type) { + case *rsa.PublicKey: + rsaKey := new(jsonKeys.RSAPublicKey) + rsaKey.PublicKey = key + j.RSAPublicKey = rsaKey + case *dsa.PublicKey: + j.DSAPublicKey = &DSAPublicKeyJSON{ + P: key.P.Bytes(), + Q: key.Q.Bytes(), + G: key.G.Bytes(), + Y: key.Y.Bytes(), + } + case *ecdsa.PublicKey: + params := key.Params() + j.ECDSAPublicKey = &ECDSAPublicKeyJSON{ + P: params.P.Bytes(), + N: params.N.Bytes(), + B: params.B.Bytes(), + Gx: params.Gx.Bytes(), + Gy: params.Gy.Bytes(), + X: key.X.Bytes(), + Y: key.Y.Bytes(), + Curve: key.Curve.Params().Name, + Length: key.Curve.Params().BitSize, + } + case *AugmentedECDSA: + params := key.Pub.Params() + j.ECDSAPublicKey = &ECDSAPublicKeyJSON{ + P: params.P.Bytes(), + N: params.N.Bytes(), + B: params.B.Bytes(), + Gx: params.Gx.Bytes(), + Gy: params.Gy.Bytes(), + X: key.Pub.X.Bytes(), + Y: key.Pub.Y.Bytes(), + Curve: key.Pub.Curve.Params().Name, + Length: key.Pub.Curve.Params().BitSize, + Pub: key.Raw.Bytes, + } + } + return j +} + +// JSONSubjectKeyInfo - used to condense several fields from x509.Certificate +// related to the subject public key into one field within JSONCertificate +// Unfortunately, this struct cannot have its own Marshal method since it +// needs information from multiple fields in x509.Certificate +type JSONSubjectKeyInfo struct { + KeyAlgorithm PublicKeyAlgorithm `json:"key_algorithm"` + RSAPublicKey *jsonKeys.RSAPublicKey `json:"rsa_public_key,omitempty"` + DSAPublicKey *DSAPublicKeyJSON `json:"dsa_public_key,omitempty"` + ECDSAPublicKey *ECDSAPublicKeyJSON `json:"ecdsa_public_key,omitempty"` + SPKIFingerprint CertificateFingerprint `json:"fingerprint_sha256"` +} + +// JSONSignature - used to condense several fields from x509.Certificate +// related to the signature into one field within JSONCertificate +// Unfortunately, this struct cannot have its own Marshal method since it +// needs information from multiple fields in x509.Certificate +type JSONSignature struct { + SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"` + Value []byte `json:"value"` + Valid bool `json:"valid"` + SelfSigned bool `json:"self_signed"` +} + +// JSONValidity - used to condense several fields related +// to validity in x509.Certificate into one field within JSONCertificate +// Unfortunately, this struct cannot have its own Marshal method since it +// needs information from multiple fields in x509.Certificate +type JSONValidity struct { + validity + ValidityPeriod int +} + +// JSONCertificate - used to condense data from x509.Certificate when marhsaling +// into JSON. This struct has a distinct and independent layout from +// x509.Certificate, mostly for condensing data across repetitive +// fields and making it more presentable. +type JSONCertificate struct { + Version int `json:"version"` + SerialNumber string `json:"serial_number"` + SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"` + Issuer pkix.Name `json:"issuer"` + IssuerDN string `json:"issuer_dn,omitempty"` + Validity JSONValidity `json:"validity"` + Subject pkix.Name `json:"subject"` + SubjectDN string `json:"subject_dn,omitempty"` + SubjectKeyInfo JSONSubjectKeyInfo `json:"subject_key_info"` + Extensions *CertificateExtensions `json:"extensions,omitempty"` + UnknownExtensions UnknownCertificateExtensions `json:"unknown_extensions,omitempty"` + Signature JSONSignature `json:"signature"` + FingerprintMD5 CertificateFingerprint `json:"fingerprint_md5"` + FingerprintSHA1 CertificateFingerprint `json:"fingerprint_sha1"` + FingerprintSHA256 CertificateFingerprint `json:"fingerprint_sha256"` + FingerprintNoCT CertificateFingerprint `json:"tbs_noct_fingerprint"` + SPKISubjectFingerprint CertificateFingerprint `json:"spki_subject_fingerprint"` + TBSCertificateFingerprint CertificateFingerprint `json:"tbs_fingerprint"` + ValidationLevel CertValidationLevel `json:"validation_level"` + Names []string `json:"names,omitempty"` + Redacted bool `json:"redacted"` +} + +// CollectAllNames - Collect and validate all DNS / URI / IP Address names for a given certificate +func (c *Certificate) CollectAllNames() []string { + var names []string + + if isValidName(c.Subject.CommonName) { + names = append(names, c.Subject.CommonName) + } + + for _, name := range c.DNSNames { + if isValidName(name) { + names = append(names, name) + } else if !strings.Contains(name, ".") { //just a TLD + names = append(names, name) + } + + } + + for _, name := range c.URIs { + if util.IsURL(name) { + names = append(names, name) + } + } + + for _, name := range c.IPAddresses { + str := name.String() + if util.IsURL(str) { + names = append(names, str) + } + } + + return purgeNameDuplicates(names) +} + +func (c *Certificate) MarshalJSON() ([]byte, error) { + // Fill out the certificate + jc := new(JSONCertificate) + jc.Version = c.Version + jc.SerialNumber = c.SerialNumber.String() + jc.Issuer = c.Issuer + jc.IssuerDN = c.Issuer.String() + + jc.Validity.NotBefore = c.NotBefore + jc.Validity.NotAfter = c.NotAfter + jc.Validity.ValidityPeriod = c.ValidityPeriod + jc.Subject = c.Subject + jc.SubjectDN = c.Subject.String() + jc.Names = c.CollectAllNames() + jc.Redacted = false + for _, name := range jc.Names { + if strings.HasPrefix(name, "?") { + jc.Redacted = true + } + } + + jc.SubjectKeyInfo = c.jsonifySubjectKey() + jc.Extensions, jc.UnknownExtensions = c.jsonifyExtensions() + + // TODO: Handle the fact this might not match + jc.SignatureAlgorithm = c.jsonifySignatureAlgorithm() + jc.Signature.SignatureAlgorithm = jc.SignatureAlgorithm + jc.Signature.Value = c.Signature + jc.Signature.Valid = c.validSignature + jc.Signature.SelfSigned = c.SelfSigned + if c.SelfSigned { + jc.Signature.Valid = true + } + jc.FingerprintMD5 = c.FingerprintMD5 + jc.FingerprintSHA1 = c.FingerprintSHA1 + jc.FingerprintSHA256 = c.FingerprintSHA256 + jc.FingerprintNoCT = c.FingerprintNoCT + jc.SPKISubjectFingerprint = c.SPKISubjectFingerprint + jc.TBSCertificateFingerprint = c.TBSCertificateFingerprint + jc.ValidationLevel = c.ValidationLevel + + return json.Marshal(jc) +} + +// UnmarshalJSON - intentionally implimented to always error, +// as this method should not be used. The MarshalJSON method +// on Certificate condenses data in a way that is not recoverable. +// Use the x509.ParseCertificate function instead or +// JSONCertificateWithRaw Marshal method +func (jc *JSONCertificate) UnmarshalJSON(b []byte) error { + return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function") +} + +// UnmarshalJSON - intentionally implimented to always error, +// as this method should not be used. The MarshalJSON method +// on Certificate condenses data in a way that is not recoverable. +// Use the x509.ParseCertificate function instead or +// JSONCertificateWithRaw Marshal method +func (c *Certificate) UnmarshalJSON(b []byte) error { + return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function") +} + +// JSONCertificateWithRaw - intermediate struct for unmarshaling json +// of a certificate - the raw is require since the +// MarshalJSON method on Certificate condenses data in a way that +// makes extraction to the original in Unmarshal impossible. +// The JSON output of Marshal is not even used to construct +// a certificate, all we need is raw +type JSONCertificateWithRaw struct { + Raw []byte `json:"raw,omitempty"` +} + +// ParseRaw - for converting the intermediate object +// JSONCertificateWithRaw into a parsed Certificate +// see description of JSONCertificateWithRaw for +// why this is used instead of UnmarshalJSON methods +func (c *JSONCertificateWithRaw) ParseRaw() (*Certificate, error) { + return ParseCertificate(c.Raw) +} + +func purgeNameDuplicates(names []string) (out []string) { + hashset := make(map[string]bool, len(names)) + for _, name := range names { + if _, inc := hashset[name]; !inc { + hashset[name] = true + } + } + + out = make([]string, 0, len(hashset)) + for key := range hashset { + out = append(out, key) + } + + sort.Strings(out) // must sort to ensure output is deterministic! + return +} + +func isValidName(name string) (ret bool) { + + // Check for wildcards and redacts, ignore malformed urls + if strings.HasPrefix(name, "?.") || strings.HasPrefix(name, "*.") { + ret = isValidName(name[2:]) + } else { + ret = util.IsURL(name) + } + return +} + +func orMask(ip net.IP, mask net.IPMask) net.IP { + if len(ip) == 0 || len(mask) == 0 { + return nil + } + if len(ip) != net.IPv4len && len(ip) != net.IPv6len { + return nil + } + if len(ip) != len(mask) { + return nil + } + out := make([]byte, len(ip)) + for idx := range ip { + out[idx] = ip[idx] | mask[idx] + } + return out +} + +func invertMask(mask net.IPMask) net.IPMask { + if mask == nil { + return nil + } + out := make([]byte, len(mask)) + for idx := range mask { + out[idx] = ^mask[idx] + } + return out +} + +type auxGeneralSubtreeIP struct { + CIDR string `json:"cidr,omitempty"` + Begin string `json:"begin,omitempty"` + End string `json:"end,omitempty"` + Mask string `json:"mask,omitempty"` +} + +func (g *GeneralSubtreeIP) MarshalJSON() ([]byte, error) { + aux := auxGeneralSubtreeIP{} + aux.CIDR = g.Data.String() + // Check to see if the subnet is valid. An invalid subnet will return 0,0 + // from Size(). If the subnet is invalid, only output the CIDR. + ones, bits := g.Data.Mask.Size() + if ones == 0 && bits == 0 { + return json.Marshal(&aux) + } + // The first IP in the range should be `ip & mask`. + begin := g.Data.IP.Mask(g.Data.Mask) + if begin != nil { + aux.Begin = begin.String() + } + // The last IP (inclusive) is `ip & (^mask)`. + inverseMask := invertMask(g.Data.Mask) + end := orMask(g.Data.IP, inverseMask) + if end != nil { + aux.End = end.String() + } + // Output the mask as an IP, but enforce it can be formatted correctly. + // net.IP.String() only works on byte arrays of the correct length. + maskLen := len(g.Data.Mask) + if maskLen == net.IPv4len || maskLen == net.IPv6len { + maskAsIP := net.IP(g.Data.Mask) + aux.Mask = maskAsIP.String() + } + return json.Marshal(&aux) +} + +func (g *GeneralSubtreeIP) UnmarshalJSON(b []byte) error { + aux := auxGeneralSubtreeIP{} + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + ip, ipNet, err := net.ParseCIDR(aux.CIDR) + if err != nil { + return err + } + g.Data.IP = ip + g.Data.Mask = ipNet.Mask + g.Min = 0 + g.Max = 0 + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/names.go b/vendor/github.com/zmap/zcrypto/x509/names.go new file mode 100644 index 0000000000..012f919210 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/names.go @@ -0,0 +1,30 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +func (p PublicKeyAlgorithm) String() string { + if p >= total_key_algorithms || p < 0 { + p = UnknownPublicKeyAlgorithm + } + return keyAlgorithmNames[p] +} + +func (c *Certificate) SignatureAlgorithmName() string { + switch c.SignatureAlgorithm { + case UnknownSignatureAlgorithm: + return c.SignatureAlgorithmOID.String() + default: + return c.SignatureAlgorithm.String() + } +} + +func (c *Certificate) PublicKeyAlgorithmName() string { + switch c.PublicKeyAlgorithm { + case UnknownPublicKeyAlgorithm: + return c.PublicKeyAlgorithmOID.String() + default: + return c.PublicKeyAlgorithm.String() + } +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go b/vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go new file mode 100644 index 0000000000..0388d63e14 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go @@ -0,0 +1,240 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +// RFC 1423 describes the encryption of PEM blocks. The algorithm used to +// generate a key from the password was derived by looking at the OpenSSL +// implementation. + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/des" + "crypto/md5" + "encoding/hex" + "encoding/pem" + "errors" + "io" + "strings" +) + +type PEMCipher int + +// Possible values for the EncryptPEMBlock encryption algorithm. +const ( + _ PEMCipher = iota + PEMCipherDES + PEMCipher3DES + PEMCipherAES128 + PEMCipherAES192 + PEMCipherAES256 +) + +// rfc1423Algo holds a method for enciphering a PEM block. +type rfc1423Algo struct { + cipher PEMCipher + name string + cipherFunc func(key []byte) (cipher.Block, error) + keySize int + blockSize int +} + +// rfc1423Algos holds a slice of the possible ways to encrypt a PEM +// block. The ivSize numbers were taken from the OpenSSL source. +var rfc1423Algos = []rfc1423Algo{{ + cipher: PEMCipherDES, + name: "DES-CBC", + cipherFunc: des.NewCipher, + keySize: 8, + blockSize: des.BlockSize, +}, { + cipher: PEMCipher3DES, + name: "DES-EDE3-CBC", + cipherFunc: des.NewTripleDESCipher, + keySize: 24, + blockSize: des.BlockSize, +}, { + cipher: PEMCipherAES128, + name: "AES-128-CBC", + cipherFunc: aes.NewCipher, + keySize: 16, + blockSize: aes.BlockSize, +}, { + cipher: PEMCipherAES192, + name: "AES-192-CBC", + cipherFunc: aes.NewCipher, + keySize: 24, + blockSize: aes.BlockSize, +}, { + cipher: PEMCipherAES256, + name: "AES-256-CBC", + cipherFunc: aes.NewCipher, + keySize: 32, + blockSize: aes.BlockSize, +}, +} + +// deriveKey uses a key derivation function to stretch the password into a key +// with the number of bits our cipher requires. This algorithm was derived from +// the OpenSSL source. +func (c rfc1423Algo) deriveKey(password, salt []byte) []byte { + hash := md5.New() + out := make([]byte, c.keySize) + var digest []byte + + for i := 0; i < len(out); i += len(digest) { + hash.Reset() + hash.Write(digest) + hash.Write(password) + hash.Write(salt) + digest = hash.Sum(digest[:0]) + copy(out[i:], digest) + } + return out +} + +// IsEncryptedPEMBlock returns if the PEM block is password encrypted. +func IsEncryptedPEMBlock(b *pem.Block) bool { + _, ok := b.Headers["DEK-Info"] + return ok +} + +// IncorrectPasswordError is returned when an incorrect password is detected. +var IncorrectPasswordError = errors.New("x509: decryption password incorrect") + +// DecryptPEMBlock takes a password encrypted PEM block and the password used to +// encrypt it and returns a slice of decrypted DER encoded bytes. It inspects +// the DEK-Info header to determine the algorithm used for decryption. If no +// DEK-Info header is present, an error is returned. If an incorrect password +// is detected an IncorrectPasswordError is returned. Because of deficiencies +// in the encrypted-PEM format, it's not always possible to detect an incorrect +// password. In these cases no error will be returned but the decrypted DER +// bytes will be random noise. +func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) { + dek, ok := b.Headers["DEK-Info"] + if !ok { + return nil, errors.New("x509: no DEK-Info header in block") + } + + idx := strings.Index(dek, ",") + if idx == -1 { + return nil, errors.New("x509: malformed DEK-Info header") + } + + mode, hexIV := dek[:idx], dek[idx+1:] + ciph := cipherByName(mode) + if ciph == nil { + return nil, errors.New("x509: unknown encryption mode") + } + iv, err := hex.DecodeString(hexIV) + if err != nil { + return nil, err + } + if len(iv) != ciph.blockSize { + return nil, errors.New("x509: incorrect IV size") + } + + // Based on the OpenSSL implementation. The salt is the first 8 bytes + // of the initialization vector. + key := ciph.deriveKey(password, iv[:8]) + block, err := ciph.cipherFunc(key) + if err != nil { + return nil, err + } + + if len(b.Bytes)%block.BlockSize() != 0 { + return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size") + } + + data := make([]byte, len(b.Bytes)) + dec := cipher.NewCBCDecrypter(block, iv) + dec.CryptBlocks(data, b.Bytes) + + // Blocks are padded using a scheme where the last n bytes of padding are all + // equal to n. It can pad from 1 to blocksize bytes inclusive. See RFC 1423. + // For example: + // [x y z 2 2] + // [x y 7 7 7 7 7 7 7] + // If we detect a bad padding, we assume it is an invalid password. + dlen := len(data) + if dlen == 0 || dlen%ciph.blockSize != 0 { + return nil, errors.New("x509: invalid padding") + } + last := int(data[dlen-1]) + if dlen < last { + return nil, IncorrectPasswordError + } + if last == 0 || last > ciph.blockSize { + return nil, IncorrectPasswordError + } + for _, val := range data[dlen-last:] { + if int(val) != last { + return nil, IncorrectPasswordError + } + } + return data[:dlen-last], nil +} + +// EncryptPEMBlock returns a PEM block of the specified type holding the +// given DER-encoded data encrypted with the specified algorithm and +// password. +func EncryptPEMBlock(rand io.Reader, blockType string, data, password []byte, alg PEMCipher) (*pem.Block, error) { + ciph := cipherByKey(alg) + if ciph == nil { + return nil, errors.New("x509: unknown encryption mode") + } + iv := make([]byte, ciph.blockSize) + if _, err := io.ReadFull(rand, iv); err != nil { + return nil, errors.New("x509: cannot generate IV: " + err.Error()) + } + // The salt is the first 8 bytes of the initialization vector, + // matching the key derivation in DecryptPEMBlock. + key := ciph.deriveKey(password, iv[:8]) + block, err := ciph.cipherFunc(key) + if err != nil { + return nil, err + } + enc := cipher.NewCBCEncrypter(block, iv) + pad := ciph.blockSize - len(data)%ciph.blockSize + encrypted := make([]byte, len(data), len(data)+pad) + // We could save this copy by encrypting all the whole blocks in + // the data separately, but it doesn't seem worth the additional + // code. + copy(encrypted, data) + // See RFC 1423, section 1.1 + for i := 0; i < pad; i++ { + encrypted = append(encrypted, byte(pad)) + } + enc.CryptBlocks(encrypted, encrypted) + + return &pem.Block{ + Type: blockType, + Headers: map[string]string{ + "Proc-Type": "4,ENCRYPTED", + "DEK-Info": ciph.name + "," + hex.EncodeToString(iv), + }, + Bytes: encrypted, + }, nil +} + +func cipherByName(name string) *rfc1423Algo { + for i := range rfc1423Algos { + alg := &rfc1423Algos[i] + if alg.name == name { + return alg + } + } + return nil +} + +func cipherByKey(key PEMCipher) *rfc1423Algo { + for i := range rfc1423Algos { + alg := &rfc1423Algos[i] + if alg.cipher == key { + return alg + } + } + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkcs1.go b/vendor/github.com/zmap/zcrypto/x509/pkcs1.go new file mode 100644 index 0000000000..73bc7623a5 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkcs1.go @@ -0,0 +1,121 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "crypto/rsa" + "encoding/asn1" + "errors" + "math/big" +) + +// pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key. +type pkcs1PrivateKey struct { + Version int + N *big.Int + E int + D *big.Int + P *big.Int + Q *big.Int + // We ignore these values, if present, because rsa will calculate them. + Dp *big.Int `asn1:"optional"` + Dq *big.Int `asn1:"optional"` + Qinv *big.Int `asn1:"optional"` + + AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"` +} + +type pkcs1AdditionalRSAPrime struct { + Prime *big.Int + + // We ignore these values because rsa will calculate them. + Exp *big.Int + Coeff *big.Int +} + +// pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key. +type pkcs1PublicKey struct { + N *big.Int + E int +} + +// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form. +func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) { + var priv pkcs1PrivateKey + rest, err := asn1.Unmarshal(der, &priv) + if len(rest) > 0 { + return nil, asn1.SyntaxError{Msg: "trailing data"} + } + if err != nil { + return nil, err + } + + if priv.Version > 1 { + return nil, errors.New("x509: unsupported private key version") + } + + if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 { + return nil, errors.New("x509: private key contains zero or negative value") + } + + key := new(rsa.PrivateKey) + key.PublicKey = rsa.PublicKey{ + E: priv.E, + N: priv.N, + } + + key.D = priv.D + key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes)) + key.Primes[0] = priv.P + key.Primes[1] = priv.Q + for i, a := range priv.AdditionalPrimes { + if a.Prime.Sign() <= 0 { + return nil, errors.New("x509: private key contains zero or negative prime") + } + key.Primes[i+2] = a.Prime + // We ignore the other two values because rsa will calculate + // them as needed. + } + + err = key.Validate() + if err != nil { + return nil, err + } + key.Precompute() + + return key, nil +} + +// MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form. +func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { + key.Precompute() + + version := 0 + if len(key.Primes) > 2 { + version = 1 + } + + priv := pkcs1PrivateKey{ + Version: version, + N: key.N, + E: key.PublicKey.E, + D: key.D, + P: key.Primes[0], + Q: key.Primes[1], + Dp: key.Precomputed.Dp, + Dq: key.Precomputed.Dq, + Qinv: key.Precomputed.Qinv, + } + + priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues)) + for i, values := range key.Precomputed.CRTValues { + priv.AdditionalPrimes[i].Prime = key.Primes[2+i] + priv.AdditionalPrimes[i].Exp = values.Exp + priv.AdditionalPrimes[i].Coeff = values.Coeff + } + + b, _ := asn1.Marshal(priv) + return b +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkcs8.go b/vendor/github.com/zmap/zcrypto/x509/pkcs8.go new file mode 100644 index 0000000000..d69049fae5 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkcs8.go @@ -0,0 +1,54 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "encoding/asn1" + "errors" + "fmt" + "github.com/zmap/zcrypto/x509/pkix" +) + +// pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See +// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn +// and RFC 5208. +type pkcs8 struct { + Version int + Algo pkix.AlgorithmIdentifier + PrivateKey []byte + // optional attributes omitted. +} + +// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. +// See RFC 5208. +func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { + var privKey pkcs8 + if _, err := asn1.Unmarshal(der, &privKey); err != nil { + return nil, err + } + switch { + case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): + key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) + if err != nil { + return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) + } + return key, nil + + case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): + bytes := privKey.Algo.Parameters.FullBytes + namedCurveOID := new(asn1.ObjectIdentifier) + if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { + namedCurveOID = nil + } + key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) + if err != nil { + return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) + } + return key, nil + + default: + return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) + } +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkix/json.go b/vendor/github.com/zmap/zcrypto/x509/pkix/json.go new file mode 100644 index 0000000000..3000f977e2 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkix/json.go @@ -0,0 +1,279 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkix + +import ( + "encoding/asn1" + "encoding/json" + "errors" + "strconv" + "strings" +) + +type auxAttributeTypeAndValue struct { + Type string `json:"type,omitempty"` + Value string `json:"value,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (a *AttributeTypeAndValue) MarshalJSON() ([]byte, error) { + aux := auxAttributeTypeAndValue{} + aux.Type = a.Type.String() + if s, ok := a.Value.(string); ok { + aux.Value = s + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (a *AttributeTypeAndValue) UnmarshalJSON(b []byte) error { + aux := auxAttributeTypeAndValue{} + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + a.Type = nil + if len(aux.Type) > 0 { + parts := strings.Split(aux.Type, ".") + for _, part := range parts { + i, err := strconv.Atoi(part) + if err != nil { + return err + } + a.Type = append(a.Type, i) + } + } + a.Value = aux.Value + return nil +} + +type auxOtherName struct { + ID string `json:"id,omitempty"` + Value []byte `json:"value,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (o *OtherName) MarshalJSON() ([]byte, error) { + aux := auxOtherName{ + ID: o.TypeID.String(), + Value: o.Value.Bytes, + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (o *OtherName) UnmarshalJSON(b []byte) (err error) { + aux := auxOtherName{} + if err = json.Unmarshal(b, &aux); err != nil { + return + } + + // Turn dot-notation back into an OID + if len(aux.ID) == 0 { + return errors.New("empty type ID") + } + parts := strings.Split(aux.ID, ".") + o.TypeID = nil + for _, part := range parts { + i, err := strconv.Atoi(part) + if err != nil { + return err + } + o.TypeID = append(o.TypeID, i) + } + + // Build the ASN.1 value + o.Value = asn1.RawValue{ + Tag: 0, + Class: asn1.ClassContextSpecific, + IsCompound: true, + Bytes: aux.Value, + } + o.Value.FullBytes, err = asn1.Marshal(o.Value) + return +} + +type auxExtension struct { + ID string `json:"id,omitempty"` + Critical bool `json:"critical"` + Value []byte `json:"value,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (ext *Extension) MarshalJSON() ([]byte, error) { + aux := auxExtension{ + ID: ext.Id.String(), + Critical: ext.Critical, + Value: ext.Value, + } + return json.Marshal(&aux) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (ext *Extension) UnmarshalJSON(b []byte) (err error) { + aux := auxExtension{} + if err = json.Unmarshal(b, &aux); err != nil { + return + } + + parts := strings.Split(aux.ID, ".") + for _, part := range parts { + i, err := strconv.Atoi(part) + if err != nil { + return err + } + ext.Id = append(ext.Id, i) + } + ext.Critical = aux.Critical + ext.Value = aux.Value + return +} + +type auxName struct { + CommonName []string `json:"common_name,omitempty"` + SerialNumber []string `json:"serial_number,omitempty"` + Country []string `json:"country,omitempty"` + Locality []string `json:"locality,omitempty"` + Province []string `json:"province,omitempty"` + StreetAddress []string `json:"street_address,omitempty"` + Organization []string `json:"organization,omitempty"` + OrganizationalUnit []string `json:"organizational_unit,omitempty"` + PostalCode []string `json:"postal_code,omitempty"` + DomainComponent []string `json:"domain_component,omitempty"` + EmailAddress []string `json:"email_address,omitempty"` + GivenName []string `json:"given_name,omitempty"` + Surname []string `json:"surname,omitempty"` + // EV + JurisdictionCountry []string `json:"jurisdiction_country,omitempty"` + JurisdictionLocality []string `json:"jurisdiction_locality,omitempty"` + JurisdictionProvince []string `json:"jurisdiction_province,omitempty"` + + // QWACS + OrganizationID []string `json:"organization_id,omitempty"` + + UnknownAttributes []AttributeTypeAndValue `json:"-"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (n *Name) MarshalJSON() ([]byte, error) { + aux := auxName{} + attrs := n.ToRDNSequence() + for _, attrSet := range attrs { + for _, a := range attrSet { + s, ok := a.Value.(string) + if !ok { + continue + } + if a.Type.Equal(oidCommonName) { + aux.CommonName = append(aux.CommonName, s) + } else if a.Type.Equal(oidSurname) { + aux.Surname = append(aux.Surname, s) + } else if a.Type.Equal(oidSerialNumber) { + aux.SerialNumber = append(aux.SerialNumber, s) + } else if a.Type.Equal(oidCountry) { + aux.Country = append(aux.Country, s) + } else if a.Type.Equal(oidLocality) { + aux.Locality = append(aux.Locality, s) + } else if a.Type.Equal(oidProvince) { + aux.Province = append(aux.Province, s) + } else if a.Type.Equal(oidStreetAddress) { + aux.StreetAddress = append(aux.StreetAddress, s) + } else if a.Type.Equal(oidOrganization) { + aux.Organization = append(aux.Organization, s) + } else if a.Type.Equal(oidGivenName) { + aux.GivenName = append(aux.GivenName, s) + } else if a.Type.Equal(oidOrganizationalUnit) { + aux.OrganizationalUnit = append(aux.OrganizationalUnit, s) + } else if a.Type.Equal(oidPostalCode) { + aux.PostalCode = append(aux.PostalCode, s) + } else if a.Type.Equal(oidDomainComponent) { + aux.DomainComponent = append(aux.DomainComponent, s) + } else if a.Type.Equal(oidDNEmailAddress) { + aux.EmailAddress = append(aux.EmailAddress, s) + // EV + } else if a.Type.Equal(oidJurisdictionCountry) { + aux.JurisdictionCountry = append(aux.JurisdictionCountry, s) + } else if a.Type.Equal(oidJurisdictionLocality) { + aux.JurisdictionLocality = append(aux.JurisdictionLocality, s) + } else if a.Type.Equal(oidJurisdictionProvince) { + aux.JurisdictionProvince = append(aux.JurisdictionProvince, s) + } else if a.Type.Equal(oidOrganizationID) { + aux.OrganizationID = append(aux.OrganizationID, s) + } else { + aux.UnknownAttributes = append(aux.UnknownAttributes, a) + } + } + } + return json.Marshal(&aux) +} + +func appendATV(names []AttributeTypeAndValue, fieldVals []string, asn1Id asn1.ObjectIdentifier) []AttributeTypeAndValue { + if len(fieldVals) == 0 { + return names + } + + for _, val := range fieldVals { + names = append(names, AttributeTypeAndValue{Type: asn1Id, Value: val}) + } + + return names +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (n *Name) UnmarshalJSON(b []byte) error { + aux := auxName{} + if err := json.Unmarshal(b, &aux); err != nil { + return err + } + + // Populate Names as []AttributeTypeAndValue + n.Names = appendATV(n.Names, aux.Country, oidCountry) + n.Names = appendATV(n.Names, aux.Organization, oidOrganization) + n.Names = appendATV(n.Names, aux.OrganizationalUnit, oidOrganizationalUnit) + n.Names = appendATV(n.Names, aux.Locality, oidLocality) + n.Names = appendATV(n.Names, aux.Province, oidProvince) + n.Names = appendATV(n.Names, aux.StreetAddress, oidStreetAddress) + n.Names = appendATV(n.Names, aux.PostalCode, oidPostalCode) + n.Names = appendATV(n.Names, aux.DomainComponent, oidDomainComponent) + n.Names = appendATV(n.Names, aux.EmailAddress, oidDNEmailAddress) + // EV + n.Names = appendATV(n.Names, aux.JurisdictionCountry, oidJurisdictionCountry) + n.Names = appendATV(n.Names, aux.JurisdictionLocality, oidJurisdictionLocality) + n.Names = appendATV(n.Names, aux.JurisdictionProvince, oidJurisdictionProvince) + + n.Names = appendATV(n.Names, aux.CommonName, oidCommonName) + n.Names = appendATV(n.Names, aux.SerialNumber, oidSerialNumber) + + // Populate specific fields as []string + n.Country = aux.Country + n.Organization = aux.Organization + n.OrganizationalUnit = aux.OrganizationalUnit + n.Locality = aux.Locality + n.Province = aux.Province + n.StreetAddress = aux.StreetAddress + n.PostalCode = aux.PostalCode + n.DomainComponent = aux.DomainComponent + // EV + n.JurisdictionCountry = aux.JurisdictionCountry + n.JurisdictionLocality = aux.JurisdictionLocality + n.JurisdictionProvince = aux.JurisdictionProvince + + // CommonName and SerialNumber are not arrays. + if len(aux.CommonName) > 0 { + n.CommonName = aux.CommonName[0] + } + if len(aux.SerialNumber) > 0 { + n.SerialNumber = aux.SerialNumber[0] + } + + // Add "extra" commonNames and serialNumbers to ExtraNames. + if len(aux.CommonName) > 1 { + n.ExtraNames = appendATV(n.ExtraNames, aux.CommonName[1:], oidCommonName) + } + if len(aux.SerialNumber) > 1 { + n.ExtraNames = appendATV(n.ExtraNames, aux.SerialNumber[1:], oidSerialNumber) + } + + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkix/oid.go b/vendor/github.com/zmap/zcrypto/x509/pkix/oid.go new file mode 100644 index 0000000000..314ab7b587 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkix/oid.go @@ -0,0 +1,74 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkix + +import ( + "encoding/asn1" + "encoding/json" + "fmt" + "strconv" + "strings" +) + +// AuxOID behaves similar to asn1.ObjectIdentifier, except encodes to JSON as a +// string in dot notation. It is a type synonym for []int, and can be converted +// to an asn1.ObjectIdentifier by going through []int and back. +type AuxOID []int + +// AsSlice returns a slice over the inner-representation +func (aux *AuxOID) AsSlice() []int { + return *aux +} + +// CopyAsSlice returns a copy of the inter-representation as a slice +func (aux *AuxOID) CopyAsSlice() []int { + out := make([]int, len(*aux)) + copy(out, *aux) + return out +} + +// Equal tests (deep) equality of two AuxOIDs +func (aux *AuxOID) Equal(other *AuxOID) bool { + var a []int = *aux + var b []int = *other + if len(a) != len(b) { + return false + } + for idx := range a { + if a[idx] != b[idx] { + return false + } + } + return true +} + +// MarshalJSON implements the json.Marshaler interface +func (aux *AuxOID) MarshalJSON() ([]byte, error) { + var oid asn1.ObjectIdentifier + oid = []int(*aux) + return json.Marshal(oid.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface +func (aux *AuxOID) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + parts := strings.Split(s, ".") + if len(parts) < 1 { + return fmt.Errorf("Invalid OID string %s", s) + } + slice := make([]int, len(parts)) + for idx := range parts { + n, err := strconv.Atoi(parts[idx]) + if err != nil || n < 0 { + return fmt.Errorf("Invalid OID integer %s", parts[idx]) + } + slice[idx] = n + } + *aux = slice + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go b/vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go new file mode 100644 index 0000000000..1f396560f6 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go @@ -0,0 +1,1014 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkix + +// OIDName stores the short and long version of the name of an IANA-assigned OID +type OIDName struct { + ShortName string `json:"short_name"` + LongName string `json:"long_name"` +} + +var oidDotNotationToNames map[string]OIDName + +func init() { + oidDotNotationToNames = make(map[string]OIDName, 1024) + + oidDotNotationToNames["0.0"] = OIDName{ShortName: "UNDEF", LongName: "undefined"} + oidDotNotationToNames["1.2.840.113549"] = OIDName{ShortName: "rsadsi", LongName: "RSA Data Security"} + oidDotNotationToNames["1.2.840.113549.1"] = OIDName{ShortName: "pkcs", LongName: "RSA Data Security"} + oidDotNotationToNames["1.2.840.113549.2.2"] = OIDName{ShortName: "MD2", LongName: "md2"} + oidDotNotationToNames["1.2.840.113549.2.5"] = OIDName{ShortName: "MD5", LongName: "md5"} + oidDotNotationToNames["1.2.840.113549.3.4"] = OIDName{ShortName: "RC4", LongName: "rc4"} + oidDotNotationToNames["1.2.840.113549.1.1.1"] = OIDName{ShortName: "rsaEncryption", LongName: "rsaEncryption"} + oidDotNotationToNames["1.2.840.113549.1.1.2"] = OIDName{ShortName: "RSA-MD2", LongName: "md2WithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.1.1.4"] = OIDName{ShortName: "RSA-MD5", LongName: "md5WithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.1.5.1"] = OIDName{ShortName: "PBE-MD2-DES", LongName: "pbeWithMD2AndDES-CBC"} + oidDotNotationToNames["1.2.840.113549.1.5.3"] = OIDName{ShortName: "PBE-MD5-DES", LongName: "pbeWithMD5AndDES-CBC"} + oidDotNotationToNames["2.5"] = OIDName{ShortName: "X500", LongName: "directory services (X.500)"} + oidDotNotationToNames["2.5.4"] = OIDName{ShortName: "X509", LongName: "X509"} + oidDotNotationToNames["2.5.4.3"] = OIDName{ShortName: "CN", LongName: "commonName"} + oidDotNotationToNames["2.5.4.6"] = OIDName{ShortName: "C", LongName: "countryName"} + oidDotNotationToNames["2.5.4.7"] = OIDName{ShortName: "L", LongName: "localityName"} + oidDotNotationToNames["2.5.4.8"] = OIDName{ShortName: "ST", LongName: "stateOrProvinceName"} + oidDotNotationToNames["2.5.4.10"] = OIDName{ShortName: "O", LongName: "organizationName"} + oidDotNotationToNames["2.5.4.11"] = OIDName{ShortName: "OU", LongName: "organizationalUnitName"} + oidDotNotationToNames["2.5.4.97"] = OIDName{ShortName: "organizationIdentifier", LongName: "organizationIdentifier"} + oidDotNotationToNames["2.5.8.1.1"] = OIDName{ShortName: "RSA", LongName: "rsa"} + oidDotNotationToNames["1.2.840.113549.1.7"] = OIDName{ShortName: "pkcs7", LongName: "pkcs7"} + oidDotNotationToNames["1.2.840.113549.1.7.1"] = OIDName{ShortName: "pkcs7-data", LongName: "pkcs7-data"} + oidDotNotationToNames["1.2.840.113549.1.7.2"] = OIDName{ShortName: "pkcs7-signedData", LongName: "pkcs7-signedData"} + oidDotNotationToNames["1.2.840.113549.1.7.3"] = OIDName{ShortName: "pkcs7-envelopedData", LongName: "pkcs7-envelopedData"} + oidDotNotationToNames["1.2.840.113549.1.7.4"] = OIDName{ShortName: "pkcs7-signedAndEnvelopedData", LongName: "pkcs7-signedAndEnvelopedData"} + oidDotNotationToNames["1.2.840.113549.1.7.5"] = OIDName{ShortName: "pkcs7-digestData", LongName: "pkcs7-digestData"} + oidDotNotationToNames["1.2.840.113549.1.7.6"] = OIDName{ShortName: "pkcs7-encryptedData", LongName: "pkcs7-encryptedData"} + oidDotNotationToNames["1.2.840.113549.1.3"] = OIDName{ShortName: "pkcs3", LongName: "pkcs3"} + oidDotNotationToNames["1.2.840.113549.1.3.1"] = OIDName{ShortName: "dhKeyAgreement", LongName: "dhKeyAgreement"} + oidDotNotationToNames["1.3.14.3.2.6"] = OIDName{ShortName: "DES-ECB", LongName: "des-ecb"} + oidDotNotationToNames["1.3.14.3.2.9"] = OIDName{ShortName: "DES-CFB", LongName: "des-cfb"} + oidDotNotationToNames["1.3.14.3.2.7"] = OIDName{ShortName: "DES-CBC", LongName: "des-cbc"} + oidDotNotationToNames["1.3.14.3.2.17"] = OIDName{ShortName: "DES-EDE", LongName: "des-ede"} + oidDotNotationToNames["1.3.6.1.4.1.188.7.1.1.2"] = OIDName{ShortName: "IDEA-CBC", LongName: "idea-cbc"} + oidDotNotationToNames["1.2.840.113549.3.2"] = OIDName{ShortName: "RC2-CBC", LongName: "rc2-cbc"} + oidDotNotationToNames["1.3.14.3.2.18"] = OIDName{ShortName: "SHA", LongName: "sha"} + oidDotNotationToNames["1.3.14.3.2.15"] = OIDName{ShortName: "RSA-SHA", LongName: "shaWithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.3.7"] = OIDName{ShortName: "DES-EDE3-CBC", LongName: "des-ede3-cbc"} + oidDotNotationToNames["1.3.14.3.2.8"] = OIDName{ShortName: "DES-OFB", LongName: "des-ofb"} + oidDotNotationToNames["1.2.840.113549.1.9"] = OIDName{ShortName: "pkcs9", LongName: "pkcs9"} + oidDotNotationToNames["1.2.840.113549.1.9.1"] = OIDName{ShortName: "emailAddress", LongName: "emailAddress"} + oidDotNotationToNames["1.2.840.113549.1.9.2"] = OIDName{ShortName: "unstructuredName", LongName: "unstructuredName"} + oidDotNotationToNames["1.2.840.113549.1.9.3"] = OIDName{ShortName: "contentType", LongName: "contentType"} + oidDotNotationToNames["1.2.840.113549.1.9.4"] = OIDName{ShortName: "messageDigest", LongName: "messageDigest"} + oidDotNotationToNames["1.2.840.113549.1.9.5"] = OIDName{ShortName: "signingTime", LongName: "signingTime"} + oidDotNotationToNames["1.2.840.113549.1.9.6"] = OIDName{ShortName: "countersignature", LongName: "countersignature"} + oidDotNotationToNames["1.2.840.113549.1.9.7"] = OIDName{ShortName: "challengePassword", LongName: "challengePassword"} + oidDotNotationToNames["1.2.840.113549.1.9.8"] = OIDName{ShortName: "unstructuredAddress", LongName: "unstructuredAddress"} + oidDotNotationToNames["1.2.840.113549.1.9.9"] = OIDName{ShortName: "extendedCertificateAttributes", LongName: "extendedCertificateAttributes"} + oidDotNotationToNames["2.16.840.1.113730"] = OIDName{ShortName: "Netscape", LongName: "Netscape Communications Corp."} + oidDotNotationToNames["2.16.840.1.113730.1"] = OIDName{ShortName: "nsCertExt", LongName: "Netscape Certificate Extension"} + oidDotNotationToNames["2.16.840.1.113730.2"] = OIDName{ShortName: "nsDataType", LongName: "Netscape Data Type"} + oidDotNotationToNames["1.3.14.3.2.26"] = OIDName{ShortName: "SHA1", LongName: "sha1"} + oidDotNotationToNames["1.2.840.113549.1.1.5"] = OIDName{ShortName: "RSA-SHA1", LongName: "sha1WithRSAEncryption"} + oidDotNotationToNames["1.3.14.3.2.13"] = OIDName{ShortName: "DSA-SHA", LongName: "dsaWithSHA"} + oidDotNotationToNames["1.3.14.3.2.12"] = OIDName{ShortName: "DSA-old", LongName: "dsaEncryption-old"} + oidDotNotationToNames["1.2.840.113549.1.5.11"] = OIDName{ShortName: "PBE-SHA1-RC2-64", LongName: "pbeWithSHA1AndRC2-CBC"} + oidDotNotationToNames["1.2.840.113549.1.5.12"] = OIDName{ShortName: "PBKDF2", LongName: "PBKDF2"} + oidDotNotationToNames["1.3.14.3.2.27"] = OIDName{ShortName: "DSA-SHA1-old", LongName: "dsaWithSHA1-old"} + oidDotNotationToNames["2.16.840.1.113730.1.1"] = OIDName{ShortName: "nsCertType", LongName: "Netscape Cert Type"} + oidDotNotationToNames["2.16.840.1.113730.1.2"] = OIDName{ShortName: "nsBaseUrl", LongName: "Netscape Base Url"} + oidDotNotationToNames["2.16.840.1.113730.1.3"] = OIDName{ShortName: "nsRevocationUrl", LongName: "Netscape Revocation Url"} + oidDotNotationToNames["2.16.840.1.113730.1.4"] = OIDName{ShortName: "nsCaRevocationUrl", LongName: "Netscape CA Revocation Url"} + oidDotNotationToNames["2.16.840.1.113730.1.7"] = OIDName{ShortName: "nsRenewalUrl", LongName: "Netscape Renewal Url"} + oidDotNotationToNames["2.16.840.1.113730.1.8"] = OIDName{ShortName: "nsCaPolicyUrl", LongName: "Netscape CA Policy Url"} + oidDotNotationToNames["2.16.840.1.113730.1.12"] = OIDName{ShortName: "nsSslServerName", LongName: "Netscape SSL Server Name"} + oidDotNotationToNames["2.16.840.1.113730.1.13"] = OIDName{ShortName: "nsComment", LongName: "Netscape Comment"} + oidDotNotationToNames["2.16.840.1.113730.2.5"] = OIDName{ShortName: "nsCertSequence", LongName: "Netscape Certificate Sequence"} + oidDotNotationToNames["2.5.29"] = OIDName{ShortName: "id-ce", LongName: "id-ce"} + oidDotNotationToNames["2.5.29.14"] = OIDName{ShortName: "subjectKeyIdentifier", LongName: "X509v3 Subject Key Identifier"} + oidDotNotationToNames["2.5.29.15"] = OIDName{ShortName: "keyUsage", LongName: "X509v3 Key Usage"} + oidDotNotationToNames["2.5.29.16"] = OIDName{ShortName: "privateKeyUsagePeriod", LongName: "X509v3 Private Key Usage Period"} + oidDotNotationToNames["2.5.29.17"] = OIDName{ShortName: "subjectAltName", LongName: "X509v3 Subject Alternative Name"} + oidDotNotationToNames["2.5.29.18"] = OIDName{ShortName: "issuerAltName", LongName: "X509v3 Issuer Alternative Name"} + oidDotNotationToNames["2.5.29.19"] = OIDName{ShortName: "basicConstraints", LongName: "X509v3 Basic Constraints"} + oidDotNotationToNames["2.5.29.20"] = OIDName{ShortName: "crlNumber", LongName: "X509v3 CRL Number"} + oidDotNotationToNames["2.5.29.32"] = OIDName{ShortName: "certificatePolicies", LongName: "X509v3 Certificate Policies"} + oidDotNotationToNames["2.5.29.35"] = OIDName{ShortName: "authorityKeyIdentifier", LongName: "X509v3 Authority Key Identifier"} + oidDotNotationToNames["1.3.6.1.4.1.3029.1.2"] = OIDName{ShortName: "BF-CBC", LongName: "bf-cbc"} + oidDotNotationToNames["2.5.8.3.101"] = OIDName{ShortName: "MDC2", LongName: "mdc2"} + oidDotNotationToNames["2.5.8.3.100"] = OIDName{ShortName: "RSA-MDC2", LongName: "mdc2WithRSA"} + oidDotNotationToNames["2.5.4.42"] = OIDName{ShortName: "GN", LongName: "givenName"} + oidDotNotationToNames["2.5.4.4"] = OIDName{ShortName: "SN", LongName: "surname"} + oidDotNotationToNames["2.5.4.43"] = OIDName{ShortName: "initials", LongName: "initials"} + oidDotNotationToNames["2.5.29.31"] = OIDName{ShortName: "crlDistributionPoints", LongName: "X509v3 CRL Distribution Points"} + oidDotNotationToNames["1.3.14.3.2.3"] = OIDName{ShortName: "RSA-NP-MD5", LongName: "md5WithRSA"} + oidDotNotationToNames["2.5.4.5"] = OIDName{ShortName: "serialNumber", LongName: "serialNumber"} + oidDotNotationToNames["2.5.4.12"] = OIDName{ShortName: "title", LongName: "title"} + oidDotNotationToNames["2.5.4.13"] = OIDName{ShortName: "description", LongName: "description"} + oidDotNotationToNames["1.2.840.113533.7.66.10"] = OIDName{ShortName: "CAST5-CBC", LongName: "cast5-cbc"} + oidDotNotationToNames["1.2.840.113533.7.66.12"] = OIDName{ShortName: "pbeWithMD5AndCast5CBC", LongName: "pbeWithMD5AndCast5CBC"} + oidDotNotationToNames["1.2.840.10040.4.3"] = OIDName{ShortName: "DSA-SHA1", LongName: "dsaWithSHA1"} + oidDotNotationToNames["1.3.14.3.2.29"] = OIDName{ShortName: "RSA-SHA1-2", LongName: "sha1WithRSA"} + oidDotNotationToNames["1.2.840.10040.4.1"] = OIDName{ShortName: "DSA", LongName: "dsaEncryption"} + oidDotNotationToNames["1.3.36.3.2.1"] = OIDName{ShortName: "RIPEMD160", LongName: "ripemd160"} + oidDotNotationToNames["1.3.36.3.3.1.2"] = OIDName{ShortName: "RSA-RIPEMD160", LongName: "ripemd160WithRSA"} + oidDotNotationToNames["1.2.840.113549.3.8"] = OIDName{ShortName: "RC5-CBC", LongName: "rc5-cbc"} + oidDotNotationToNames["1.1.1.1.666.1"] = OIDName{ShortName: "RLE", LongName: "run length compression"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.8"] = OIDName{ShortName: "ZLIB", LongName: "zlib compression"} + oidDotNotationToNames["2.5.29.37"] = OIDName{ShortName: "extendedKeyUsage", LongName: "X509v3 Extended Key Usage"} + oidDotNotationToNames["1.3.6.1.5.5.7"] = OIDName{ShortName: "PKIX", LongName: "PKIX"} + oidDotNotationToNames["1.3.6.1.5.5.7.3"] = OIDName{ShortName: "id-kp", LongName: "id-kp"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.1"] = OIDName{ShortName: "serverAuth", LongName: "TLS Web Server Authentication"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.2"] = OIDName{ShortName: "clientAuth", LongName: "TLS Web Client Authentication"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.3"] = OIDName{ShortName: "codeSigning", LongName: "Code Signing"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.4"] = OIDName{ShortName: "emailProtection", LongName: "E-mail Protection"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.8"] = OIDName{ShortName: "timeStamping", LongName: "Time Stamping"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.21"] = OIDName{ShortName: "msCodeInd", LongName: "Microsoft Individual Code Signing"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.22"] = OIDName{ShortName: "msCodeCom", LongName: "Microsoft Commercial Code Signing"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.1"] = OIDName{ShortName: "msCTLSign", LongName: "Microsoft Trust List Signing"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.3"] = OIDName{ShortName: "msSGC", LongName: "Microsoft Server Gated Crypto"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.4"] = OIDName{ShortName: "msEFS", LongName: "Microsoft Encrypted File System"} + oidDotNotationToNames["2.16.840.1.113730.4.1"] = OIDName{ShortName: "nsSGC", LongName: "Netscape Server Gated Crypto"} + oidDotNotationToNames["2.5.29.27"] = OIDName{ShortName: "deltaCRL", LongName: "X509v3 Delta CRL Indicator"} + oidDotNotationToNames["2.5.29.21"] = OIDName{ShortName: "CRLReason", LongName: "X509v3 CRL Reason Code"} + oidDotNotationToNames["2.5.29.24"] = OIDName{ShortName: "invalidityDate", LongName: "Invalidity Date"} + oidDotNotationToNames["1.3.101.1.4.1"] = OIDName{ShortName: "SXNetID", LongName: "Strong Extranet ID"} + oidDotNotationToNames["1.2.840.113549.1.12.1.1"] = OIDName{ShortName: "PBE-SHA1-RC4-128", LongName: "pbeWithSHA1And128BitRC4"} + oidDotNotationToNames["1.2.840.113549.1.12.1.2"] = OIDName{ShortName: "PBE-SHA1-RC4-40", LongName: "pbeWithSHA1And40BitRC4"} + oidDotNotationToNames["1.2.840.113549.1.12.1.3"] = OIDName{ShortName: "PBE-SHA1-3DES", LongName: "pbeWithSHA1And3-KeyTripleDES-CBC"} + oidDotNotationToNames["1.2.840.113549.1.12.1.4"] = OIDName{ShortName: "PBE-SHA1-2DES", LongName: "pbeWithSHA1And2-KeyTripleDES-CBC"} + oidDotNotationToNames["1.2.840.113549.1.12.1.5"] = OIDName{ShortName: "PBE-SHA1-RC2-128", LongName: "pbeWithSHA1And128BitRC2-CBC"} + oidDotNotationToNames["1.2.840.113549.1.12.1.6"] = OIDName{ShortName: "PBE-SHA1-RC2-40", LongName: "pbeWithSHA1And40BitRC2-CBC"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.1"] = OIDName{ShortName: "keyBag", LongName: "keyBag"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.2"] = OIDName{ShortName: "pkcs8ShroudedKeyBag", LongName: "pkcs8ShroudedKeyBag"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.3"] = OIDName{ShortName: "certBag", LongName: "certBag"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.4"] = OIDName{ShortName: "crlBag", LongName: "crlBag"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.5"] = OIDName{ShortName: "secretBag", LongName: "secretBag"} + oidDotNotationToNames["1.2.840.113549.1.12.10.1.6"] = OIDName{ShortName: "safeContentsBag", LongName: "safeContentsBag"} + oidDotNotationToNames["1.2.840.113549.1.9.20"] = OIDName{ShortName: "friendlyName", LongName: "friendlyName"} + oidDotNotationToNames["1.2.840.113549.1.9.21"] = OIDName{ShortName: "localKeyID", LongName: "localKeyID"} + oidDotNotationToNames["1.2.840.113549.1.9.22.1"] = OIDName{ShortName: "x509Certificate", LongName: "x509Certificate"} + oidDotNotationToNames["1.2.840.113549.1.9.22.2"] = OIDName{ShortName: "sdsiCertificate", LongName: "sdsiCertificate"} + oidDotNotationToNames["1.2.840.113549.1.9.23.1"] = OIDName{ShortName: "x509Crl", LongName: "x509Crl"} + oidDotNotationToNames["1.2.840.113549.1.5.13"] = OIDName{ShortName: "PBES2", LongName: "PBES2"} + oidDotNotationToNames["1.2.840.113549.1.5.14"] = OIDName{ShortName: "PBMAC1", LongName: "PBMAC1"} + oidDotNotationToNames["1.2.840.113549.2.7"] = OIDName{ShortName: "hmacWithSHA1", LongName: "hmacWithSHA1"} + oidDotNotationToNames["1.3.6.1.5.5.7.2.1"] = OIDName{ShortName: "id-qt-cps", LongName: "Policy Qualifier CPS"} + oidDotNotationToNames["1.3.6.1.5.5.7.2.2"] = OIDName{ShortName: "id-qt-unotice", LongName: "Policy Qualifier User Notice"} + oidDotNotationToNames["1.2.840.113549.1.9.15"] = OIDName{ShortName: "SMIME-CAPS", LongName: "S/MIME Capabilities"} + oidDotNotationToNames["1.2.840.113549.1.5.4"] = OIDName{ShortName: "PBE-MD2-RC2-64", LongName: "pbeWithMD2AndRC2-CBC"} + oidDotNotationToNames["1.2.840.113549.1.5.6"] = OIDName{ShortName: "PBE-MD5-RC2-64", LongName: "pbeWithMD5AndRC2-CBC"} + oidDotNotationToNames["1.2.840.113549.1.5.10"] = OIDName{ShortName: "PBE-SHA1-DES", LongName: "pbeWithSHA1AndDES-CBC"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.14"] = OIDName{ShortName: "msExtReq", LongName: "Microsoft Extension Request"} + oidDotNotationToNames["1.2.840.113549.1.9.14"] = OIDName{ShortName: "extReq", LongName: "Extension Request"} + oidDotNotationToNames["2.5.4.41"] = OIDName{ShortName: "name", LongName: "name"} + oidDotNotationToNames["2.5.4.46"] = OIDName{ShortName: "dnQualifier", LongName: "dnQualifier"} + oidDotNotationToNames["1.3.6.1.5.5.7.1"] = OIDName{ShortName: "id-pe", LongName: "id-pe"} + oidDotNotationToNames["1.3.6.1.5.5.7.48"] = OIDName{ShortName: "id-ad", LongName: "id-ad"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.1"] = OIDName{ShortName: "authorityInfoAccess", LongName: "Authority Information Access"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1"] = OIDName{ShortName: "OCSP", LongName: "OCSP"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.2"] = OIDName{ShortName: "caIssuers", LongName: "CA Issuers"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.9"] = OIDName{ShortName: "OCSPSigning", LongName: "OCSP Signing"} + oidDotNotationToNames["1.0"] = OIDName{ShortName: "ISO", LongName: "iso"} + oidDotNotationToNames["1.2"] = OIDName{ShortName: "member-body", LongName: "ISO Member Body"} + oidDotNotationToNames["1.2.840"] = OIDName{ShortName: "ISO-US", LongName: "ISO US Member Body"} + oidDotNotationToNames["1.2.840.10040"] = OIDName{ShortName: "X9-57", LongName: "X9.57"} + oidDotNotationToNames["1.2.840.10040.4"] = OIDName{ShortName: "X9cm", LongName: "X9.57 CM ?"} + oidDotNotationToNames["1.2.840.113549.1.1"] = OIDName{ShortName: "pkcs1", LongName: "pkcs1"} + oidDotNotationToNames["1.2.840.113549.1.5"] = OIDName{ShortName: "pkcs5", LongName: "pkcs5"} + oidDotNotationToNames["1.2.840.113549.1.9.16"] = OIDName{ShortName: "SMIME", LongName: "S/MIME"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0"] = OIDName{ShortName: "id-smime-mod", LongName: "id-smime-mod"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1"] = OIDName{ShortName: "id-smime-ct", LongName: "id-smime-ct"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2"] = OIDName{ShortName: "id-smime-aa", LongName: "id-smime-aa"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3"] = OIDName{ShortName: "id-smime-alg", LongName: "id-smime-alg"} + oidDotNotationToNames["1.2.840.113549.1.9.16.4"] = OIDName{ShortName: "id-smime-cd", LongName: "id-smime-cd"} + oidDotNotationToNames["1.2.840.113549.1.9.16.5"] = OIDName{ShortName: "id-smime-spq", LongName: "id-smime-spq"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6"] = OIDName{ShortName: "id-smime-cti", LongName: "id-smime-cti"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.1"] = OIDName{ShortName: "id-smime-mod-cms", LongName: "id-smime-mod-cms"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.2"] = OIDName{ShortName: "id-smime-mod-ess", LongName: "id-smime-mod-ess"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.3"] = OIDName{ShortName: "id-smime-mod-oid", LongName: "id-smime-mod-oid"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.4"] = OIDName{ShortName: "id-smime-mod-msg-v3", LongName: "id-smime-mod-msg-v3"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.5"] = OIDName{ShortName: "id-smime-mod-ets-eSignature-88", LongName: "id-smime-mod-ets-eSignature-88"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.6"] = OIDName{ShortName: "id-smime-mod-ets-eSignature-97", LongName: "id-smime-mod-ets-eSignature-97"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.7"] = OIDName{ShortName: "id-smime-mod-ets-eSigPolicy-88", LongName: "id-smime-mod-ets-eSigPolicy-88"} + oidDotNotationToNames["1.2.840.113549.1.9.16.0.8"] = OIDName{ShortName: "id-smime-mod-ets-eSigPolicy-97", LongName: "id-smime-mod-ets-eSigPolicy-97"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.1"] = OIDName{ShortName: "id-smime-ct-receipt", LongName: "id-smime-ct-receipt"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.2"] = OIDName{ShortName: "id-smime-ct-authData", LongName: "id-smime-ct-authData"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.3"] = OIDName{ShortName: "id-smime-ct-publishCert", LongName: "id-smime-ct-publishCert"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.4"] = OIDName{ShortName: "id-smime-ct-TSTInfo", LongName: "id-smime-ct-TSTInfo"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.5"] = OIDName{ShortName: "id-smime-ct-TDTInfo", LongName: "id-smime-ct-TDTInfo"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.6"] = OIDName{ShortName: "id-smime-ct-contentInfo", LongName: "id-smime-ct-contentInfo"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.7"] = OIDName{ShortName: "id-smime-ct-DVCSRequestData", LongName: "id-smime-ct-DVCSRequestData"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.8"] = OIDName{ShortName: "id-smime-ct-DVCSResponseData", LongName: "id-smime-ct-DVCSResponseData"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.1"] = OIDName{ShortName: "id-smime-aa-receiptRequest", LongName: "id-smime-aa-receiptRequest"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.2"] = OIDName{ShortName: "id-smime-aa-securityLabel", LongName: "id-smime-aa-securityLabel"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.3"] = OIDName{ShortName: "id-smime-aa-mlExpandHistory", LongName: "id-smime-aa-mlExpandHistory"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.4"] = OIDName{ShortName: "id-smime-aa-contentHint", LongName: "id-smime-aa-contentHint"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.5"] = OIDName{ShortName: "id-smime-aa-msgSigDigest", LongName: "id-smime-aa-msgSigDigest"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.6"] = OIDName{ShortName: "id-smime-aa-encapContentType", LongName: "id-smime-aa-encapContentType"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.7"] = OIDName{ShortName: "id-smime-aa-contentIdentifier", LongName: "id-smime-aa-contentIdentifier"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.8"] = OIDName{ShortName: "id-smime-aa-macValue", LongName: "id-smime-aa-macValue"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.9"] = OIDName{ShortName: "id-smime-aa-equivalentLabels", LongName: "id-smime-aa-equivalentLabels"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.10"] = OIDName{ShortName: "id-smime-aa-contentReference", LongName: "id-smime-aa-contentReference"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.11"] = OIDName{ShortName: "id-smime-aa-encrypKeyPref", LongName: "id-smime-aa-encrypKeyPref"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.12"] = OIDName{ShortName: "id-smime-aa-signingCertificate", LongName: "id-smime-aa-signingCertificate"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.13"] = OIDName{ShortName: "id-smime-aa-smimeEncryptCerts", LongName: "id-smime-aa-smimeEncryptCerts"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.14"] = OIDName{ShortName: "id-smime-aa-timeStampToken", LongName: "id-smime-aa-timeStampToken"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.15"] = OIDName{ShortName: "id-smime-aa-ets-sigPolicyId", LongName: "id-smime-aa-ets-sigPolicyId"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.16"] = OIDName{ShortName: "id-smime-aa-ets-commitmentType", LongName: "id-smime-aa-ets-commitmentType"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.17"] = OIDName{ShortName: "id-smime-aa-ets-signerLocation", LongName: "id-smime-aa-ets-signerLocation"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.18"] = OIDName{ShortName: "id-smime-aa-ets-signerAttr", LongName: "id-smime-aa-ets-signerAttr"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.19"] = OIDName{ShortName: "id-smime-aa-ets-otherSigCert", LongName: "id-smime-aa-ets-otherSigCert"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.20"] = OIDName{ShortName: "id-smime-aa-ets-contentTimestamp", LongName: "id-smime-aa-ets-contentTimestamp"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.21"] = OIDName{ShortName: "id-smime-aa-ets-CertificateRefs", LongName: "id-smime-aa-ets-CertificateRefs"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.22"] = OIDName{ShortName: "id-smime-aa-ets-RevocationRefs", LongName: "id-smime-aa-ets-RevocationRefs"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.23"] = OIDName{ShortName: "id-smime-aa-ets-certValues", LongName: "id-smime-aa-ets-certValues"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.24"] = OIDName{ShortName: "id-smime-aa-ets-revocationValues", LongName: "id-smime-aa-ets-revocationValues"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.25"] = OIDName{ShortName: "id-smime-aa-ets-escTimeStamp", LongName: "id-smime-aa-ets-escTimeStamp"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.26"] = OIDName{ShortName: "id-smime-aa-ets-certCRLTimestamp", LongName: "id-smime-aa-ets-certCRLTimestamp"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.27"] = OIDName{ShortName: "id-smime-aa-ets-archiveTimeStamp", LongName: "id-smime-aa-ets-archiveTimeStamp"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.28"] = OIDName{ShortName: "id-smime-aa-signatureType", LongName: "id-smime-aa-signatureType"} + oidDotNotationToNames["1.2.840.113549.1.9.16.2.29"] = OIDName{ShortName: "id-smime-aa-dvcs-dvc", LongName: "id-smime-aa-dvcs-dvc"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.1"] = OIDName{ShortName: "id-smime-alg-ESDHwith3DES", LongName: "id-smime-alg-ESDHwith3DES"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.2"] = OIDName{ShortName: "id-smime-alg-ESDHwithRC2", LongName: "id-smime-alg-ESDHwithRC2"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.3"] = OIDName{ShortName: "id-smime-alg-3DESwrap", LongName: "id-smime-alg-3DESwrap"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.4"] = OIDName{ShortName: "id-smime-alg-RC2wrap", LongName: "id-smime-alg-RC2wrap"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.5"] = OIDName{ShortName: "id-smime-alg-ESDH", LongName: "id-smime-alg-ESDH"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.6"] = OIDName{ShortName: "id-smime-alg-CMS3DESwrap", LongName: "id-smime-alg-CMS3DESwrap"} + oidDotNotationToNames["1.2.840.113549.1.9.16.3.7"] = OIDName{ShortName: "id-smime-alg-CMSRC2wrap", LongName: "id-smime-alg-CMSRC2wrap"} + oidDotNotationToNames["1.2.840.113549.1.9.16.4.1"] = OIDName{ShortName: "id-smime-cd-ldap", LongName: "id-smime-cd-ldap"} + oidDotNotationToNames["1.2.840.113549.1.9.16.5.1"] = OIDName{ShortName: "id-smime-spq-ets-sqt-uri", LongName: "id-smime-spq-ets-sqt-uri"} + oidDotNotationToNames["1.2.840.113549.1.9.16.5.2"] = OIDName{ShortName: "id-smime-spq-ets-sqt-unotice", LongName: "id-smime-spq-ets-sqt-unotice"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.1"] = OIDName{ShortName: "id-smime-cti-ets-proofOfOrigin", LongName: "id-smime-cti-ets-proofOfOrigin"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.2"] = OIDName{ShortName: "id-smime-cti-ets-proofOfReceipt", LongName: "id-smime-cti-ets-proofOfReceipt"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.3"] = OIDName{ShortName: "id-smime-cti-ets-proofOfDelivery", LongName: "id-smime-cti-ets-proofOfDelivery"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.4"] = OIDName{ShortName: "id-smime-cti-ets-proofOfSender", LongName: "id-smime-cti-ets-proofOfSender"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.5"] = OIDName{ShortName: "id-smime-cti-ets-proofOfApproval", LongName: "id-smime-cti-ets-proofOfApproval"} + oidDotNotationToNames["1.2.840.113549.1.9.16.6.6"] = OIDName{ShortName: "id-smime-cti-ets-proofOfCreation", LongName: "id-smime-cti-ets-proofOfCreation"} + oidDotNotationToNames["1.2.840.113549.2.4"] = OIDName{ShortName: "MD4", LongName: "md4"} + oidDotNotationToNames["1.3.6.1.5.5.7.0"] = OIDName{ShortName: "id-pkix-mod", LongName: "id-pkix-mod"} + oidDotNotationToNames["1.3.6.1.5.5.7.2"] = OIDName{ShortName: "id-qt", LongName: "id-qt"} + oidDotNotationToNames["1.3.6.1.5.5.7.4"] = OIDName{ShortName: "id-it", LongName: "id-it"} + oidDotNotationToNames["1.3.6.1.5.5.7.5"] = OIDName{ShortName: "id-pkip", LongName: "id-pkip"} + oidDotNotationToNames["1.3.6.1.5.5.7.6"] = OIDName{ShortName: "id-alg", LongName: "id-alg"} + oidDotNotationToNames["1.3.6.1.5.5.7.7"] = OIDName{ShortName: "id-cmc", LongName: "id-cmc"} + oidDotNotationToNames["1.3.6.1.5.5.7.8"] = OIDName{ShortName: "id-on", LongName: "id-on"} + oidDotNotationToNames["1.3.6.1.5.5.7.9"] = OIDName{ShortName: "id-pda", LongName: "id-pda"} + oidDotNotationToNames["1.3.6.1.5.5.7.10"] = OIDName{ShortName: "id-aca", LongName: "id-aca"} + oidDotNotationToNames["1.3.6.1.5.5.7.11"] = OIDName{ShortName: "id-qcs", LongName: "id-qcs"} + oidDotNotationToNames["1.3.6.1.5.5.7.12"] = OIDName{ShortName: "id-cct", LongName: "id-cct"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.1"] = OIDName{ShortName: "id-pkix1-explicit-88", LongName: "id-pkix1-explicit-88"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.2"] = OIDName{ShortName: "id-pkix1-implicit-88", LongName: "id-pkix1-implicit-88"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.3"] = OIDName{ShortName: "id-pkix1-explicit-93", LongName: "id-pkix1-explicit-93"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.4"] = OIDName{ShortName: "id-pkix1-implicit-93", LongName: "id-pkix1-implicit-93"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.5"] = OIDName{ShortName: "id-mod-crmf", LongName: "id-mod-crmf"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.6"] = OIDName{ShortName: "id-mod-cmc", LongName: "id-mod-cmc"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.7"] = OIDName{ShortName: "id-mod-kea-profile-88", LongName: "id-mod-kea-profile-88"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.8"] = OIDName{ShortName: "id-mod-kea-profile-93", LongName: "id-mod-kea-profile-93"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.9"] = OIDName{ShortName: "id-mod-cmp", LongName: "id-mod-cmp"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.10"] = OIDName{ShortName: "id-mod-qualified-cert-88", LongName: "id-mod-qualified-cert-88"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.11"] = OIDName{ShortName: "id-mod-qualified-cert-93", LongName: "id-mod-qualified-cert-93"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.12"] = OIDName{ShortName: "id-mod-attribute-cert", LongName: "id-mod-attribute-cert"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.13"] = OIDName{ShortName: "id-mod-timestamp-protocol", LongName: "id-mod-timestamp-protocol"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.14"] = OIDName{ShortName: "id-mod-ocsp", LongName: "id-mod-ocsp"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.15"] = OIDName{ShortName: "id-mod-dvcs", LongName: "id-mod-dvcs"} + oidDotNotationToNames["1.3.6.1.5.5.7.0.16"] = OIDName{ShortName: "id-mod-cmp2000", LongName: "id-mod-cmp2000"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.2"] = OIDName{ShortName: "biometricInfo", LongName: "Biometric Info"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.3"] = OIDName{ShortName: "qcStatements", LongName: "qcStatements"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.4"] = OIDName{ShortName: "ac-auditEntity", LongName: "ac-auditEntity"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.5"] = OIDName{ShortName: "ac-targeting", LongName: "ac-targeting"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.6"] = OIDName{ShortName: "aaControls", LongName: "aaControls"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.7"] = OIDName{ShortName: "sbgp-ipAddrBlock", LongName: "sbgp-ipAddrBlock"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.8"] = OIDName{ShortName: "sbgp-autonomousSysNum", LongName: "sbgp-autonomousSysNum"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.9"] = OIDName{ShortName: "sbgp-routerIdentifier", LongName: "sbgp-routerIdentifier"} + oidDotNotationToNames["1.3.6.1.5.5.7.2.3"] = OIDName{ShortName: "textNotice", LongName: "textNotice"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.5"] = OIDName{ShortName: "ipsecEndSystem", LongName: "IPSec End System"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.6"] = OIDName{ShortName: "ipsecTunnel", LongName: "IPSec Tunnel"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.7"] = OIDName{ShortName: "ipsecUser", LongName: "IPSec User"} + oidDotNotationToNames["1.3.6.1.5.5.7.3.10"] = OIDName{ShortName: "DVCS", LongName: "dvcs"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.1"] = OIDName{ShortName: "id-it-caProtEncCert", LongName: "id-it-caProtEncCert"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.2"] = OIDName{ShortName: "id-it-signKeyPairTypes", LongName: "id-it-signKeyPairTypes"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.3"] = OIDName{ShortName: "id-it-encKeyPairTypes", LongName: "id-it-encKeyPairTypes"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.4"] = OIDName{ShortName: "id-it-preferredSymmAlg", LongName: "id-it-preferredSymmAlg"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.5"] = OIDName{ShortName: "id-it-caKeyUpdateInfo", LongName: "id-it-caKeyUpdateInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.6"] = OIDName{ShortName: "id-it-currentCRL", LongName: "id-it-currentCRL"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.7"] = OIDName{ShortName: "id-it-unsupportedOIDs", LongName: "id-it-unsupportedOIDs"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.8"] = OIDName{ShortName: "id-it-subscriptionRequest", LongName: "id-it-subscriptionRequest"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.9"] = OIDName{ShortName: "id-it-subscriptionResponse", LongName: "id-it-subscriptionResponse"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.10"] = OIDName{ShortName: "id-it-keyPairParamReq", LongName: "id-it-keyPairParamReq"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.11"] = OIDName{ShortName: "id-it-keyPairParamRep", LongName: "id-it-keyPairParamRep"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.12"] = OIDName{ShortName: "id-it-revPassphrase", LongName: "id-it-revPassphrase"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.13"] = OIDName{ShortName: "id-it-implicitConfirm", LongName: "id-it-implicitConfirm"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.14"] = OIDName{ShortName: "id-it-confirmWaitTime", LongName: "id-it-confirmWaitTime"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.15"] = OIDName{ShortName: "id-it-origPKIMessage", LongName: "id-it-origPKIMessage"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1"] = OIDName{ShortName: "id-regCtrl", LongName: "id-regCtrl"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.2"] = OIDName{ShortName: "id-regInfo", LongName: "id-regInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.1"] = OIDName{ShortName: "id-regCtrl-regToken", LongName: "id-regCtrl-regToken"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.2"] = OIDName{ShortName: "id-regCtrl-authenticator", LongName: "id-regCtrl-authenticator"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.3"] = OIDName{ShortName: "id-regCtrl-pkiPublicationInfo", LongName: "id-regCtrl-pkiPublicationInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.4"] = OIDName{ShortName: "id-regCtrl-pkiArchiveOptions", LongName: "id-regCtrl-pkiArchiveOptions"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.5"] = OIDName{ShortName: "id-regCtrl-oldCertID", LongName: "id-regCtrl-oldCertID"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.1.6"] = OIDName{ShortName: "id-regCtrl-protocolEncrKey", LongName: "id-regCtrl-protocolEncrKey"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.2.1"] = OIDName{ShortName: "id-regInfo-utf8Pairs", LongName: "id-regInfo-utf8Pairs"} + oidDotNotationToNames["1.3.6.1.5.5.7.5.2.2"] = OIDName{ShortName: "id-regInfo-certReq", LongName: "id-regInfo-certReq"} + oidDotNotationToNames["1.3.6.1.5.5.7.6.1"] = OIDName{ShortName: "id-alg-des40", LongName: "id-alg-des40"} + oidDotNotationToNames["1.3.6.1.5.5.7.6.2"] = OIDName{ShortName: "id-alg-noSignature", LongName: "id-alg-noSignature"} + oidDotNotationToNames["1.3.6.1.5.5.7.6.3"] = OIDName{ShortName: "id-alg-dh-sig-hmac-sha1", LongName: "id-alg-dh-sig-hmac-sha1"} + oidDotNotationToNames["1.3.6.1.5.5.7.6.4"] = OIDName{ShortName: "id-alg-dh-pop", LongName: "id-alg-dh-pop"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.1"] = OIDName{ShortName: "id-cmc-statusInfo", LongName: "id-cmc-statusInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.2"] = OIDName{ShortName: "id-cmc-identification", LongName: "id-cmc-identification"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.3"] = OIDName{ShortName: "id-cmc-identityProof", LongName: "id-cmc-identityProof"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.4"] = OIDName{ShortName: "id-cmc-dataReturn", LongName: "id-cmc-dataReturn"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.5"] = OIDName{ShortName: "id-cmc-transactionId", LongName: "id-cmc-transactionId"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.6"] = OIDName{ShortName: "id-cmc-senderNonce", LongName: "id-cmc-senderNonce"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.7"] = OIDName{ShortName: "id-cmc-recipientNonce", LongName: "id-cmc-recipientNonce"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.8"] = OIDName{ShortName: "id-cmc-addExtensions", LongName: "id-cmc-addExtensions"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.9"] = OIDName{ShortName: "id-cmc-encryptedPOP", LongName: "id-cmc-encryptedPOP"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.10"] = OIDName{ShortName: "id-cmc-decryptedPOP", LongName: "id-cmc-decryptedPOP"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.11"] = OIDName{ShortName: "id-cmc-lraPOPWitness", LongName: "id-cmc-lraPOPWitness"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.15"] = OIDName{ShortName: "id-cmc-getCert", LongName: "id-cmc-getCert"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.16"] = OIDName{ShortName: "id-cmc-getCRL", LongName: "id-cmc-getCRL"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.17"] = OIDName{ShortName: "id-cmc-revokeRequest", LongName: "id-cmc-revokeRequest"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.18"] = OIDName{ShortName: "id-cmc-regInfo", LongName: "id-cmc-regInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.19"] = OIDName{ShortName: "id-cmc-responseInfo", LongName: "id-cmc-responseInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.21"] = OIDName{ShortName: "id-cmc-queryPending", LongName: "id-cmc-queryPending"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.22"] = OIDName{ShortName: "id-cmc-popLinkRandom", LongName: "id-cmc-popLinkRandom"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.23"] = OIDName{ShortName: "id-cmc-popLinkWitness", LongName: "id-cmc-popLinkWitness"} + oidDotNotationToNames["1.3.6.1.5.5.7.7.24"] = OIDName{ShortName: "id-cmc-confirmCertAcceptance", LongName: "id-cmc-confirmCertAcceptance"} + oidDotNotationToNames["1.3.6.1.5.5.7.8.1"] = OIDName{ShortName: "id-on-personalData", LongName: "id-on-personalData"} + oidDotNotationToNames["1.3.6.1.5.5.7.9.1"] = OIDName{ShortName: "id-pda-dateOfBirth", LongName: "id-pda-dateOfBirth"} + oidDotNotationToNames["1.3.6.1.5.5.7.9.2"] = OIDName{ShortName: "id-pda-placeOfBirth", LongName: "id-pda-placeOfBirth"} + oidDotNotationToNames["1.3.6.1.5.5.7.9.3"] = OIDName{ShortName: "id-pda-gender", LongName: "id-pda-gender"} + oidDotNotationToNames["1.3.6.1.5.5.7.9.4"] = OIDName{ShortName: "id-pda-countryOfCitizenship", LongName: "id-pda-countryOfCitizenship"} + oidDotNotationToNames["1.3.6.1.5.5.7.9.5"] = OIDName{ShortName: "id-pda-countryOfResidence", LongName: "id-pda-countryOfResidence"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.1"] = OIDName{ShortName: "id-aca-authenticationInfo", LongName: "id-aca-authenticationInfo"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.2"] = OIDName{ShortName: "id-aca-accessIdentity", LongName: "id-aca-accessIdentity"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.3"] = OIDName{ShortName: "id-aca-chargingIdentity", LongName: "id-aca-chargingIdentity"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.4"] = OIDName{ShortName: "id-aca-group", LongName: "id-aca-group"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.5"] = OIDName{ShortName: "id-aca-role", LongName: "id-aca-role"} + oidDotNotationToNames["1.3.6.1.5.5.7.11.1"] = OIDName{ShortName: "id-qcs-pkixQCSyntax-v1", LongName: "id-qcs-pkixQCSyntax-v1"} + oidDotNotationToNames["1.3.6.1.5.5.7.12.1"] = OIDName{ShortName: "id-cct-crs", LongName: "id-cct-crs"} + oidDotNotationToNames["1.3.6.1.5.5.7.12.2"] = OIDName{ShortName: "id-cct-PKIData", LongName: "id-cct-PKIData"} + oidDotNotationToNames["1.3.6.1.5.5.7.12.3"] = OIDName{ShortName: "id-cct-PKIResponse", LongName: "id-cct-PKIResponse"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.3"] = OIDName{ShortName: "ad_timestamping", LongName: "AD Time Stamping"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.4"] = OIDName{ShortName: "AD_DVCS", LongName: "ad dvcs"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.1"] = OIDName{ShortName: "basicOCSPResponse", LongName: "Basic OCSP Response"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.2"] = OIDName{ShortName: "Nonce", LongName: "OCSP Nonce"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.3"] = OIDName{ShortName: "CrlID", LongName: "OCSP CRL ID"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.4"] = OIDName{ShortName: "acceptableResponses", LongName: "Acceptable OCSP Responses"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.5"] = OIDName{ShortName: "noCheck", LongName: "OCSP No Check"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.6"] = OIDName{ShortName: "archiveCutoff", LongName: "OCSP Archive Cutoff"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.7"] = OIDName{ShortName: "serviceLocator", LongName: "OCSP Service Locator"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.8"] = OIDName{ShortName: "extendedStatus", LongName: "Extended OCSP Status"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.9"] = OIDName{ShortName: "valid", LongName: "valid"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.10"] = OIDName{ShortName: "path", LongName: "path"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.1.11"] = OIDName{ShortName: "trustRoot", LongName: "Trust Root"} + oidDotNotationToNames["1.3.14.3.2"] = OIDName{ShortName: "algorithm", LongName: "algorithm"} + oidDotNotationToNames["1.3.14.3.2.11"] = OIDName{ShortName: "rsaSignature", LongName: "rsaSignature"} + oidDotNotationToNames["2.5.8"] = OIDName{ShortName: "X500algorithms", LongName: "directory services - algorithms"} + oidDotNotationToNames["1.3"] = OIDName{ShortName: "ORG", LongName: "org"} + oidDotNotationToNames["1.3.6"] = OIDName{ShortName: "DOD", LongName: "dod"} + oidDotNotationToNames["1.3.6.1"] = OIDName{ShortName: "IANA", LongName: "iana"} + oidDotNotationToNames["1.3.6.1.1"] = OIDName{ShortName: "directory", LongName: "Directory"} + oidDotNotationToNames["1.3.6.1.2"] = OIDName{ShortName: "mgmt", LongName: "Management"} + oidDotNotationToNames["1.3.6.1.3"] = OIDName{ShortName: "experimental", LongName: "Experimental"} + oidDotNotationToNames["1.3.6.1.4"] = OIDName{ShortName: "private", LongName: "Private"} + oidDotNotationToNames["1.3.6.1.5"] = OIDName{ShortName: "security", LongName: "Security"} + oidDotNotationToNames["1.3.6.1.6"] = OIDName{ShortName: "snmpv2", LongName: "SNMPv2"} + oidDotNotationToNames["1.3.6.1.7"] = OIDName{ShortName: "Mail", LongName: "Mail"} + oidDotNotationToNames["1.3.6.1.4.1"] = OIDName{ShortName: "enterprises", LongName: "Enterprises"} + oidDotNotationToNames["1.3.6.1.4.1.1466.344"] = OIDName{ShortName: "dcobject", LongName: "dcObject"} + oidDotNotationToNames["0.9.2342.19200300.100.1.25"] = OIDName{ShortName: "DC", LongName: "domainComponent"} + oidDotNotationToNames["0.9.2342.19200300.100.4.13"] = OIDName{ShortName: "domain", LongName: "Domain"} + oidDotNotationToNames["0.0"] = OIDName{ShortName: "NULL", LongName: "NULL"} + oidDotNotationToNames["2.5.1.5"] = OIDName{ShortName: "selected-attribute-types", LongName: "Selected Attribute Types"} + oidDotNotationToNames["2.5.1.5.55"] = OIDName{ShortName: "clearance", LongName: "clearance"} + oidDotNotationToNames["1.2.840.113549.1.1.3"] = OIDName{ShortName: "RSA-MD4", LongName: "md4WithRSAEncryption"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.10"] = OIDName{ShortName: "ac-proxying", LongName: "ac-proxying"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.11"] = OIDName{ShortName: "subjectInfoAccess", LongName: "Subject Information Access"} + oidDotNotationToNames["1.3.6.1.5.5.7.10.6"] = OIDName{ShortName: "id-aca-encAttrs", LongName: "id-aca-encAttrs"} + oidDotNotationToNames["2.5.4.72"] = OIDName{ShortName: "role", LongName: "role"} + oidDotNotationToNames["2.5.29.36"] = OIDName{ShortName: "policyConstraints", LongName: "X509v3 Policy Constraints"} + oidDotNotationToNames["2.5.29.55"] = OIDName{ShortName: "targetInformation", LongName: "X509v3 AC Targeting"} + oidDotNotationToNames["2.5.29.56"] = OIDName{ShortName: "noRevAvail", LongName: "X509v3 No Revocation Available"} + oidDotNotationToNames["0.0"] = OIDName{ShortName: "NULL", LongName: "NULL"} + oidDotNotationToNames["1.2.840.10045"] = OIDName{ShortName: "ansi-X9-62", LongName: "ANSI X9.62"} + oidDotNotationToNames["1.2.840.10045.1.1"] = OIDName{ShortName: "prime-field", LongName: "prime-field"} + oidDotNotationToNames["1.2.840.10045.1.2"] = OIDName{ShortName: "characteristic-two-field", LongName: "characteristic-two-field"} + oidDotNotationToNames["1.2.840.10045.2.1"] = OIDName{ShortName: "id-ecPublicKey", LongName: "id-ecPublicKey"} + oidDotNotationToNames["1.2.840.10045.3.1.1"] = OIDName{ShortName: "prime192v1", LongName: "prime192v1"} + oidDotNotationToNames["1.2.840.10045.3.1.2"] = OIDName{ShortName: "prime192v2", LongName: "prime192v2"} + oidDotNotationToNames["1.2.840.10045.3.1.3"] = OIDName{ShortName: "prime192v3", LongName: "prime192v3"} + oidDotNotationToNames["1.2.840.10045.3.1.4"] = OIDName{ShortName: "prime239v1", LongName: "prime239v1"} + oidDotNotationToNames["1.2.840.10045.3.1.5"] = OIDName{ShortName: "prime239v2", LongName: "prime239v2"} + oidDotNotationToNames["1.2.840.10045.3.1.6"] = OIDName{ShortName: "prime239v3", LongName: "prime239v3"} + oidDotNotationToNames["1.2.840.10045.3.1.7"] = OIDName{ShortName: "prime256v1", LongName: "prime256v1"} + oidDotNotationToNames["1.2.840.10045.4.1"] = OIDName{ShortName: "ecdsa-with-SHA1", LongName: "ecdsa-with-SHA1"} + oidDotNotationToNames["1.3.6.1.4.1.311.17.1"] = OIDName{ShortName: "CSPName", LongName: "Microsoft CSP Name"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.1"] = OIDName{ShortName: "AES-128-ECB", LongName: "aes-128-ecb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.2"] = OIDName{ShortName: "AES-128-CBC", LongName: "aes-128-cbc"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.3"] = OIDName{ShortName: "AES-128-OFB", LongName: "aes-128-ofb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.4"] = OIDName{ShortName: "AES-128-CFB", LongName: "aes-128-cfb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.21"] = OIDName{ShortName: "AES-192-ECB", LongName: "aes-192-ecb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.22"] = OIDName{ShortName: "AES-192-CBC", LongName: "aes-192-cbc"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.23"] = OIDName{ShortName: "AES-192-OFB", LongName: "aes-192-ofb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.24"] = OIDName{ShortName: "AES-192-CFB", LongName: "aes-192-cfb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.41"] = OIDName{ShortName: "AES-256-ECB", LongName: "aes-256-ecb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.42"] = OIDName{ShortName: "AES-256-CBC", LongName: "aes-256-cbc"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.43"] = OIDName{ShortName: "AES-256-OFB", LongName: "aes-256-ofb"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.44"] = OIDName{ShortName: "AES-256-CFB", LongName: "aes-256-cfb"} + oidDotNotationToNames["2.5.29.23"] = OIDName{ShortName: "holdInstructionCode", LongName: "Hold Instruction Code"} + oidDotNotationToNames["1.2.840.10040.2.1"] = OIDName{ShortName: "holdInstructionNone", LongName: "Hold Instruction None"} + oidDotNotationToNames["1.2.840.10040.2.2"] = OIDName{ShortName: "holdInstructionCallIssuer", LongName: "Hold Instruction Call Issuer"} + oidDotNotationToNames["1.2.840.10040.2.3"] = OIDName{ShortName: "holdInstructionReject", LongName: "Hold Instruction Reject"} + oidDotNotationToNames["0.9"] = OIDName{ShortName: "data", LongName: "data"} + oidDotNotationToNames["0.9.2342"] = OIDName{ShortName: "pss", LongName: "pss"} + oidDotNotationToNames["0.9.2342.19200300"] = OIDName{ShortName: "ucl", LongName: "ucl"} + oidDotNotationToNames["0.9.2342.19200300.100"] = OIDName{ShortName: "pilot", LongName: "pilot"} + oidDotNotationToNames["0.9.2342.19200300.100.1"] = OIDName{ShortName: "pilotAttributeType", LongName: "pilotAttributeType"} + oidDotNotationToNames["0.9.2342.19200300.100.3"] = OIDName{ShortName: "pilotAttributeSyntax", LongName: "pilotAttributeSyntax"} + oidDotNotationToNames["0.9.2342.19200300.100.4"] = OIDName{ShortName: "pilotObjectClass", LongName: "pilotObjectClass"} + oidDotNotationToNames["0.9.2342.19200300.100.10"] = OIDName{ShortName: "pilotGroups", LongName: "pilotGroups"} + oidDotNotationToNames["0.9.2342.19200300.100.3.4"] = OIDName{ShortName: "iA5StringSyntax", LongName: "iA5StringSyntax"} + oidDotNotationToNames["0.9.2342.19200300.100.3.5"] = OIDName{ShortName: "caseIgnoreIA5StringSyntax", LongName: "caseIgnoreIA5StringSyntax"} + oidDotNotationToNames["0.9.2342.19200300.100.4.3"] = OIDName{ShortName: "pilotObject", LongName: "pilotObject"} + oidDotNotationToNames["0.9.2342.19200300.100.4.4"] = OIDName{ShortName: "pilotPerson", LongName: "pilotPerson"} + oidDotNotationToNames["0.9.2342.19200300.100.4.5"] = OIDName{ShortName: "account", LongName: "account"} + oidDotNotationToNames["0.9.2342.19200300.100.4.6"] = OIDName{ShortName: "document", LongName: "document"} + oidDotNotationToNames["0.9.2342.19200300.100.4.7"] = OIDName{ShortName: "room", LongName: "room"} + oidDotNotationToNames["0.9.2342.19200300.100.4.9"] = OIDName{ShortName: "documentSeries", LongName: "documentSeries"} + oidDotNotationToNames["0.9.2342.19200300.100.4.14"] = OIDName{ShortName: "rFC822localPart", LongName: "rFC822localPart"} + oidDotNotationToNames["0.9.2342.19200300.100.4.15"] = OIDName{ShortName: "dNSDomain", LongName: "dNSDomain"} + oidDotNotationToNames["0.9.2342.19200300.100.4.17"] = OIDName{ShortName: "domainRelatedObject", LongName: "domainRelatedObject"} + oidDotNotationToNames["0.9.2342.19200300.100.4.18"] = OIDName{ShortName: "friendlyCountry", LongName: "friendlyCountry"} + oidDotNotationToNames["0.9.2342.19200300.100.4.19"] = OIDName{ShortName: "simpleSecurityObject", LongName: "simpleSecurityObject"} + oidDotNotationToNames["0.9.2342.19200300.100.4.20"] = OIDName{ShortName: "pilotOrganization", LongName: "pilotOrganization"} + oidDotNotationToNames["0.9.2342.19200300.100.4.21"] = OIDName{ShortName: "pilotDSA", LongName: "pilotDSA"} + oidDotNotationToNames["0.9.2342.19200300.100.4.22"] = OIDName{ShortName: "qualityLabelledData", LongName: "qualityLabelledData"} + oidDotNotationToNames["0.9.2342.19200300.100.1.1"] = OIDName{ShortName: "UID", LongName: "userId"} + oidDotNotationToNames["0.9.2342.19200300.100.1.2"] = OIDName{ShortName: "textEncodedORAddress", LongName: "textEncodedORAddress"} + oidDotNotationToNames["0.9.2342.19200300.100.1.3"] = OIDName{ShortName: "mail", LongName: "rfc822Mailbox"} + oidDotNotationToNames["0.9.2342.19200300.100.1.4"] = OIDName{ShortName: "info", LongName: "info"} + oidDotNotationToNames["0.9.2342.19200300.100.1.5"] = OIDName{ShortName: "favouriteDrink", LongName: "favouriteDrink"} + oidDotNotationToNames["0.9.2342.19200300.100.1.6"] = OIDName{ShortName: "roomNumber", LongName: "roomNumber"} + oidDotNotationToNames["0.9.2342.19200300.100.1.7"] = OIDName{ShortName: "photo", LongName: "photo"} + oidDotNotationToNames["0.9.2342.19200300.100.1.8"] = OIDName{ShortName: "userClass", LongName: "userClass"} + oidDotNotationToNames["0.9.2342.19200300.100.1.9"] = OIDName{ShortName: "host", LongName: "host"} + oidDotNotationToNames["0.9.2342.19200300.100.1.10"] = OIDName{ShortName: "manager", LongName: "manager"} + oidDotNotationToNames["0.9.2342.19200300.100.1.11"] = OIDName{ShortName: "documentIdentifier", LongName: "documentIdentifier"} + oidDotNotationToNames["0.9.2342.19200300.100.1.12"] = OIDName{ShortName: "documentTitle", LongName: "documentTitle"} + oidDotNotationToNames["0.9.2342.19200300.100.1.13"] = OIDName{ShortName: "documentVersion", LongName: "documentVersion"} + oidDotNotationToNames["0.9.2342.19200300.100.1.14"] = OIDName{ShortName: "documentAuthor", LongName: "documentAuthor"} + oidDotNotationToNames["0.9.2342.19200300.100.1.15"] = OIDName{ShortName: "documentLocation", LongName: "documentLocation"} + oidDotNotationToNames["0.9.2342.19200300.100.1.20"] = OIDName{ShortName: "homeTelephoneNumber", LongName: "homeTelephoneNumber"} + oidDotNotationToNames["0.9.2342.19200300.100.1.21"] = OIDName{ShortName: "secretary", LongName: "secretary"} + oidDotNotationToNames["0.9.2342.19200300.100.1.22"] = OIDName{ShortName: "otherMailbox", LongName: "otherMailbox"} + oidDotNotationToNames["0.9.2342.19200300.100.1.23"] = OIDName{ShortName: "lastModifiedTime", LongName: "lastModifiedTime"} + oidDotNotationToNames["0.9.2342.19200300.100.1.24"] = OIDName{ShortName: "lastModifiedBy", LongName: "lastModifiedBy"} + oidDotNotationToNames["0.9.2342.19200300.100.1.26"] = OIDName{ShortName: "aRecord", LongName: "aRecord"} + oidDotNotationToNames["0.9.2342.19200300.100.1.27"] = OIDName{ShortName: "pilotAttributeType27", LongName: "pilotAttributeType27"} + oidDotNotationToNames["0.9.2342.19200300.100.1.28"] = OIDName{ShortName: "mXRecord", LongName: "mXRecord"} + oidDotNotationToNames["0.9.2342.19200300.100.1.29"] = OIDName{ShortName: "nSRecord", LongName: "nSRecord"} + oidDotNotationToNames["0.9.2342.19200300.100.1.30"] = OIDName{ShortName: "sOARecord", LongName: "sOARecord"} + oidDotNotationToNames["0.9.2342.19200300.100.1.31"] = OIDName{ShortName: "cNAMERecord", LongName: "cNAMERecord"} + oidDotNotationToNames["0.9.2342.19200300.100.1.37"] = OIDName{ShortName: "associatedDomain", LongName: "associatedDomain"} + oidDotNotationToNames["0.9.2342.19200300.100.1.38"] = OIDName{ShortName: "associatedName", LongName: "associatedName"} + oidDotNotationToNames["0.9.2342.19200300.100.1.39"] = OIDName{ShortName: "homePostalAddress", LongName: "homePostalAddress"} + oidDotNotationToNames["0.9.2342.19200300.100.1.40"] = OIDName{ShortName: "personalTitle", LongName: "personalTitle"} + oidDotNotationToNames["0.9.2342.19200300.100.1.41"] = OIDName{ShortName: "mobileTelephoneNumber", LongName: "mobileTelephoneNumber"} + oidDotNotationToNames["0.9.2342.19200300.100.1.42"] = OIDName{ShortName: "pagerTelephoneNumber", LongName: "pagerTelephoneNumber"} + oidDotNotationToNames["0.9.2342.19200300.100.1.43"] = OIDName{ShortName: "friendlyCountryName", LongName: "friendlyCountryName"} + oidDotNotationToNames["0.9.2342.19200300.100.1.45"] = OIDName{ShortName: "organizationalStatus", LongName: "organizationalStatus"} + oidDotNotationToNames["0.9.2342.19200300.100.1.46"] = OIDName{ShortName: "janetMailbox", LongName: "janetMailbox"} + oidDotNotationToNames["0.9.2342.19200300.100.1.47"] = OIDName{ShortName: "mailPreferenceOption", LongName: "mailPreferenceOption"} + oidDotNotationToNames["0.9.2342.19200300.100.1.48"] = OIDName{ShortName: "buildingName", LongName: "buildingName"} + oidDotNotationToNames["0.9.2342.19200300.100.1.49"] = OIDName{ShortName: "dSAQuality", LongName: "dSAQuality"} + oidDotNotationToNames["0.9.2342.19200300.100.1.50"] = OIDName{ShortName: "singleLevelQuality", LongName: "singleLevelQuality"} + oidDotNotationToNames["0.9.2342.19200300.100.1.51"] = OIDName{ShortName: "subtreeMinimumQuality", LongName: "subtreeMinimumQuality"} + oidDotNotationToNames["0.9.2342.19200300.100.1.52"] = OIDName{ShortName: "subtreeMaximumQuality", LongName: "subtreeMaximumQuality"} + oidDotNotationToNames["0.9.2342.19200300.100.1.53"] = OIDName{ShortName: "personalSignature", LongName: "personalSignature"} + oidDotNotationToNames["0.9.2342.19200300.100.1.54"] = OIDName{ShortName: "dITRedirect", LongName: "dITRedirect"} + oidDotNotationToNames["0.9.2342.19200300.100.1.55"] = OIDName{ShortName: "audio", LongName: "audio"} + oidDotNotationToNames["0.9.2342.19200300.100.1.56"] = OIDName{ShortName: "documentPublisher", LongName: "documentPublisher"} + oidDotNotationToNames["2.5.4.45"] = OIDName{ShortName: "x500UniqueIdentifier", LongName: "x500UniqueIdentifier"} + oidDotNotationToNames["1.3.6.1.7.1"] = OIDName{ShortName: "mime-mhs", LongName: "MIME MHS"} + oidDotNotationToNames["1.3.6.1.7.1.1"] = OIDName{ShortName: "mime-mhs-headings", LongName: "mime-mhs-headings"} + oidDotNotationToNames["1.3.6.1.7.1.2"] = OIDName{ShortName: "mime-mhs-bodies", LongName: "mime-mhs-bodies"} + oidDotNotationToNames["1.3.6.1.7.1.1.1"] = OIDName{ShortName: "id-hex-partial-message", LongName: "id-hex-partial-message"} + oidDotNotationToNames["1.3.6.1.7.1.1.2"] = OIDName{ShortName: "id-hex-multipart-message", LongName: "id-hex-multipart-message"} + oidDotNotationToNames["2.5.4.44"] = OIDName{ShortName: "generationQualifier", LongName: "generationQualifier"} + oidDotNotationToNames["2.5.4.65"] = OIDName{ShortName: "pseudonym", LongName: "pseudonym"} + oidDotNotationToNames["2.23.42"] = OIDName{ShortName: "id-set", LongName: "Secure Electronic Transactions"} + oidDotNotationToNames["2.23.42.0"] = OIDName{ShortName: "set-ctype", LongName: "content types"} + oidDotNotationToNames["2.23.42.1"] = OIDName{ShortName: "set-msgExt", LongName: "message extensions"} + oidDotNotationToNames["2.23.42.3"] = OIDName{ShortName: "set-attr", LongName: "set-attr"} + oidDotNotationToNames["2.23.42.5"] = OIDName{ShortName: "set-policy", LongName: "set-policy"} + oidDotNotationToNames["2.23.42.7"] = OIDName{ShortName: "set-certExt", LongName: "certificate extensions"} + oidDotNotationToNames["2.23.42.8"] = OIDName{ShortName: "set-brand", LongName: "set-brand"} + oidDotNotationToNames["2.23.42.0.0"] = OIDName{ShortName: "setct-PANData", LongName: "setct-PANData"} + oidDotNotationToNames["2.23.42.0.1"] = OIDName{ShortName: "setct-PANToken", LongName: "setct-PANToken"} + oidDotNotationToNames["2.23.42.0.2"] = OIDName{ShortName: "setct-PANOnly", LongName: "setct-PANOnly"} + oidDotNotationToNames["2.23.42.0.3"] = OIDName{ShortName: "setct-OIData", LongName: "setct-OIData"} + oidDotNotationToNames["2.23.42.0.4"] = OIDName{ShortName: "setct-PI", LongName: "setct-PI"} + oidDotNotationToNames["2.23.42.0.5"] = OIDName{ShortName: "setct-PIData", LongName: "setct-PIData"} + oidDotNotationToNames["2.23.42.0.6"] = OIDName{ShortName: "setct-PIDataUnsigned", LongName: "setct-PIDataUnsigned"} + oidDotNotationToNames["2.23.42.0.7"] = OIDName{ShortName: "setct-HODInput", LongName: "setct-HODInput"} + oidDotNotationToNames["2.23.42.0.8"] = OIDName{ShortName: "setct-AuthResBaggage", LongName: "setct-AuthResBaggage"} + oidDotNotationToNames["2.23.42.0.9"] = OIDName{ShortName: "setct-AuthRevReqBaggage", LongName: "setct-AuthRevReqBaggage"} + oidDotNotationToNames["2.23.42.0.10"] = OIDName{ShortName: "setct-AuthRevResBaggage", LongName: "setct-AuthRevResBaggage"} + oidDotNotationToNames["2.23.42.0.11"] = OIDName{ShortName: "setct-CapTokenSeq", LongName: "setct-CapTokenSeq"} + oidDotNotationToNames["2.23.42.0.12"] = OIDName{ShortName: "setct-PInitResData", LongName: "setct-PInitResData"} + oidDotNotationToNames["2.23.42.0.13"] = OIDName{ShortName: "setct-PI-TBS", LongName: "setct-PI-TBS"} + oidDotNotationToNames["2.23.42.0.14"] = OIDName{ShortName: "setct-PResData", LongName: "setct-PResData"} + oidDotNotationToNames["2.23.42.0.16"] = OIDName{ShortName: "setct-AuthReqTBS", LongName: "setct-AuthReqTBS"} + oidDotNotationToNames["2.23.42.0.17"] = OIDName{ShortName: "setct-AuthResTBS", LongName: "setct-AuthResTBS"} + oidDotNotationToNames["2.23.42.0.18"] = OIDName{ShortName: "setct-AuthResTBSX", LongName: "setct-AuthResTBSX"} + oidDotNotationToNames["2.23.42.0.19"] = OIDName{ShortName: "setct-AuthTokenTBS", LongName: "setct-AuthTokenTBS"} + oidDotNotationToNames["2.23.42.0.20"] = OIDName{ShortName: "setct-CapTokenData", LongName: "setct-CapTokenData"} + oidDotNotationToNames["2.23.42.0.21"] = OIDName{ShortName: "setct-CapTokenTBS", LongName: "setct-CapTokenTBS"} + oidDotNotationToNames["2.23.42.0.22"] = OIDName{ShortName: "setct-AcqCardCodeMsg", LongName: "setct-AcqCardCodeMsg"} + oidDotNotationToNames["2.23.42.0.23"] = OIDName{ShortName: "setct-AuthRevReqTBS", LongName: "setct-AuthRevReqTBS"} + oidDotNotationToNames["2.23.42.0.24"] = OIDName{ShortName: "setct-AuthRevResData", LongName: "setct-AuthRevResData"} + oidDotNotationToNames["2.23.42.0.25"] = OIDName{ShortName: "setct-AuthRevResTBS", LongName: "setct-AuthRevResTBS"} + oidDotNotationToNames["2.23.42.0.26"] = OIDName{ShortName: "setct-CapReqTBS", LongName: "setct-CapReqTBS"} + oidDotNotationToNames["2.23.42.0.27"] = OIDName{ShortName: "setct-CapReqTBSX", LongName: "setct-CapReqTBSX"} + oidDotNotationToNames["2.23.42.0.28"] = OIDName{ShortName: "setct-CapResData", LongName: "setct-CapResData"} + oidDotNotationToNames["2.23.42.0.29"] = OIDName{ShortName: "setct-CapRevReqTBS", LongName: "setct-CapRevReqTBS"} + oidDotNotationToNames["2.23.42.0.30"] = OIDName{ShortName: "setct-CapRevReqTBSX", LongName: "setct-CapRevReqTBSX"} + oidDotNotationToNames["2.23.42.0.31"] = OIDName{ShortName: "setct-CapRevResData", LongName: "setct-CapRevResData"} + oidDotNotationToNames["2.23.42.0.32"] = OIDName{ShortName: "setct-CredReqTBS", LongName: "setct-CredReqTBS"} + oidDotNotationToNames["2.23.42.0.33"] = OIDName{ShortName: "setct-CredReqTBSX", LongName: "setct-CredReqTBSX"} + oidDotNotationToNames["2.23.42.0.34"] = OIDName{ShortName: "setct-CredResData", LongName: "setct-CredResData"} + oidDotNotationToNames["2.23.42.0.35"] = OIDName{ShortName: "setct-CredRevReqTBS", LongName: "setct-CredRevReqTBS"} + oidDotNotationToNames["2.23.42.0.36"] = OIDName{ShortName: "setct-CredRevReqTBSX", LongName: "setct-CredRevReqTBSX"} + oidDotNotationToNames["2.23.42.0.37"] = OIDName{ShortName: "setct-CredRevResData", LongName: "setct-CredRevResData"} + oidDotNotationToNames["2.23.42.0.38"] = OIDName{ShortName: "setct-PCertReqData", LongName: "setct-PCertReqData"} + oidDotNotationToNames["2.23.42.0.39"] = OIDName{ShortName: "setct-PCertResTBS", LongName: "setct-PCertResTBS"} + oidDotNotationToNames["2.23.42.0.40"] = OIDName{ShortName: "setct-BatchAdminReqData", LongName: "setct-BatchAdminReqData"} + oidDotNotationToNames["2.23.42.0.41"] = OIDName{ShortName: "setct-BatchAdminResData", LongName: "setct-BatchAdminResData"} + oidDotNotationToNames["2.23.42.0.42"] = OIDName{ShortName: "setct-CardCInitResTBS", LongName: "setct-CardCInitResTBS"} + oidDotNotationToNames["2.23.42.0.43"] = OIDName{ShortName: "setct-MeAqCInitResTBS", LongName: "setct-MeAqCInitResTBS"} + oidDotNotationToNames["2.23.42.0.44"] = OIDName{ShortName: "setct-RegFormResTBS", LongName: "setct-RegFormResTBS"} + oidDotNotationToNames["2.23.42.0.45"] = OIDName{ShortName: "setct-CertReqData", LongName: "setct-CertReqData"} + oidDotNotationToNames["2.23.42.0.46"] = OIDName{ShortName: "setct-CertReqTBS", LongName: "setct-CertReqTBS"} + oidDotNotationToNames["2.23.42.0.47"] = OIDName{ShortName: "setct-CertResData", LongName: "setct-CertResData"} + oidDotNotationToNames["2.23.42.0.48"] = OIDName{ShortName: "setct-CertInqReqTBS", LongName: "setct-CertInqReqTBS"} + oidDotNotationToNames["2.23.42.0.49"] = OIDName{ShortName: "setct-ErrorTBS", LongName: "setct-ErrorTBS"} + oidDotNotationToNames["2.23.42.0.50"] = OIDName{ShortName: "setct-PIDualSignedTBE", LongName: "setct-PIDualSignedTBE"} + oidDotNotationToNames["2.23.42.0.51"] = OIDName{ShortName: "setct-PIUnsignedTBE", LongName: "setct-PIUnsignedTBE"} + oidDotNotationToNames["2.23.42.0.52"] = OIDName{ShortName: "setct-AuthReqTBE", LongName: "setct-AuthReqTBE"} + oidDotNotationToNames["2.23.42.0.53"] = OIDName{ShortName: "setct-AuthResTBE", LongName: "setct-AuthResTBE"} + oidDotNotationToNames["2.23.42.0.54"] = OIDName{ShortName: "setct-AuthResTBEX", LongName: "setct-AuthResTBEX"} + oidDotNotationToNames["2.23.42.0.55"] = OIDName{ShortName: "setct-AuthTokenTBE", LongName: "setct-AuthTokenTBE"} + oidDotNotationToNames["2.23.42.0.56"] = OIDName{ShortName: "setct-CapTokenTBE", LongName: "setct-CapTokenTBE"} + oidDotNotationToNames["2.23.42.0.57"] = OIDName{ShortName: "setct-CapTokenTBEX", LongName: "setct-CapTokenTBEX"} + oidDotNotationToNames["2.23.42.0.58"] = OIDName{ShortName: "setct-AcqCardCodeMsgTBE", LongName: "setct-AcqCardCodeMsgTBE"} + oidDotNotationToNames["2.23.42.0.59"] = OIDName{ShortName: "setct-AuthRevReqTBE", LongName: "setct-AuthRevReqTBE"} + oidDotNotationToNames["2.23.42.0.60"] = OIDName{ShortName: "setct-AuthRevResTBE", LongName: "setct-AuthRevResTBE"} + oidDotNotationToNames["2.23.42.0.61"] = OIDName{ShortName: "setct-AuthRevResTBEB", LongName: "setct-AuthRevResTBEB"} + oidDotNotationToNames["2.23.42.0.62"] = OIDName{ShortName: "setct-CapReqTBE", LongName: "setct-CapReqTBE"} + oidDotNotationToNames["2.23.42.0.63"] = OIDName{ShortName: "setct-CapReqTBEX", LongName: "setct-CapReqTBEX"} + oidDotNotationToNames["2.23.42.0.64"] = OIDName{ShortName: "setct-CapResTBE", LongName: "setct-CapResTBE"} + oidDotNotationToNames["2.23.42.0.65"] = OIDName{ShortName: "setct-CapRevReqTBE", LongName: "setct-CapRevReqTBE"} + oidDotNotationToNames["2.23.42.0.66"] = OIDName{ShortName: "setct-CapRevReqTBEX", LongName: "setct-CapRevReqTBEX"} + oidDotNotationToNames["2.23.42.0.67"] = OIDName{ShortName: "setct-CapRevResTBE", LongName: "setct-CapRevResTBE"} + oidDotNotationToNames["2.23.42.0.68"] = OIDName{ShortName: "setct-CredReqTBE", LongName: "setct-CredReqTBE"} + oidDotNotationToNames["2.23.42.0.69"] = OIDName{ShortName: "setct-CredReqTBEX", LongName: "setct-CredReqTBEX"} + oidDotNotationToNames["2.23.42.0.70"] = OIDName{ShortName: "setct-CredResTBE", LongName: "setct-CredResTBE"} + oidDotNotationToNames["2.23.42.0.71"] = OIDName{ShortName: "setct-CredRevReqTBE", LongName: "setct-CredRevReqTBE"} + oidDotNotationToNames["2.23.42.0.72"] = OIDName{ShortName: "setct-CredRevReqTBEX", LongName: "setct-CredRevReqTBEX"} + oidDotNotationToNames["2.23.42.0.73"] = OIDName{ShortName: "setct-CredRevResTBE", LongName: "setct-CredRevResTBE"} + oidDotNotationToNames["2.23.42.0.74"] = OIDName{ShortName: "setct-BatchAdminReqTBE", LongName: "setct-BatchAdminReqTBE"} + oidDotNotationToNames["2.23.42.0.75"] = OIDName{ShortName: "setct-BatchAdminResTBE", LongName: "setct-BatchAdminResTBE"} + oidDotNotationToNames["2.23.42.0.76"] = OIDName{ShortName: "setct-RegFormReqTBE", LongName: "setct-RegFormReqTBE"} + oidDotNotationToNames["2.23.42.0.77"] = OIDName{ShortName: "setct-CertReqTBE", LongName: "setct-CertReqTBE"} + oidDotNotationToNames["2.23.42.0.78"] = OIDName{ShortName: "setct-CertReqTBEX", LongName: "setct-CertReqTBEX"} + oidDotNotationToNames["2.23.42.0.79"] = OIDName{ShortName: "setct-CertResTBE", LongName: "setct-CertResTBE"} + oidDotNotationToNames["2.23.42.0.80"] = OIDName{ShortName: "setct-CRLNotificationTBS", LongName: "setct-CRLNotificationTBS"} + oidDotNotationToNames["2.23.42.0.81"] = OIDName{ShortName: "setct-CRLNotificationResTBS", LongName: "setct-CRLNotificationResTBS"} + oidDotNotationToNames["2.23.42.0.82"] = OIDName{ShortName: "setct-BCIDistributionTBS", LongName: "setct-BCIDistributionTBS"} + oidDotNotationToNames["2.23.42.1.1"] = OIDName{ShortName: "setext-genCrypt", LongName: "generic cryptogram"} + oidDotNotationToNames["2.23.42.1.3"] = OIDName{ShortName: "setext-miAuth", LongName: "merchant initiated auth"} + oidDotNotationToNames["2.23.42.1.4"] = OIDName{ShortName: "setext-pinSecure", LongName: "setext-pinSecure"} + oidDotNotationToNames["2.23.42.1.5"] = OIDName{ShortName: "setext-pinAny", LongName: "setext-pinAny"} + oidDotNotationToNames["2.23.42.1.7"] = OIDName{ShortName: "setext-track2", LongName: "setext-track2"} + oidDotNotationToNames["2.23.42.1.8"] = OIDName{ShortName: "setext-cv", LongName: "additional verification"} + oidDotNotationToNames["2.23.42.5.0"] = OIDName{ShortName: "set-policy-root", LongName: "set-policy-root"} + oidDotNotationToNames["2.23.42.7.0"] = OIDName{ShortName: "setCext-hashedRoot", LongName: "setCext-hashedRoot"} + oidDotNotationToNames["2.23.42.7.1"] = OIDName{ShortName: "setCext-certType", LongName: "setCext-certType"} + oidDotNotationToNames["2.23.42.7.2"] = OIDName{ShortName: "setCext-merchData", LongName: "setCext-merchData"} + oidDotNotationToNames["2.23.42.7.3"] = OIDName{ShortName: "setCext-cCertRequired", LongName: "setCext-cCertRequired"} + oidDotNotationToNames["2.23.42.7.4"] = OIDName{ShortName: "setCext-tunneling", LongName: "setCext-tunneling"} + oidDotNotationToNames["2.23.42.7.5"] = OIDName{ShortName: "setCext-setExt", LongName: "setCext-setExt"} + oidDotNotationToNames["2.23.42.7.6"] = OIDName{ShortName: "setCext-setQualf", LongName: "setCext-setQualf"} + oidDotNotationToNames["2.23.42.7.7"] = OIDName{ShortName: "setCext-PGWYcapabilities", LongName: "setCext-PGWYcapabilities"} + oidDotNotationToNames["2.23.42.7.8"] = OIDName{ShortName: "setCext-TokenIdentifier", LongName: "setCext-TokenIdentifier"} + oidDotNotationToNames["2.23.42.7.9"] = OIDName{ShortName: "setCext-Track2Data", LongName: "setCext-Track2Data"} + oidDotNotationToNames["2.23.42.7.10"] = OIDName{ShortName: "setCext-TokenType", LongName: "setCext-TokenType"} + oidDotNotationToNames["2.23.42.7.11"] = OIDName{ShortName: "setCext-IssuerCapabilities", LongName: "setCext-IssuerCapabilities"} + oidDotNotationToNames["2.23.42.3.0"] = OIDName{ShortName: "setAttr-Cert", LongName: "setAttr-Cert"} + oidDotNotationToNames["2.23.42.3.1"] = OIDName{ShortName: "setAttr-PGWYcap", LongName: "payment gateway capabilities"} + oidDotNotationToNames["2.23.42.3.2"] = OIDName{ShortName: "setAttr-TokenType", LongName: "setAttr-TokenType"} + oidDotNotationToNames["2.23.42.3.3"] = OIDName{ShortName: "setAttr-IssCap", LongName: "issuer capabilities"} + oidDotNotationToNames["2.23.42.3.0.0"] = OIDName{ShortName: "set-rootKeyThumb", LongName: "set-rootKeyThumb"} + oidDotNotationToNames["2.23.42.3.0.1"] = OIDName{ShortName: "set-addPolicy", LongName: "set-addPolicy"} + oidDotNotationToNames["2.23.42.3.2.1"] = OIDName{ShortName: "setAttr-Token-EMV", LongName: "setAttr-Token-EMV"} + oidDotNotationToNames["2.23.42.3.2.2"] = OIDName{ShortName: "setAttr-Token-B0Prime", LongName: "setAttr-Token-B0Prime"} + oidDotNotationToNames["2.23.42.3.3.3"] = OIDName{ShortName: "setAttr-IssCap-CVM", LongName: "setAttr-IssCap-CVM"} + oidDotNotationToNames["2.23.42.3.3.4"] = OIDName{ShortName: "setAttr-IssCap-T2", LongName: "setAttr-IssCap-T2"} + oidDotNotationToNames["2.23.42.3.3.5"] = OIDName{ShortName: "setAttr-IssCap-Sig", LongName: "setAttr-IssCap-Sig"} + oidDotNotationToNames["2.23.42.3.3.3.1"] = OIDName{ShortName: "setAttr-GenCryptgrm", LongName: "generate cryptogram"} + oidDotNotationToNames["2.23.42.3.3.4.1"] = OIDName{ShortName: "setAttr-T2Enc", LongName: "encrypted track 2"} + oidDotNotationToNames["2.23.42.3.3.4.2"] = OIDName{ShortName: "setAttr-T2cleartxt", LongName: "cleartext track 2"} + oidDotNotationToNames["2.23.42.3.3.5.1"] = OIDName{ShortName: "setAttr-TokICCsig", LongName: "ICC or token signature"} + oidDotNotationToNames["2.23.42.3.3.5.2"] = OIDName{ShortName: "setAttr-SecDevSig", LongName: "secure device signature"} + oidDotNotationToNames["2.23.42.8.1"] = OIDName{ShortName: "set-brand-IATA-ATA", LongName: "set-brand-IATA-ATA"} + oidDotNotationToNames["2.23.42.8.30"] = OIDName{ShortName: "set-brand-Diners", LongName: "set-brand-Diners"} + oidDotNotationToNames["2.23.42.8.34"] = OIDName{ShortName: "set-brand-AmericanExpress", LongName: "set-brand-AmericanExpress"} + oidDotNotationToNames["2.23.42.8.35"] = OIDName{ShortName: "set-brand-JCB", LongName: "set-brand-JCB"} + oidDotNotationToNames["2.23.42.8.4"] = OIDName{ShortName: "set-brand-Visa", LongName: "set-brand-Visa"} + oidDotNotationToNames["2.23.42.8.5"] = OIDName{ShortName: "set-brand-MasterCard", LongName: "set-brand-MasterCard"} + oidDotNotationToNames["2.23.42.8.6011"] = OIDName{ShortName: "set-brand-Novus", LongName: "set-brand-Novus"} + oidDotNotationToNames["1.2.840.113549.3.10"] = OIDName{ShortName: "DES-CDMF", LongName: "des-cdmf"} + oidDotNotationToNames["1.2.840.113549.1.1.6"] = OIDName{ShortName: "rsaOAEPEncryptionSET", LongName: "rsaOAEPEncryptionSET"} + oidDotNotationToNames["0.0"] = OIDName{ShortName: "ITU-T", LongName: "itu-t"} + oidDotNotationToNames["2.0"] = OIDName{ShortName: "JOINT-ISO-ITU-T", LongName: "joint-iso-itu-t"} + oidDotNotationToNames["2.23"] = OIDName{ShortName: "international-organizations", LongName: "International Organizations"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2.2"] = OIDName{ShortName: "msSmartcardLogin", LongName: "Microsoft Smartcardlogin"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2.3"] = OIDName{ShortName: "msUPN", LongName: "Microsoft Universal Principal Name"} + oidDotNotationToNames["2.5.4.9"] = OIDName{ShortName: "street", LongName: "streetAddress"} + oidDotNotationToNames["2.5.4.17"] = OIDName{ShortName: "postalCode", LongName: "postalCode"} + oidDotNotationToNames["1.3.6.1.5.5.7.21"] = OIDName{ShortName: "id-ppl", LongName: "id-ppl"} + oidDotNotationToNames["1.3.6.1.5.5.7.1.14"] = OIDName{ShortName: "proxyCertInfo", LongName: "Proxy Certificate Information"} + oidDotNotationToNames["1.3.6.1.5.5.7.21.0"] = OIDName{ShortName: "id-ppl-anyLanguage", LongName: "Any language"} + oidDotNotationToNames["1.3.6.1.5.5.7.21.1"] = OIDName{ShortName: "id-ppl-inheritAll", LongName: "Inherit all"} + oidDotNotationToNames["2.5.29.30"] = OIDName{ShortName: "nameConstraints", LongName: "X509v3 Name Constraints"} + oidDotNotationToNames["1.3.6.1.5.5.7.21.2"] = OIDName{ShortName: "id-ppl-independent", LongName: "Independent"} + oidDotNotationToNames["1.2.840.113549.1.1.11"] = OIDName{ShortName: "RSA-SHA256", LongName: "sha256WithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.1.1.12"] = OIDName{ShortName: "RSA-SHA384", LongName: "sha384WithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.1.1.13"] = OIDName{ShortName: "RSA-SHA512", LongName: "sha512WithRSAEncryption"} + oidDotNotationToNames["1.2.840.113549.1.1.14"] = OIDName{ShortName: "RSA-SHA224", LongName: "sha224WithRSAEncryption"} + oidDotNotationToNames["2.16.840.1.101.3.4.2.1"] = OIDName{ShortName: "SHA256", LongName: "sha256"} + oidDotNotationToNames["2.16.840.1.101.3.4.2.2"] = OIDName{ShortName: "SHA384", LongName: "sha384"} + oidDotNotationToNames["2.16.840.1.101.3.4.2.3"] = OIDName{ShortName: "SHA512", LongName: "sha512"} + oidDotNotationToNames["2.16.840.1.101.3.4.2.4"] = OIDName{ShortName: "SHA224", LongName: "sha224"} + oidDotNotationToNames["1.3"] = OIDName{ShortName: "identified-organization", LongName: "identified-organization"} + oidDotNotationToNames["1.3.132"] = OIDName{ShortName: "certicom-arc", LongName: "certicom-arc"} + oidDotNotationToNames["2.23.43"] = OIDName{ShortName: "wap", LongName: "wap"} + oidDotNotationToNames["2.23.43.1"] = OIDName{ShortName: "wap-wsg", LongName: "wap-wsg"} + oidDotNotationToNames["1.2.840.10045.1.2.3"] = OIDName{ShortName: "id-characteristic-two-basis", LongName: "id-characteristic-two-basis"} + oidDotNotationToNames["1.2.840.10045.1.2.3.1"] = OIDName{ShortName: "onBasis", LongName: "onBasis"} + oidDotNotationToNames["1.2.840.10045.1.2.3.2"] = OIDName{ShortName: "tpBasis", LongName: "tpBasis"} + oidDotNotationToNames["1.2.840.10045.1.2.3.3"] = OIDName{ShortName: "ppBasis", LongName: "ppBasis"} + oidDotNotationToNames["1.2.840.10045.3.0.1"] = OIDName{ShortName: "c2pnb163v1", LongName: "c2pnb163v1"} + oidDotNotationToNames["1.2.840.10045.3.0.2"] = OIDName{ShortName: "c2pnb163v2", LongName: "c2pnb163v2"} + oidDotNotationToNames["1.2.840.10045.3.0.3"] = OIDName{ShortName: "c2pnb163v3", LongName: "c2pnb163v3"} + oidDotNotationToNames["1.2.840.10045.3.0.4"] = OIDName{ShortName: "c2pnb176v1", LongName: "c2pnb176v1"} + oidDotNotationToNames["1.2.840.10045.3.0.5"] = OIDName{ShortName: "c2tnb191v1", LongName: "c2tnb191v1"} + oidDotNotationToNames["1.2.840.10045.3.0.6"] = OIDName{ShortName: "c2tnb191v2", LongName: "c2tnb191v2"} + oidDotNotationToNames["1.2.840.10045.3.0.7"] = OIDName{ShortName: "c2tnb191v3", LongName: "c2tnb191v3"} + oidDotNotationToNames["1.2.840.10045.3.0.8"] = OIDName{ShortName: "c2onb191v4", LongName: "c2onb191v4"} + oidDotNotationToNames["1.2.840.10045.3.0.9"] = OIDName{ShortName: "c2onb191v5", LongName: "c2onb191v5"} + oidDotNotationToNames["1.2.840.10045.3.0.10"] = OIDName{ShortName: "c2pnb208w1", LongName: "c2pnb208w1"} + oidDotNotationToNames["1.2.840.10045.3.0.11"] = OIDName{ShortName: "c2tnb239v1", LongName: "c2tnb239v1"} + oidDotNotationToNames["1.2.840.10045.3.0.12"] = OIDName{ShortName: "c2tnb239v2", LongName: "c2tnb239v2"} + oidDotNotationToNames["1.2.840.10045.3.0.13"] = OIDName{ShortName: "c2tnb239v3", LongName: "c2tnb239v3"} + oidDotNotationToNames["1.2.840.10045.3.0.14"] = OIDName{ShortName: "c2onb239v4", LongName: "c2onb239v4"} + oidDotNotationToNames["1.2.840.10045.3.0.15"] = OIDName{ShortName: "c2onb239v5", LongName: "c2onb239v5"} + oidDotNotationToNames["1.2.840.10045.3.0.16"] = OIDName{ShortName: "c2pnb272w1", LongName: "c2pnb272w1"} + oidDotNotationToNames["1.2.840.10045.3.0.17"] = OIDName{ShortName: "c2pnb304w1", LongName: "c2pnb304w1"} + oidDotNotationToNames["1.2.840.10045.3.0.18"] = OIDName{ShortName: "c2tnb359v1", LongName: "c2tnb359v1"} + oidDotNotationToNames["1.2.840.10045.3.0.19"] = OIDName{ShortName: "c2pnb368w1", LongName: "c2pnb368w1"} + oidDotNotationToNames["1.2.840.10045.3.0.20"] = OIDName{ShortName: "c2tnb431r1", LongName: "c2tnb431r1"} + oidDotNotationToNames["1.3.132.0.6"] = OIDName{ShortName: "secp112r1", LongName: "secp112r1"} + oidDotNotationToNames["1.3.132.0.7"] = OIDName{ShortName: "secp112r2", LongName: "secp112r2"} + oidDotNotationToNames["1.3.132.0.28"] = OIDName{ShortName: "secp128r1", LongName: "secp128r1"} + oidDotNotationToNames["1.3.132.0.29"] = OIDName{ShortName: "secp128r2", LongName: "secp128r2"} + oidDotNotationToNames["1.3.132.0.9"] = OIDName{ShortName: "secp160k1", LongName: "secp160k1"} + oidDotNotationToNames["1.3.132.0.8"] = OIDName{ShortName: "secp160r1", LongName: "secp160r1"} + oidDotNotationToNames["1.3.132.0.30"] = OIDName{ShortName: "secp160r2", LongName: "secp160r2"} + oidDotNotationToNames["1.3.132.0.31"] = OIDName{ShortName: "secp192k1", LongName: "secp192k1"} + oidDotNotationToNames["1.3.132.0.32"] = OIDName{ShortName: "secp224k1", LongName: "secp224k1"} + oidDotNotationToNames["1.3.132.0.33"] = OIDName{ShortName: "secp224r1", LongName: "secp224r1"} + oidDotNotationToNames["1.3.132.0.10"] = OIDName{ShortName: "secp256k1", LongName: "secp256k1"} + oidDotNotationToNames["1.3.132.0.34"] = OIDName{ShortName: "secp384r1", LongName: "secp384r1"} + oidDotNotationToNames["1.3.132.0.35"] = OIDName{ShortName: "secp521r1", LongName: "secp521r1"} + oidDotNotationToNames["1.3.132.0.4"] = OIDName{ShortName: "sect113r1", LongName: "sect113r1"} + oidDotNotationToNames["1.3.132.0.5"] = OIDName{ShortName: "sect113r2", LongName: "sect113r2"} + oidDotNotationToNames["1.3.132.0.22"] = OIDName{ShortName: "sect131r1", LongName: "sect131r1"} + oidDotNotationToNames["1.3.132.0.23"] = OIDName{ShortName: "sect131r2", LongName: "sect131r2"} + oidDotNotationToNames["1.3.132.0.1"] = OIDName{ShortName: "sect163k1", LongName: "sect163k1"} + oidDotNotationToNames["1.3.132.0.2"] = OIDName{ShortName: "sect163r1", LongName: "sect163r1"} + oidDotNotationToNames["1.3.132.0.15"] = OIDName{ShortName: "sect163r2", LongName: "sect163r2"} + oidDotNotationToNames["1.3.132.0.24"] = OIDName{ShortName: "sect193r1", LongName: "sect193r1"} + oidDotNotationToNames["1.3.132.0.25"] = OIDName{ShortName: "sect193r2", LongName: "sect193r2"} + oidDotNotationToNames["1.3.132.0.26"] = OIDName{ShortName: "sect233k1", LongName: "sect233k1"} + oidDotNotationToNames["1.3.132.0.27"] = OIDName{ShortName: "sect233r1", LongName: "sect233r1"} + oidDotNotationToNames["1.3.132.0.3"] = OIDName{ShortName: "sect239k1", LongName: "sect239k1"} + oidDotNotationToNames["1.3.132.0.16"] = OIDName{ShortName: "sect283k1", LongName: "sect283k1"} + oidDotNotationToNames["1.3.132.0.17"] = OIDName{ShortName: "sect283r1", LongName: "sect283r1"} + oidDotNotationToNames["1.3.132.0.36"] = OIDName{ShortName: "sect409k1", LongName: "sect409k1"} + oidDotNotationToNames["1.3.132.0.37"] = OIDName{ShortName: "sect409r1", LongName: "sect409r1"} + oidDotNotationToNames["1.3.132.0.38"] = OIDName{ShortName: "sect571k1", LongName: "sect571k1"} + oidDotNotationToNames["1.3.132.0.39"] = OIDName{ShortName: "sect571r1", LongName: "sect571r1"} + oidDotNotationToNames["2.23.43.1.4.1"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls1", LongName: "wap-wsg-idm-ecid-wtls1"} + oidDotNotationToNames["2.23.43.1.4.3"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls3", LongName: "wap-wsg-idm-ecid-wtls3"} + oidDotNotationToNames["2.23.43.1.4.4"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls4", LongName: "wap-wsg-idm-ecid-wtls4"} + oidDotNotationToNames["2.23.43.1.4.5"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls5", LongName: "wap-wsg-idm-ecid-wtls5"} + oidDotNotationToNames["2.23.43.1.4.6"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls6", LongName: "wap-wsg-idm-ecid-wtls6"} + oidDotNotationToNames["2.23.43.1.4.7"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls7", LongName: "wap-wsg-idm-ecid-wtls7"} + oidDotNotationToNames["2.23.43.1.4.8"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls8", LongName: "wap-wsg-idm-ecid-wtls8"} + oidDotNotationToNames["2.23.43.1.4.9"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls9", LongName: "wap-wsg-idm-ecid-wtls9"} + oidDotNotationToNames["2.23.43.1.4.10"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls10", LongName: "wap-wsg-idm-ecid-wtls10"} + oidDotNotationToNames["2.23.43.1.4.11"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls11", LongName: "wap-wsg-idm-ecid-wtls11"} + oidDotNotationToNames["2.23.43.1.4.12"] = OIDName{ShortName: "wap-wsg-idm-ecid-wtls12", LongName: "wap-wsg-idm-ecid-wtls12"} + oidDotNotationToNames["2.5.29.32.0"] = OIDName{ShortName: "anyPolicy", LongName: "X509v3 Any Policy"} + oidDotNotationToNames["2.5.29.33"] = OIDName{ShortName: "policyMappings", LongName: "X509v3 Policy Mappings"} + oidDotNotationToNames["2.5.29.54"] = OIDName{ShortName: "inhibitAnyPolicy", LongName: "X509v3 Inhibit Any Policy"} + oidDotNotationToNames["1.2.392.200011.61.1.1.1.2"] = OIDName{ShortName: "CAMELLIA-128-CBC", LongName: "camellia-128-cbc"} + oidDotNotationToNames["1.2.392.200011.61.1.1.1.3"] = OIDName{ShortName: "CAMELLIA-192-CBC", LongName: "camellia-192-cbc"} + oidDotNotationToNames["1.2.392.200011.61.1.1.1.4"] = OIDName{ShortName: "CAMELLIA-256-CBC", LongName: "camellia-256-cbc"} + oidDotNotationToNames["0.3.4401.5.3.1.9.1"] = OIDName{ShortName: "CAMELLIA-128-ECB", LongName: "camellia-128-ecb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.21"] = OIDName{ShortName: "CAMELLIA-192-ECB", LongName: "camellia-192-ecb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.41"] = OIDName{ShortName: "CAMELLIA-256-ECB", LongName: "camellia-256-ecb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.4"] = OIDName{ShortName: "CAMELLIA-128-CFB", LongName: "camellia-128-cfb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.24"] = OIDName{ShortName: "CAMELLIA-192-CFB", LongName: "camellia-192-cfb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.44"] = OIDName{ShortName: "CAMELLIA-256-CFB", LongName: "camellia-256-cfb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.3"] = OIDName{ShortName: "CAMELLIA-128-OFB", LongName: "camellia-128-ofb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.23"] = OIDName{ShortName: "CAMELLIA-192-OFB", LongName: "camellia-192-ofb"} + oidDotNotationToNames["0.3.4401.5.3.1.9.43"] = OIDName{ShortName: "CAMELLIA-256-OFB", LongName: "camellia-256-ofb"} + oidDotNotationToNames["2.5.29.9"] = OIDName{ShortName: "subjectDirectoryAttributes", LongName: "X509v3 Subject Directory Attributes"} + oidDotNotationToNames["2.5.29.28"] = OIDName{ShortName: "issuingDistributionPoint", LongName: "X509v3 Issuing Distrubution Point"} + oidDotNotationToNames["2.5.29.29"] = OIDName{ShortName: "certificateIssuer", LongName: "X509v3 Certificate Issuer"} + oidDotNotationToNames["1.2.410.200004"] = OIDName{ShortName: "KISA", LongName: "kisa"} + oidDotNotationToNames["1.2.410.200004.1.3"] = OIDName{ShortName: "SEED-ECB", LongName: "seed-ecb"} + oidDotNotationToNames["1.2.410.200004.1.4"] = OIDName{ShortName: "SEED-CBC", LongName: "seed-cbc"} + oidDotNotationToNames["1.2.410.200004.1.6"] = OIDName{ShortName: "SEED-OFB", LongName: "seed-ofb"} + oidDotNotationToNames["1.2.410.200004.1.5"] = OIDName{ShortName: "SEED-CFB", LongName: "seed-cfb"} + oidDotNotationToNames["1.3.6.1.5.5.8.1.1"] = OIDName{ShortName: "HMAC-MD5", LongName: "hmac-md5"} + oidDotNotationToNames["1.3.6.1.5.5.8.1.2"] = OIDName{ShortName: "HMAC-SHA1", LongName: "hmac-sha1"} + oidDotNotationToNames["1.2.840.113533.7.66.13"] = OIDName{ShortName: "id-PasswordBasedMAC", LongName: "password based MAC"} + oidDotNotationToNames["1.2.840.113533.7.66.30"] = OIDName{ShortName: "id-DHBasedMac", LongName: "Diffie-Hellman based MAC"} + oidDotNotationToNames["1.3.6.1.5.5.7.4.16"] = OIDName{ShortName: "id-it-suppLangTags", LongName: "id-it-suppLangTags"} + oidDotNotationToNames["1.3.6.1.5.5.7.48.5"] = OIDName{ShortName: "caRepository", LongName: "CA Repository"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.9"] = OIDName{ShortName: "id-smime-ct-compressedData", LongName: "id-smime-ct-compressedData"} + oidDotNotationToNames["1.2.840.113549.1.9.16.1.27"] = OIDName{ShortName: "id-ct-asciiTextWithCRLF", LongName: "id-ct-asciiTextWithCRLF"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.5"] = OIDName{ShortName: "id-aes128-wrap", LongName: "id-aes128-wrap"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.25"] = OIDName{ShortName: "id-aes192-wrap", LongName: "id-aes192-wrap"} + oidDotNotationToNames["2.16.840.1.101.3.4.1.45"] = OIDName{ShortName: "id-aes256-wrap", LongName: "id-aes256-wrap"} + oidDotNotationToNames["1.2.840.10045.4.2"] = OIDName{ShortName: "ecdsa-with-Recommended", LongName: "ecdsa-with-Recommended"} + oidDotNotationToNames["1.2.840.10045.4.3"] = OIDName{ShortName: "ecdsa-with-Specified", LongName: "ecdsa-with-Specified"} + oidDotNotationToNames["1.2.840.10045.4.3.1"] = OIDName{ShortName: "ecdsa-with-SHA224", LongName: "ecdsa-with-SHA224"} + oidDotNotationToNames["1.2.840.10045.4.3.2"] = OIDName{ShortName: "ecdsa-with-SHA256", LongName: "ecdsa-with-SHA256"} + oidDotNotationToNames["1.2.840.10045.4.3.3"] = OIDName{ShortName: "ecdsa-with-SHA384", LongName: "ecdsa-with-SHA384"} + oidDotNotationToNames["1.2.840.10045.4.3.4"] = OIDName{ShortName: "ecdsa-with-SHA512", LongName: "ecdsa-with-SHA512"} + oidDotNotationToNames["1.2.840.113549.2.6"] = OIDName{ShortName: "hmacWithMD5", LongName: "hmacWithMD5"} + oidDotNotationToNames["1.2.840.113549.2.8"] = OIDName{ShortName: "hmacWithSHA224", LongName: "hmacWithSHA224"} + oidDotNotationToNames["1.2.840.113549.2.9"] = OIDName{ShortName: "hmacWithSHA256", LongName: "hmacWithSHA256"} + oidDotNotationToNames["1.2.840.113549.2.10"] = OIDName{ShortName: "hmacWithSHA384", LongName: "hmacWithSHA384"} + oidDotNotationToNames["1.2.840.113549.2.11"] = OIDName{ShortName: "hmacWithSHA512", LongName: "hmacWithSHA512"} + oidDotNotationToNames["2.16.840.1.101.3.4.3.1"] = OIDName{ShortName: "dsa_with_SHA224", LongName: "dsa_with_SHA224"} + oidDotNotationToNames["2.16.840.1.101.3.4.3.2"] = OIDName{ShortName: "dsa_with_SHA256", LongName: "dsa_with_SHA256"} + oidDotNotationToNames["1.0.10118.3.0.55"] = OIDName{ShortName: "whirlpool", LongName: "whirlpool"} + oidDotNotationToNames["1.2.643.2.2"] = OIDName{ShortName: "cryptopro", LongName: "cryptopro"} + oidDotNotationToNames["1.2.643.2.9"] = OIDName{ShortName: "cryptocom", LongName: "cryptocom"} + oidDotNotationToNames["1.2.643.2.2.3"] = OIDName{ShortName: "id-GostR3411-94-with-GostR3410-2001", LongName: "GOST R 34.11-94 with GOST R 34.10-2001"} + oidDotNotationToNames["1.2.643.2.2.4"] = OIDName{ShortName: "id-GostR3411-94-with-GostR3410-94", LongName: "GOST R 34.11-94 with GOST R 34.10-94"} + oidDotNotationToNames["1.2.643.2.2.9"] = OIDName{ShortName: "md_gost94", LongName: "GOST R 34.11-94"} + oidDotNotationToNames["1.2.643.2.2.10"] = OIDName{ShortName: "id-HMACGostR3411-94", LongName: "HMAC GOST 34.11-94"} + oidDotNotationToNames["1.2.643.2.2.19"] = OIDName{ShortName: "gost2001", LongName: "GOST R 34.10-2001"} + oidDotNotationToNames["1.2.643.2.2.20"] = OIDName{ShortName: "gost94", LongName: "GOST R 34.10-94"} + oidDotNotationToNames["1.2.643.2.2.21"] = OIDName{ShortName: "gost89", LongName: "GOST 28147-89"} + oidDotNotationToNames["1.2.643.2.2.22"] = OIDName{ShortName: "gost-mac", LongName: "GOST 28147-89 MAC"} + oidDotNotationToNames["1.2.643.2.2.23"] = OIDName{ShortName: "prf-gostr3411-94", LongName: "GOST R 34.11-94 PRF"} + oidDotNotationToNames["1.2.643.2.2.98"] = OIDName{ShortName: "id-GostR3410-2001DH", LongName: "GOST R 34.10-2001 DH"} + oidDotNotationToNames["1.2.643.2.2.99"] = OIDName{ShortName: "id-GostR3410-94DH", LongName: "GOST R 34.10-94 DH"} + oidDotNotationToNames["1.2.643.2.2.14.1"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-KeyMeshing", LongName: "id-Gost28147-89-CryptoPro-KeyMeshing"} + oidDotNotationToNames["1.2.643.2.2.14.0"] = OIDName{ShortName: "id-Gost28147-89-None-KeyMeshing", LongName: "id-Gost28147-89-None-KeyMeshing"} + oidDotNotationToNames["1.2.643.2.2.30.0"] = OIDName{ShortName: "id-GostR3411-94-TestParamSet", LongName: "id-GostR3411-94-TestParamSet"} + oidDotNotationToNames["1.2.643.2.2.30.1"] = OIDName{ShortName: "id-GostR3411-94-CryptoProParamSet", LongName: "id-GostR3411-94-CryptoProParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.0"] = OIDName{ShortName: "id-Gost28147-89-TestParamSet", LongName: "id-Gost28147-89-TestParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.1"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-A-ParamSet", LongName: "id-Gost28147-89-CryptoPro-A-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.2"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-B-ParamSet", LongName: "id-Gost28147-89-CryptoPro-B-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.3"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-C-ParamSet", LongName: "id-Gost28147-89-CryptoPro-C-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.4"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-D-ParamSet", LongName: "id-Gost28147-89-CryptoPro-D-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.5"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", LongName: "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.6"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", LongName: "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.31.7"] = OIDName{ShortName: "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", LongName: "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.32.0"] = OIDName{ShortName: "id-GostR3410-94-TestParamSet", LongName: "id-GostR3410-94-TestParamSet"} + oidDotNotationToNames["1.2.643.2.2.32.2"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-A-ParamSet", LongName: "id-GostR3410-94-CryptoPro-A-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.32.3"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-B-ParamSet", LongName: "id-GostR3410-94-CryptoPro-B-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.32.4"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-C-ParamSet", LongName: "id-GostR3410-94-CryptoPro-C-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.32.5"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-D-ParamSet", LongName: "id-GostR3410-94-CryptoPro-D-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.33.1"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-XchA-ParamSet", LongName: "id-GostR3410-94-CryptoPro-XchA-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.33.2"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-XchB-ParamSet", LongName: "id-GostR3410-94-CryptoPro-XchB-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.33.3"] = OIDName{ShortName: "id-GostR3410-94-CryptoPro-XchC-ParamSet", LongName: "id-GostR3410-94-CryptoPro-XchC-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.35.0"] = OIDName{ShortName: "id-GostR3410-2001-TestParamSet", LongName: "id-GostR3410-2001-TestParamSet"} + oidDotNotationToNames["1.2.643.2.2.35.1"] = OIDName{ShortName: "id-GostR3410-2001-CryptoPro-A-ParamSet", LongName: "id-GostR3410-2001-CryptoPro-A-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.35.2"] = OIDName{ShortName: "id-GostR3410-2001-CryptoPro-B-ParamSet", LongName: "id-GostR3410-2001-CryptoPro-B-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.35.3"] = OIDName{ShortName: "id-GostR3410-2001-CryptoPro-C-ParamSet", LongName: "id-GostR3410-2001-CryptoPro-C-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.36.0"] = OIDName{ShortName: "id-GostR3410-2001-CryptoPro-XchA-ParamSet", LongName: "id-GostR3410-2001-CryptoPro-XchA-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.36.1"] = OIDName{ShortName: "id-GostR3410-2001-CryptoPro-XchB-ParamSet", LongName: "id-GostR3410-2001-CryptoPro-XchB-ParamSet"} + oidDotNotationToNames["1.2.643.2.2.20.1"] = OIDName{ShortName: "id-GostR3410-94-a", LongName: "id-GostR3410-94-a"} + oidDotNotationToNames["1.2.643.2.2.20.2"] = OIDName{ShortName: "id-GostR3410-94-aBis", LongName: "id-GostR3410-94-aBis"} + oidDotNotationToNames["1.2.643.2.2.20.3"] = OIDName{ShortName: "id-GostR3410-94-b", LongName: "id-GostR3410-94-b"} + oidDotNotationToNames["1.2.643.2.2.20.4"] = OIDName{ShortName: "id-GostR3410-94-bBis", LongName: "id-GostR3410-94-bBis"} + oidDotNotationToNames["1.2.643.2.9.1.6.1"] = OIDName{ShortName: "id-Gost28147-89-cc", LongName: "GOST 28147-89 Cryptocom ParamSet"} + oidDotNotationToNames["1.2.643.2.9.1.5.3"] = OIDName{ShortName: "gost94cc", LongName: "GOST 34.10-94 Cryptocom"} + oidDotNotationToNames["1.2.643.2.9.1.5.4"] = OIDName{ShortName: "gost2001cc", LongName: "GOST 34.10-2001 Cryptocom"} + oidDotNotationToNames["1.2.643.2.9.1.3.3"] = OIDName{ShortName: "id-GostR3411-94-with-GostR3410-94-cc", LongName: "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"} + oidDotNotationToNames["1.2.643.2.9.1.3.4"] = OIDName{ShortName: "id-GostR3411-94-with-GostR3410-2001-cc", LongName: "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"} + oidDotNotationToNames["1.2.643.2.9.1.8.1"] = OIDName{ShortName: "id-GostR3410-2001-ParamSet-cc", LongName: "GOST R 3410-2001 Parameter Set Cryptocom"} + oidDotNotationToNames["1.3.6.1.4.1.311.17.2"] = OIDName{ShortName: "LocalKeySet", LongName: "Microsoft Local Key set"} + oidDotNotationToNames["2.5.29.46"] = OIDName{ShortName: "freshestCRL", LongName: "X509v3 Freshest CRL"} + oidDotNotationToNames["1.3.6.1.5.5.7.8.3"] = OIDName{ShortName: "id-on-permanentIdentifier", LongName: "Permanent Identifier"} + oidDotNotationToNames["2.5.4.14"] = OIDName{ShortName: "searchGuide", LongName: "searchGuide"} + oidDotNotationToNames["2.5.4.15"] = OIDName{ShortName: "businessCategory", LongName: "businessCategory"} + oidDotNotationToNames["2.5.4.16"] = OIDName{ShortName: "postalAddress", LongName: "postalAddress"} + oidDotNotationToNames["2.5.4.18"] = OIDName{ShortName: "postOfficeBox", LongName: "postOfficeBox"} + oidDotNotationToNames["2.5.4.19"] = OIDName{ShortName: "physicalDeliveryOfficeName", LongName: "physicalDeliveryOfficeName"} + oidDotNotationToNames["2.5.4.20"] = OIDName{ShortName: "telephoneNumber", LongName: "telephoneNumber"} + oidDotNotationToNames["2.5.4.21"] = OIDName{ShortName: "telexNumber", LongName: "telexNumber"} + oidDotNotationToNames["2.5.4.22"] = OIDName{ShortName: "teletexTerminalIdentifier", LongName: "teletexTerminalIdentifier"} + oidDotNotationToNames["2.5.4.23"] = OIDName{ShortName: "facsimileTelephoneNumber", LongName: "facsimileTelephoneNumber"} + oidDotNotationToNames["2.5.4.24"] = OIDName{ShortName: "x121Address", LongName: "x121Address"} + oidDotNotationToNames["2.5.4.25"] = OIDName{ShortName: "internationaliSDNNumber", LongName: "internationaliSDNNumber"} + oidDotNotationToNames["2.5.4.26"] = OIDName{ShortName: "registeredAddress", LongName: "registeredAddress"} + oidDotNotationToNames["2.5.4.27"] = OIDName{ShortName: "destinationIndicator", LongName: "destinationIndicator"} + oidDotNotationToNames["2.5.4.28"] = OIDName{ShortName: "preferredDeliveryMethod", LongName: "preferredDeliveryMethod"} + oidDotNotationToNames["2.5.4.29"] = OIDName{ShortName: "presentationAddress", LongName: "presentationAddress"} + oidDotNotationToNames["2.5.4.30"] = OIDName{ShortName: "supportedApplicationContext", LongName: "supportedApplicationContext"} + oidDotNotationToNames["2.5.4.31"] = OIDName{ShortName: "member", LongName: "member"} + oidDotNotationToNames["2.5.4.32"] = OIDName{ShortName: "owner", LongName: "owner"} + oidDotNotationToNames["2.5.4.33"] = OIDName{ShortName: "roleOccupant", LongName: "roleOccupant"} + oidDotNotationToNames["2.5.4.34"] = OIDName{ShortName: "seeAlso", LongName: "seeAlso"} + oidDotNotationToNames["2.5.4.35"] = OIDName{ShortName: "userPassword", LongName: "userPassword"} + oidDotNotationToNames["2.5.4.36"] = OIDName{ShortName: "userCertificate", LongName: "userCertificate"} + oidDotNotationToNames["2.5.4.37"] = OIDName{ShortName: "cACertificate", LongName: "cACertificate"} + oidDotNotationToNames["2.5.4.38"] = OIDName{ShortName: "authorityRevocationList", LongName: "authorityRevocationList"} + oidDotNotationToNames["2.5.4.39"] = OIDName{ShortName: "certificateRevocationList", LongName: "certificateRevocationList"} + oidDotNotationToNames["2.5.4.40"] = OIDName{ShortName: "crossCertificatePair", LongName: "crossCertificatePair"} + oidDotNotationToNames["2.5.4.47"] = OIDName{ShortName: "enhancedSearchGuide", LongName: "enhancedSearchGuide"} + oidDotNotationToNames["2.5.4.48"] = OIDName{ShortName: "protocolInformation", LongName: "protocolInformation"} + oidDotNotationToNames["2.5.4.49"] = OIDName{ShortName: "distinguishedName", LongName: "distinguishedName"} + oidDotNotationToNames["2.5.4.50"] = OIDName{ShortName: "uniqueMember", LongName: "uniqueMember"} + oidDotNotationToNames["2.5.4.51"] = OIDName{ShortName: "houseIdentifier", LongName: "houseIdentifier"} + oidDotNotationToNames["2.5.4.52"] = OIDName{ShortName: "supportedAlgorithms", LongName: "supportedAlgorithms"} + oidDotNotationToNames["2.5.4.53"] = OIDName{ShortName: "deltaRevocationList", LongName: "deltaRevocationList"} + oidDotNotationToNames["2.5.4.54"] = OIDName{ShortName: "dmdName", LongName: "dmdName"} + oidDotNotationToNames["1.3.6.1.4.1.311.17.1"] = OIDName{ShortName: "MS_LOCAL_MACHINE_KEYSET", LongName: "MS_LOCAL_MACHINE_KEYSET"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.4.1"] = OIDName{ShortName: "MS_YESNO_TRUST_ATTR", LongName: "MS_YESNO_TRUST_ATTR"} + oidDotNotationToNames["1.3.6.1.4.1.311.13.2.1"] = OIDName{ShortName: "MS_ENROLLMENT_NAME_VALUE_PAIR", LongName: "MS_ENROLLMENT_NAME_VALUE_PAIR"} + oidDotNotationToNames["1.3.6.1.4.1.311.13.2.3"] = OIDName{ShortName: "MS_OS_VERSION", LongName: "MS_OS_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.13.2.2"] = OIDName{ShortName: "MS_ENROLLMENT_CSP_PROVIDER", LongName: "MS_ENROLLMENT_CSP_PROVIDER"} + oidDotNotationToNames["1.3.6.1.4.1.311.12.1.2"] = OIDName{ShortName: "MS_CATALOG_LIST_MEMBER", LongName: "MS_CATALOG_LIST_MEMBER"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.11"] = OIDName{ShortName: "MS_CERT_PROP_ID_PREFIX", LongName: "MS_CERT_PROP_ID_PREFIX"} + oidDotNotationToNames["1.3.6.1.4.1.311.13.1"] = OIDName{ShortName: "MS_RENEWAL_CERTIFICATE", LongName: "MS_RENEWAL_CERTIFICATE"} + oidDotNotationToNames["1.3.6.1.4.1.311"] = OIDName{ShortName: "MS_OID", LongName: "MS_OID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.30"] = OIDName{ShortName: "MS_SPC_SIPINFO_OBJID", LongName: "MS_SPC_SIPINFO_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.3"] = OIDName{ShortName: "MS_CAPICOM_ENCRYPTED_DATA", LongName: "MS_CAPICOM_ENCRYPTED_DATA"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.2"] = OIDName{ShortName: "MS_CAPICOM_ATTRIBUTE", LongName: "MS_CAPICOM_ATTRIBUTE"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.1"] = OIDName{ShortName: "MS_CAPICOM_VERSION", LongName: "MS_CAPICOM_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.6.2"] = OIDName{ShortName: "MS_LICENSE_SERVER", LongName: "MS_LICENSE_SERVER"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.10.1"] = OIDName{ShortName: "MS_CMC_ADD_ATTRIBUTES", LongName: "MS_CMC_ADD_ATTRIBUTES"} + oidDotNotationToNames["1.3.6.1.4.1.311.3.2.1"] = OIDName{ShortName: "MS_SPC_TIME_STAMP_REQUEST_OBJID", LongName: "MS_SPC_TIME_STAMP_REQUEST_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.12.1"] = OIDName{ShortName: "MS_ANY_APPLICATION_POLICY", LongName: "MS_ANY_APPLICATION_POLICY"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.0.4"] = OIDName{ShortName: "MS_PEERNET_CERT_VERSION", LongName: "MS_PEERNET_CERT_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.19"] = OIDName{ShortName: "MS_DS_EMAIL_REPLICATION", LongName: "MS_DS_EMAIL_REPLICATION"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.16"] = OIDName{ShortName: "MS_ARCHIVED_KEY_CERT_HASH", LongName: "MS_ARCHIVED_KEY_CERT_HASH"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.17"] = OIDName{ShortName: "MS_ISSUED_CERT_HASH", LongName: "MS_ISSUED_CERT_HASH"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.14"] = OIDName{ShortName: "MS_CRL_SELF_CDP", LongName: "MS_CRL_SELF_CDP"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.15"] = OIDName{ShortName: "MS_REQUIRE_CERT_CHAIN_POLICY", LongName: "MS_REQUIRE_CERT_CHAIN_POLICY"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.12"] = OIDName{ShortName: "MS_APPLICATION_POLICY_CONSTRAINTS", LongName: "MS_APPLICATION_POLICY_CONSTRAINTS"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.13"] = OIDName{ShortName: "MS_ARCHIVED_KEY_ATTR", LongName: "MS_ARCHIVED_KEY_ATTR"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.10"] = OIDName{ShortName: "MS_APPLICATION_CERT_POLICIES", LongName: "MS_APPLICATION_CERT_POLICIES"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.11"] = OIDName{ShortName: "MS_APPLICATION_POLICY_MAPPINGS", LongName: "MS_APPLICATION_POLICY_MAPPINGS"} + oidDotNotationToNames["1.3.6.1.4.1.311.44"] = OIDName{ShortName: "MS_Peer_Networking", LongName: "MS_Peer_Networking"} + oidDotNotationToNames["1.3.6.1.4.1.311.12.2.1"] = OIDName{ShortName: "MS_CAT_NAMEVALUE_OBJID", LongName: "MS_CAT_NAMEVALUE_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.5.1"] = OIDName{ShortName: "MS_DRM", LongName: "MS_DRM"} + oidDotNotationToNames["1.3.6.1.4.1.311.43"] = OIDName{ShortName: "MS_WWOps_BizExt", LongName: "MS_WWOps_BizExt"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.5.2"] = OIDName{ShortName: "MS_DRM_INDIVIDUALIZATION", LongName: "MS_DRM_INDIVIDUALIZATION"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.13"] = OIDName{ShortName: "MS_KP_LIFETIME_SIGNING", LongName: "MS_KP_LIFETIME_SIGNING"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.12"] = OIDName{ShortName: "MS_KP_DOCUMENT_SIGNING", LongName: "MS_KP_DOCUMENT_SIGNING"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.11"] = OIDName{ShortName: "MS_KP_KEY_RECOVERY", LongName: "MS_KP_KEY_RECOVERY"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.10"] = OIDName{ShortName: "MS_KP_QUALIFIED_SUBORDINATION", LongName: "MS_KP_QUALIFIED_SUBORDINATION"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.1"] = OIDName{ShortName: "MS_PKIX_LICENSE_INFO", LongName: "MS_PKIX_LICENSE_INFO"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.2"] = OIDName{ShortName: "MS_PKIX_MANUFACTURER", LongName: "MS_PKIX_MANUFACTURER"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.3"] = OIDName{ShortName: "MS_PKIX_MANUFACTURER_MS_SPECIFIC", LongName: "MS_PKIX_MANUFACTURER_MS_SPECIFIC"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.4"] = OIDName{ShortName: "MS_PKIX_HYDRA_CERT_VERSION", LongName: "MS_PKIX_HYDRA_CERT_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.5"] = OIDName{ShortName: "MS_PKIX_LICENSED_PRODUCT_INFO", LongName: "MS_PKIX_LICENSED_PRODUCT_INFO"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.6"] = OIDName{ShortName: "MS_PKIX_MS_LICENSE_SERVER_INFO", LongName: "MS_PKIX_MS_LICENSE_SERVER_INFO"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.7"] = OIDName{ShortName: "MS_PKIS_PRODUCT_SPECIFIC_OID", LongName: "MS_PKIS_PRODUCT_SPECIFIC_OID"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.22"] = OIDName{ShortName: "MS_CERTSRV_CROSSCA_VERSION", LongName: "MS_CERTSRV_CROSSCA_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.21"] = OIDName{ShortName: "MS_ENCRYPTED_KEY_HASH", LongName: "MS_ENCRYPTED_KEY_HASH"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.20"] = OIDName{ShortName: "MS_REQUEST_CLIENT_INFO", LongName: "MS_REQUEST_CLIENT_INFO"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.3"] = OIDName{ShortName: "MS_CERT_MANIFOLD", LongName: "MS_CERT_MANIFOLD"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.1.1"] = OIDName{ShortName: "MS_SORTED_CTL", LongName: "MS_SORTED_CTL"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.1.3"] = OIDName{ShortName: "MS_PEERNET_PNRP_PAYLOAD", LongName: "MS_PEERNET_PNRP_PAYLOAD"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.7.1"] = OIDName{ShortName: "MS_KEYID_RDN", LongName: "MS_KEYID_RDN"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.1.1"] = OIDName{ShortName: "MS_PEERNET_PNRP_ADDRESS", LongName: "MS_PEERNET_PNRP_ADDRESS"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.8"] = OIDName{ShortName: "MS_ENTERPRISE_OID_ROOT", LongName: "MS_ENTERPRISE_OID_ROOT"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.1.4"] = OIDName{ShortName: "MS_PEERNET_PNRP_ID", LongName: "MS_PEERNET_PNRP_ID"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.3.1"] = OIDName{ShortName: "MS_PEERNET_GROUPING_PEERNAME", LongName: "MS_PEERNET_GROUPING_PEERNAME"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.12"] = OIDName{ShortName: "MS_CryptUI", LongName: "MS_CryptUI"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.10"] = OIDName{ShortName: "MS_CMC_OIDs", LongName: "MS_CMC_OIDs"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.11"] = OIDName{ShortName: "MS_certificate_property_OIDs", LongName: "MS_certificate_property_OIDs"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.4"] = OIDName{ShortName: "MS_SPC_INDIRECT_DATA_OBJID", LongName: "MS_SPC_INDIRECT_DATA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.2"] = OIDName{ShortName: "MS_CTL_for_Software_Publishers_Trusted_CAs", LongName: "MS_CTL_for_Software_Publishers_Trusted_CAs"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.3.5"] = OIDName{ShortName: "MS_PEERNET_GROUPING_CLASSIFIERS", LongName: "MS_PEERNET_GROUPING_CLASSIFIERS"} + oidDotNotationToNames["1.3.6.1.4.1.311.2"] = OIDName{ShortName: "MS_Authenticode", LongName: "MS_Authenticode"} + oidDotNotationToNames["1.3.6.1.4.1.311.3"] = OIDName{ShortName: "MS_Time_Stamping", LongName: "MS_Time_Stamping"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.7"] = OIDName{ShortName: "MS_CERTIFICATE_TEMPLATE", LongName: "MS_CERTIFICATE_TEMPLATE"} + oidDotNotationToNames["1.3.6.1.4.1.311.4"] = OIDName{ShortName: "MS_Permissions", LongName: "MS_Permissions"} + oidDotNotationToNames["1.3.6.1.4.1.311.30"] = OIDName{ShortName: "MS_IIS", LongName: "MS_IIS"} + oidDotNotationToNames["1.3.6.1.4.1.311.19"] = OIDName{ShortName: "MS_ISPU_Test", LongName: "MS_ISPU_Test"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.7"] = OIDName{ShortName: "MS_OEM_WHQL_CRYPTO", LongName: "MS_OEM_WHQL_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.6"] = OIDName{ShortName: "MS_NT5_CRYPTO", LongName: "MS_NT5_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.5"] = OIDName{ShortName: "MS_WHQL_CRYPTO", LongName: "MS_WHQL_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.4"] = OIDName{ShortName: "MS_EFS_CRYPTO", LongName: "MS_EFS_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2.3"] = OIDName{ShortName: "MS_NT_PRINCIPAL_NAME", LongName: "MS_NT_PRINCIPAL_NAME"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2.2"] = OIDName{ShortName: "MS_KP_SMARTCARD_LOGON", LongName: "MS_KP_SMARTCARD_LOGON"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2.1"] = OIDName{ShortName: "MS_ENROLLMENT_AGENT", LongName: "MS_ENROLLMENT_AGENT"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.9"] = OIDName{ShortName: "MS_ROOT_LIST_SIGNER", LongName: "MS_ROOT_LIST_SIGNER"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.8"] = OIDName{ShortName: "MS_EMBEDDED_NT_CRYPTO", LongName: "MS_EMBEDDED_NT_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.18.8"] = OIDName{ShortName: "MS_PKIS_TLSERVER_SPK_OID", LongName: "MS_PKIS_TLSERVER_SPK_OID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.2.2"] = OIDName{ShortName: "MS_TRUSTED_CLIENT_AUTH_CA_LIST", LongName: "MS_TRUSTED_CLIENT_AUTH_CA_LIST"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.2.3"] = OIDName{ShortName: "MS_TRUSTED_SERVER_AUTH_CA_LIST", LongName: "MS_TRUSTED_SERVER_AUTH_CA_LIST"} + oidDotNotationToNames["1.3.6.1.4.1.311.12.1.1"] = OIDName{ShortName: "MS_CATALOG_LIST", LongName: "MS_CATALOG_LIST"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.2.1"] = OIDName{ShortName: "MS_TRUSTED_CODESIGNING_CA_LIST", LongName: "MS_TRUSTED_CODESIGNING_CA_LIST"} + oidDotNotationToNames["1.3.6.1.4.1.311.45"] = OIDName{ShortName: "MS_Mobile_Devices_Code_Signing", LongName: "MS_Mobile_Devices_Code_Signing"} + oidDotNotationToNames["1.3.6.1.4.1.311.30.1"] = OIDName{ShortName: "MS_IIS_VIRTUAL_SERVER", LongName: "MS_IIS_VIRTUAL_SERVER"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.14"] = OIDName{ShortName: "MS_KP_MOBILE_DEVICE_SOFTWARE", LongName: "MS_KP_MOBILE_DEVICE_SOFTWARE"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.8.1"] = OIDName{ShortName: "MS_REMOVE_CERTIFICATE", LongName: "MS_REMOVE_CERTIFICATE"} + oidDotNotationToNames["1.3.6.1.4.1.311.42"] = OIDName{ShortName: "MS_Corporate_PKI_(ITG)", LongName: "MS_Corporate_PKI_(ITG)"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.26"] = OIDName{ShortName: "MS_SPC_MINIMAL_CRITERIA_OBJID", LongName: "MS_SPC_MINIMAL_CRITERIA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.3.2"] = OIDName{ShortName: "MS_PEERNET_GROUPING_FLAGS", LongName: "MS_PEERNET_GROUPING_FLAGS"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.3.3"] = OIDName{ShortName: "MS_PEERNET_GROUPING_ROLES", LongName: "MS_PEERNET_GROUPING_ROLES"} + oidDotNotationToNames["1.3.6.1.4.1.311.41"] = OIDName{ShortName: "MS_Licensing_and_Registration", LongName: "MS_Licensing_and_Registration"} + oidDotNotationToNames["1.3.6.1.4.1.311.20"] = OIDName{ShortName: "MS_Enrollment_Infrastructure", LongName: "MS_Enrollment_Infrastructure"} + oidDotNotationToNames["1.3.6.1.4.1.311.40"] = OIDName{ShortName: "MS_Fonts", LongName: "MS_Fonts"} + oidDotNotationToNames["1.3.6.1.4.1.311.21"] = OIDName{ShortName: "MS_CertSrv_Infrastructure", LongName: "MS_CertSrv_Infrastructure"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.3.1"] = OIDName{ShortName: "MS_SERIALIZED", LongName: "MS_SERIALIZED"} + oidDotNotationToNames["1.3.6.1.4.1.311.12.2.2"] = OIDName{ShortName: "MS_CAT_MEMBERINFO_OBJID", LongName: "MS_CAT_MEMBERINFO_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.25"] = OIDName{ShortName: "MS_Directory_Service", LongName: "MS_Directory_Service"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.0.3"] = OIDName{ShortName: "MS_PEERNET_CLASSIFIER", LongName: "MS_PEERNET_CLASSIFIER"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.0.1"] = OIDName{ShortName: "MS_PEERNET_CERT_TYPE", LongName: "MS_PEERNET_CERT_TYPE"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.1"] = OIDName{ShortName: "MS_PEERNET_PNRP", LongName: "MS_PEERNET_PNRP"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.3.1"] = OIDName{ShortName: "MS_CAPICOM_ENCRYPTED_CONTENT", LongName: "MS_CAPICOM_ENCRYPTED_CONTENT"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.0.2"] = OIDName{ShortName: "MS_PEERNET_PEERNAME", LongName: "MS_PEERNET_PEERNAME"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.3"] = OIDName{ShortName: "MS_PEERNET_GROUPING", LongName: "MS_PEERNET_GROUPING"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.1.2"] = OIDName{ShortName: "MS_PEERNET_PNRP_FLAGS", LongName: "MS_PEERNET_PNRP_FLAGS"} + oidDotNotationToNames["1.3.6.1.4.1.311.15"] = OIDName{ShortName: "MS_Java", LongName: "MS_Java"} + oidDotNotationToNames["1.3.6.1.4.1.311.16"] = OIDName{ShortName: "MS_Outlook/Exchange", LongName: "MS_Outlook/Exchange"} + oidDotNotationToNames["1.3.6.1.4.1.311.17"] = OIDName{ShortName: "MS_PKCS12_attributes", LongName: "MS_PKCS12_attributes"} + oidDotNotationToNames["1.3.6.1.4.1.311.10"] = OIDName{ShortName: "MS_Crypto_2.0", LongName: "MS_Crypto_2.0"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.9"] = OIDName{ShortName: "MS_RDN_DUMMY_SIGNER", LongName: "MS_RDN_DUMMY_SIGNER"} + oidDotNotationToNames["1.3.6.1.4.1.311.12"] = OIDName{ShortName: "MS_Catalog", LongName: "MS_Catalog"} + oidDotNotationToNames["1.3.6.1.4.1.311.13"] = OIDName{ShortName: "MS_PKCS10_OIDs", LongName: "MS_PKCS10_OIDs"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.4"] = OIDName{ShortName: "MS_CRL_NEXT_PUBLISH", LongName: "MS_CRL_NEXT_PUBLISH"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.5"] = OIDName{ShortName: "MS_KP_CA_EXCHANGE", LongName: "MS_KP_CA_EXCHANGE"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.6"] = OIDName{ShortName: "MS_KP_KEY_RECOVERY_AGENT", LongName: "MS_KP_KEY_RECOVERY_AGENT"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.6.1"] = OIDName{ShortName: "MS_LICENSES", LongName: "MS_LICENSES"} + oidDotNotationToNames["1.3.6.1.4.1.311.18"] = OIDName{ShortName: "MS_Hydra", LongName: "MS_Hydra"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.1"] = OIDName{ShortName: "MS_CERTSRV_CA_VERSION", LongName: "MS_CERTSRV_CA_VERSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.2"] = OIDName{ShortName: "MS_CERTSRV_PREVIOUS_CERT_HASH", LongName: "MS_CERTSRV_PREVIOUS_CERT_HASH"} + oidDotNotationToNames["1.3.6.1.4.1.311.21.3"] = OIDName{ShortName: "MS_CRL_VIRTUAL_BASE", LongName: "MS_CRL_VIRTUAL_BASE"} + oidDotNotationToNames["1.3.6.1.4.1.311.31.1"] = OIDName{ShortName: "MS_PRODUCT_UPDATE", LongName: "MS_PRODUCT_UPDATE"} + oidDotNotationToNames["1.3.6.1.4.1.311.16.4"] = OIDName{ShortName: "MS_MICROSOFT_Encryption_Key_Preference", LongName: "MS_MICROSOFT_Encryption_Key_Preference"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.2"] = OIDName{ShortName: "MS_PEERNET_IDENTITY", LongName: "MS_PEERNET_IDENTITY"} + oidDotNotationToNames["1.3.6.1.4.1.311.88"] = OIDName{ShortName: "MS_CAPICOM", LongName: "MS_CAPICOM"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.9.1"] = OIDName{ShortName: "MS_CROSS_CERT_DIST_POINTS", LongName: "MS_CROSS_CERT_DIST_POINTS"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.19"] = OIDName{ShortName: "MS_SPC_STRUCTURED_STORAGE_DATA_OBJID", LongName: "MS_SPC_STRUCTURED_STORAGE_DATA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.18"] = OIDName{ShortName: "MS_SPC_RAW_FILE_DATA_OBJID", LongName: "MS_SPC_RAW_FILE_DATA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.25"] = OIDName{ShortName: "MS_SPC_GLUE_RDN_OBJID", LongName: "MS_SPC_GLUE_RDN_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.11"] = OIDName{ShortName: "MS_SPC_STATEMENT_TYPE_OBJID", LongName: "MS_SPC_STATEMENT_TYPE_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.10"] = OIDName{ShortName: "MS_SPC_SP_AGENCY_INFO_OBJID", LongName: "MS_SPC_SP_AGENCY_INFO_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.4.1"] = OIDName{ShortName: "MS_EFS_RECOVERY", LongName: "MS_EFS_RECOVERY"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.12"] = OIDName{ShortName: "MS_SPC_SP_OPUS_INFO_OBJID", LongName: "MS_SPC_SP_OPUS_INFO_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.15"] = OIDName{ShortName: "MS_SPC_PE_IMAGE_DATA_OBJID", LongName: "MS_SPC_PE_IMAGE_DATA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.14"] = OIDName{ShortName: "MS_SPC_CERT_EXTENSIONS_OBJID", LongName: "MS_SPC_CERT_EXTENSIONS_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.25.1"] = OIDName{ShortName: "MS_NTDS_REPLICATION", LongName: "MS_NTDS_REPLICATION"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.27"] = OIDName{ShortName: "MS_SPC_FINANCIAL_CRITERIA_OBJID", LongName: "MS_SPC_FINANCIAL_CRITERIA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.3"] = OIDName{ShortName: "MS_SERVER_GATED_CRYPTO", LongName: "MS_SERVER_GATED_CRYPTO"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.11.1"] = OIDName{ShortName: "MS_CERT_PROP_ID_PREFIX", LongName: "MS_CERT_PROP_ID_PREFIX"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.2"] = OIDName{ShortName: "MS_KP_TIME_STAMP_SIGNING", LongName: "MS_KP_TIME_STAMP_SIGNING"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.3.1"] = OIDName{ShortName: "MS_KP_CTL_USAGE_SIGNING", LongName: "MS_KP_CTL_USAGE_SIGNING"} + oidDotNotationToNames["1.3.6.1.4.1.311.31"] = OIDName{ShortName: "MS_Windows_updates_and_service_packs", LongName: "MS_Windows_updates_and_service_packs"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.2.1"] = OIDName{ShortName: "MS_CAPICOM_DOCUMENT_NAME", LongName: "MS_CAPICOM_DOCUMENT_NAME"} + oidDotNotationToNames["1.3.6.1.4.1.311.88.2.2"] = OIDName{ShortName: "MS_CAPICOM_DOCUMENT_DESCRIPTION", LongName: "MS_CAPICOM_DOCUMENT_DESCRIPTION"} + oidDotNotationToNames["1.3.6.1.4.1.311.44.2.2"] = OIDName{ShortName: "MS_PEERNET_IDENTITY_FLAGS", LongName: "MS_PEERNET_IDENTITY_FLAGS"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.1"] = OIDName{ShortName: "MS_AUTO_ENROLL_CTL_USAGE", LongName: "MS_AUTO_ENROLL_CTL_USAGE"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.1"] = OIDName{ShortName: "MS_CTL", LongName: "MS_CTL"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.2"] = OIDName{ShortName: "MS_NEXT_UPDATE_LOCATION", LongName: "MS_NEXT_UPDATE_LOCATION"} + oidDotNotationToNames["1.3.6.1.4.1.311.20.2"] = OIDName{ShortName: "MS_ENROLL_CERTTYPE_EXTENSION", LongName: "MS_ENROLL_CERTTYPE_EXTENSION"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.20"] = OIDName{ShortName: "MS_SPC_JAVA_CLASS_DATA_OBJID", LongName: "MS_SPC_JAVA_CLASS_DATA_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.21"] = OIDName{ShortName: "MS_SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID", LongName: "MS_SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.22"] = OIDName{ShortName: "MS_SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID", LongName: "MS_SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID"} + oidDotNotationToNames["1.3.6.1.4.1.311.10.7"] = OIDName{ShortName: "MS_MICROSOFT_RDN_PREFIX", LongName: "MS_MICROSOFT_RDN_PREFIX"} + oidDotNotationToNames["1.3.6.1.4.1.311.2.1.28"] = OIDName{ShortName: "MS_SPC_LINK_OBJID", LongName: "MS_SPC_LINK_OBJID"} + // EV Certificates + oidDotNotationToNames["1.3.6.1.4.1.311.60.2.1.1"] = OIDName{ShortName: "jurisdictionLocality", LongName: "jurisdictionLocalityName"} + oidDotNotationToNames["1.3.6.1.4.1.311.60.2.1.2"] = OIDName{ShortName: "jurisdictionStateOrProvince", LongName: "jurisdictionStateOrProvinceName"} + oidDotNotationToNames["1.3.6.1.4.1.311.60.2.1.3"] = OIDName{ShortName: "jurisdictionCountry", LongName: "jurisdictionCountryName"} + +} diff --git a/vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go b/vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go new file mode 100644 index 0000000000..5f3f013c6b --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go @@ -0,0 +1,299 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkix contains shared, low level structures used for ASN.1 parsing +// and serialization of X.509 certificates, CRL and OCSP. +package pkix + +import ( + "encoding/asn1" + "math/big" + "strings" + "time" +) + +// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC +// 5280, section 4.1.1.2. +type AlgorithmIdentifier struct { + Algorithm asn1.ObjectIdentifier + Parameters asn1.RawValue `asn1:"optional"` +} + +type RDNSequence []RelativeDistinguishedNameSET + +type RelativeDistinguishedNameSET []AttributeTypeAndValue + +// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in +// http://tools.ietf.org/html/rfc5280#section-4.1.2.4 +type AttributeTypeAndValue struct { + Type asn1.ObjectIdentifier `json:"type"` + Value interface{} `json:"value"` +} + +// AttributeTypeAndValueSET represents a set of ASN.1 sequences of +// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10). +type AttributeTypeAndValueSET struct { + Type asn1.ObjectIdentifier + Value [][]AttributeTypeAndValue `asn1:"set"` +} + +// Extension represents the ASN.1 structure of the same name. See RFC +// 5280, section 4.2. +type Extension struct { + Id asn1.ObjectIdentifier + Critical bool `asn1:"optional"` + Value []byte +} + +// Name represents an X.509 distinguished name. This only includes the common +// elements of a DN. Additional elements in the name are ignored. +type Name struct { + Country, Organization, OrganizationalUnit []string + Locality, Province []string + StreetAddress, PostalCode, DomainComponent []string + EmailAddress []string + SerialNumber, CommonName string + SerialNumbers, CommonNames []string + GivenName, Surname []string + OrganizationIDs []string + // EV Components + JurisdictionLocality, JurisdictionProvince, JurisdictionCountry []string + + Names []AttributeTypeAndValue + ExtraNames []AttributeTypeAndValue + + // OriginalRDNS is saved if the name is populated using FillFromRDNSequence. + // Additionally, if OriginalRDNS is non-nil, the String and ToRDNSequence + // methods will simply use this. + OriginalRDNS RDNSequence +} + +// FillFromRDNSequence populates n based on the AttributeTypeAndValueSETs in the +// RDNSequence. It save the sequence as OriginalRDNS. +func (n *Name) FillFromRDNSequence(rdns *RDNSequence) { + n.OriginalRDNS = *rdns + for _, rdn := range *rdns { + if len(rdn) == 0 { + continue + } + atv := rdn[0] + n.Names = append(n.Names, atv) + value, ok := atv.Value.(string) + if !ok { + continue + } + + t := atv.Type + if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 { + switch t[3] { + case 3: + n.CommonName = value + n.CommonNames = append(n.CommonNames, value) + case 4: + n.Surname = append(n.Surname, value) + case 5: + n.SerialNumber = value + n.SerialNumbers = append(n.SerialNumbers, value) + case 6: + n.Country = append(n.Country, value) + case 7: + n.Locality = append(n.Locality, value) + case 8: + n.Province = append(n.Province, value) + case 9: + n.StreetAddress = append(n.StreetAddress, value) + case 10: + n.Organization = append(n.Organization, value) + case 11: + n.OrganizationalUnit = append(n.OrganizationalUnit, value) + case 17: + n.PostalCode = append(n.PostalCode, value) + case 42: + n.GivenName = append(n.GivenName, value) + case 97: + n.OrganizationIDs = append(n.OrganizationIDs, value) + } + } else if t.Equal(oidDomainComponent) { + n.DomainComponent = append(n.DomainComponent, value) + } else if t.Equal(oidDNEmailAddress) { + // Deprecated, see RFC 5280 Section 4.1.2.6 + n.EmailAddress = append(n.EmailAddress, value) + } else if t.Equal(oidJurisdictionLocality) { + n.JurisdictionLocality = append(n.JurisdictionLocality, value) + } else if t.Equal(oidJurisdictionProvince) { + n.JurisdictionProvince = append(n.JurisdictionProvince, value) + } else if t.Equal(oidJurisdictionCountry) { + n.JurisdictionCountry = append(n.JurisdictionCountry, value) + } + } +} + +var ( + oidCountry = []int{2, 5, 4, 6} + oidOrganization = []int{2, 5, 4, 10} + oidOrganizationalUnit = []int{2, 5, 4, 11} + oidCommonName = []int{2, 5, 4, 3} + oidSurname = []int{2, 5, 4, 4} + oidSerialNumber = []int{2, 5, 4, 5} + oidLocality = []int{2, 5, 4, 7} + oidProvince = []int{2, 5, 4, 8} + oidStreetAddress = []int{2, 5, 4, 9} + oidPostalCode = []int{2, 5, 4, 17} + oidGivenName = []int{2, 5, 4, 42} + oidDomainComponent = []int{0, 9, 2342, 19200300, 100, 1, 25} + oidDNEmailAddress = []int{1, 2, 840, 113549, 1, 9, 1} + // EV + oidJurisdictionLocality = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 1} + oidJurisdictionProvince = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 2} + oidJurisdictionCountry = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 3} + // QWACS + oidOrganizationID = []int{2, 5, 4, 97} +) + +// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence +// and returns the new value. The relativeDistinguishedNameSET contains an +// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and +// search for AttributeTypeAndValue. +func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence { + // NOTE: stdlib prevents adding if the oid is already present in n.ExtraNames + //if len(values) == 0 || oidInAttributeTypeAndValue(oid, n.ExtraNames) { + if len(values) == 0 { + return in + } + + s := make([]AttributeTypeAndValue, len(values)) + for i, value := range values { + s[i].Type = oid + s[i].Value = value + } + + return append(in, s) +} + +// String returns an RDNSequence as comma seperated list of +// AttributeTypeAndValues in canonical form. +func (seq RDNSequence) String() string { + out := make([]string, 0, len(seq)) + // An RDNSequence is effectively an [][]AttributeTypeAndValue + for _, atvSet := range seq { + for _, atv := range atvSet { + // Convert each individual AttributeTypeAndValue to X=Y + attrParts := make([]string, 0, 2) + oidString := atv.Type.String() + oidName, ok := oidDotNotationToNames[oidString] + if ok { + attrParts = append(attrParts, oidName.ShortName) + } else { + attrParts = append(attrParts, oidString) + } + switch value := atv.Value.(type) { + case string: + attrParts = append(attrParts, value) + case []byte: + attrParts = append(attrParts, string(value)) + default: + continue + } + attrString := strings.Join(attrParts, "=") + out = append(out, attrString) + } + } + return strings.Join(out, ", ") +} + +// ToRDNSequence returns OriginalRDNS is populated. Otherwise, it builds an +// RDNSequence in canonical order. +func (n Name) ToRDNSequence() (ret RDNSequence) { + if n.OriginalRDNS != nil { + return n.OriginalRDNS + } + if len(n.CommonName) > 0 { + ret = n.appendRDNs(ret, []string{n.CommonName}, oidCommonName) + } + ret = n.appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit) + ret = n.appendRDNs(ret, n.Organization, oidOrganization) + ret = n.appendRDNs(ret, n.StreetAddress, oidStreetAddress) + ret = n.appendRDNs(ret, n.Locality, oidLocality) + ret = n.appendRDNs(ret, n.Province, oidProvince) + ret = n.appendRDNs(ret, n.PostalCode, oidPostalCode) + ret = n.appendRDNs(ret, n.Country, oidCountry) + ret = n.appendRDNs(ret, n.DomainComponent, oidDomainComponent) + // EV Components + ret = n.appendRDNs(ret, n.JurisdictionLocality, oidJurisdictionLocality) + ret = n.appendRDNs(ret, n.JurisdictionProvince, oidJurisdictionProvince) + ret = n.appendRDNs(ret, n.JurisdictionCountry, oidJurisdictionCountry) + // QWACS + ret = n.appendRDNs(ret, n.OrganizationIDs, oidOrganizationID) + if len(n.SerialNumber) > 0 { + ret = n.appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber) + } + ret = append(ret, n.ExtraNames) + return ret +} + +// oidInAttributeTypeAndValue returns whether a type with the given OID exists +// in atv. +func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool { + for _, a := range atv { + if a.Type.Equal(oid) { + return true + } + } + return false +} + +// CertificateList represents the ASN.1 structure of the same name. See RFC +// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the +// signature. +type CertificateList struct { + TBSCertList TBSCertificateList + SignatureAlgorithm AlgorithmIdentifier + SignatureValue asn1.BitString +} + +// HasExpired reports whether now is past the expiry time of certList. +func (certList *CertificateList) HasExpired(now time.Time) bool { + return now.After(certList.TBSCertList.NextUpdate) +} + +// String returns a canonical representation of a DistinguishedName +func (n *Name) String() string { + seq := n.ToRDNSequence() + return seq.String() +} + +// OtherName represents the ASN.1 structure of the same name. See RFC +// 5280, section 4.2.1.6. +type OtherName struct { + TypeID asn1.ObjectIdentifier + Value asn1.RawValue `asn1:"explicit"` +} + +// EDIPartyName represents the ASN.1 structure of the same name. See RFC +// 5280, section 4.2.1.6. +type EDIPartyName struct { + NameAssigner string `asn1:"tag:0,optional,explicit" json:"name_assigner,omitempty"` + PartyName string `asn1:"tag:1,explicit" json:"party_name"` +} + +// TBSCertificateList represents the ASN.1 structure of the same name. See RFC +// 5280, section 5.1. +type TBSCertificateList struct { + Raw asn1.RawContent + Version int `asn1:"optional,default:0"` + Signature AlgorithmIdentifier + Issuer RDNSequence + ThisUpdate time.Time + NextUpdate time.Time `asn1:"optional"` + RevokedCertificates []RevokedCertificate `asn1:"optional"` + Extensions []Extension `asn1:"tag:0,optional,explicit"` +} + +// RevokedCertificate represents the ASN.1 structure of the same name. See RFC +// 5280, section 5.1. +type RevokedCertificate struct { + SerialNumber *big.Int + RevocationTime time.Time + Extensions []Extension `asn1:"optional"` +} diff --git a/vendor/github.com/zmap/zcrypto/x509/qc_statements.go b/vendor/github.com/zmap/zcrypto/x509/qc_statements.go new file mode 100644 index 0000000000..3adecd5c7b --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/qc_statements.go @@ -0,0 +1,173 @@ +package x509 + +import ( + "encoding/asn1" + "encoding/json" + "errors" +) + +type QCStatementASN struct { + StatementID asn1.ObjectIdentifier + StatementInfo asn1.RawValue `asn1:"optional"` +} + +func (s *QCStatementASN) MarshalJSON() ([]byte, error) { + aux := struct { + ID string `json:"id,omitempty"` + Value []byte `json:"value,omitempty"` + }{ + ID: s.StatementID.String(), + Value: s.StatementInfo.Bytes, + } + return json.Marshal(&aux) +} + +type QCStatementsASN struct { + QCStatements []QCStatementASN +} + +// ETSI OIDS from https://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.02.03_20/en_31941205v020203a.pdf +var ( + oidEtsiQcsQcCompliance = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 1} + oidEtsiQcsQcLimitValue = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 2} + oidEtsiQcsQcRetentionPeriod = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 3} + oidEtsiQcsQcSSCD = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 4} + oidEtsiQcsQcEuPDS = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 5} + oidEtsiQcsQcType = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6} + oidEtsiQcsQcCCLegislation = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 7} + oidEtsiQcsQctEsign = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 1} + oidEtsiQcsQctEseal = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 2} + oidEtsiQcsQctWeb = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 3} +) + +type QCStatements struct { + StatementIDs []string `json:"ids,omitempty"` + ParsedStatements *ParsedQCStatements `json:"parsed,omitempty"` +} + +type ParsedQCStatements struct { + ETSICompliance []bool `json:"etsi_compliance,omitempty"` + SSCD []bool `json:"sscd,omitempty"` + Types []QCType `json:"types,omitempty"` + Limit []MonetaryValue `json:"limit,omitempty"` + PDSLocations []PDSLocations `json:"pds_locations,omitempty"` + RetentionPeriod []int `json:"retention_period,omitempty"` + Legislation []QCLegistation `json:"legislation,omitempty"` +} + +type MonetaryValue struct { + Currency string `json:"currency,omitempty"` + CurrencyNumber int `json:"currency_number,omitempty"` + Amount int `json:"amount,omitempty"` + Exponent int `json:"exponent,omitempty"` +} + +type monetaryValueASNString struct { + Currency string `asn1:"printable"` + Amount int + Exponent int +} + +type monetaryValueASNNumber struct { + Currency int + Amount int + Exponent int +} + +type PDSLocations struct { + Locations []PDSLocation `json:"locations,omitempty"` +} + +type PDSLocation struct { + URL string `json:"url,omitempty" asn1:"ia5"` + Language string `json:"language,omitempty" asn1:"printable"` +} + +type QCType struct { + TypeIdentifiers []asn1.ObjectIdentifier +} + +type QCLegistation struct { + CountryCodes []string `json:"country_codes,omitempty"` +} + +func (qt *QCType) MarshalJSON() ([]byte, error) { + aux := struct { + Types []string `json:"ids,omitempty"` + }{ + Types: make([]string, len(qt.TypeIdentifiers)), + } + for idx := range qt.TypeIdentifiers { + aux.Types[idx] = qt.TypeIdentifiers[idx].String() + } + return json.Marshal(&aux) +} + +func (q *QCStatements) Parse(in *QCStatementsASN) error { + q.StatementIDs = make([]string, len(in.QCStatements)) + known := ParsedQCStatements{} + for i, s := range in.QCStatements { + val := in.QCStatements[i].StatementInfo.FullBytes + q.StatementIDs[i] = s.StatementID.String() + if s.StatementID.Equal(oidEtsiQcsQcCompliance) { + known.ETSICompliance = append(known.ETSICompliance, true) + if val != nil { + return errors.New("EtsiQcsQcCompliance QCStatement must not contain a statementInfo") + } + } else if s.StatementID.Equal(oidEtsiQcsQcLimitValue) { + // TODO + mvs := monetaryValueASNString{} + mvn := monetaryValueASNNumber{} + out := MonetaryValue{} + if _, err := asn1.Unmarshal(val, &mvs); err == nil { + out.Currency = mvs.Currency + out.Amount = mvs.Amount + out.Exponent = mvs.Exponent + } else if _, err := asn1.Unmarshal(val, &mvn); err == nil { + out.CurrencyNumber = mvn.Currency + out.Amount = mvn.Amount + out.Exponent = mvn.Exponent + } else { + return err + } + known.Limit = append(known.Limit, out) + } else if s.StatementID.Equal(oidEtsiQcsQcRetentionPeriod) { + var retentionPeriod int + if _, err := asn1.Unmarshal(val, &retentionPeriod); err != nil { + return err + } + known.RetentionPeriod = append(known.RetentionPeriod, retentionPeriod) + } else if s.StatementID.Equal(oidEtsiQcsQcSSCD) { + known.SSCD = append(known.SSCD, true) + if val != nil { + return errors.New("EtsiQcsQcSSCD QCStatement must not contain a statementInfo") + } + } else if s.StatementID.Equal(oidEtsiQcsQcEuPDS) { + locations := make([]PDSLocation, 0) + if _, err := asn1.Unmarshal(val, &locations); err != nil { + return err + } + known.PDSLocations = append(known.PDSLocations, PDSLocations{ + Locations: locations, + }) + } else if s.StatementID.Equal(oidEtsiQcsQcType) { + typeIds := make([]asn1.ObjectIdentifier, 0) + if _, err := asn1.Unmarshal(val, &typeIds); err != nil { + return err + } + known.Types = append(known.Types, QCType{ + TypeIdentifiers: typeIds, + }) + } else if s.StatementID.Equal(oidEtsiQcsQcCCLegislation) { + countryCodes := make([]string, 0) + if _, err := asn1.Unmarshal(val, &countryCodes); err != nil { + return err + } + known.Legislation = append(known.Legislation, QCLegistation{ + CountryCodes: countryCodes, + }) + } + } + q.ParsedStatements = &known + return nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/sec1.go b/vendor/github.com/zmap/zcrypto/x509/sec1.go new file mode 100644 index 0000000000..33f376c072 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/sec1.go @@ -0,0 +1,105 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "encoding/asn1" + "errors" + "fmt" + "math/big" +) + +const ecPrivKeyVersion = 1 + +// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. +// References: +// RFC 5915 +// SEC1 - http://www.secg.org/sec1-v2.pdf +// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in +// most cases it is not. +type ecPrivateKey struct { + Version int + PrivateKey []byte + NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` + PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` +} + +// ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. +func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) { + return parseECPrivateKey(nil, der) +} + +// MarshalECPrivateKey marshals an EC private key into ASN.1, DER format. +func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { + oid, ok := oidFromNamedCurve(key.Curve) + if !ok { + return nil, errors.New("x509: unknown elliptic curve") + } + + privateKeyBytes := key.D.Bytes() + paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8) + copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) + + return asn1.Marshal(ecPrivateKey{ + Version: 1, + PrivateKey: paddedPrivateKey, + NamedCurveOID: oid, + PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, + }) +} + +// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. +// The OID for the named curve may be provided from another source (such as +// the PKCS8 container) - if it is provided then use this instead of the OID +// that may exist in the EC private key structure. +func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { + var privKey ecPrivateKey + if _, err := asn1.Unmarshal(der, &privKey); err != nil { + return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) + } + if privKey.Version != ecPrivKeyVersion { + return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) + } + + var curve elliptic.Curve + if namedCurveOID != nil { + curve = namedCurveFromOID(*namedCurveOID) + } else { + curve = namedCurveFromOID(privKey.NamedCurveOID) + } + if curve == nil { + return nil, errors.New("x509: unknown elliptic curve") + } + + k := new(big.Int).SetBytes(privKey.PrivateKey) + curveOrder := curve.Params().N + if k.Cmp(curveOrder) >= 0 { + return nil, errors.New("x509: invalid elliptic curve private key value") + } + priv := new(ecdsa.PrivateKey) + priv.Curve = curve + priv.D = k + + privateKey := make([]byte, (curveOrder.BitLen()+7)/8) + + // Some private keys have leading zero padding. This is invalid + // according to [SEC1], but this code will ignore it. + for len(privKey.PrivateKey) > len(privateKey) { + if privKey.PrivateKey[0] != 0 { + return nil, errors.New("x509: invalid private key length") + } + privKey.PrivateKey = privKey.PrivateKey[1:] + } + + // Some private keys remove all leading zeros, this is also invalid + // according to [SEC1] but since OpenSSL used to do this, we ignore + // this too. + copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey) + priv.X, priv.Y = curve.ScalarBaseMult(privateKey) + + return priv, nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go b/vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go new file mode 100644 index 0000000000..366bd95910 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go @@ -0,0 +1,158 @@ +package x509 + +import ( + "encoding/asn1" + "github.com/zmap/zcrypto/x509/pkix" +) + +var ( + // oidBRTorServiceDescriptor is the assigned OID for the CAB Forum Tor Service + // Descriptor Hash extension (see EV Guidelines Appendix F) + oidBRTorServiceDescriptor = asn1.ObjectIdentifier{2, 23, 140, 1, 31} +) + +// TorServiceDescriptorHash is a structure corrsponding to the +// TorServiceDescriptorHash SEQUENCE described in Appendix F ("Issuance of +// Certificates for .onion Domain Names"). +// +// Each TorServiceDescriptorHash holds an onion URI (a utf8 string with the +// .onion address that was validated), a hash algorithm name (computed based on +// the pkix.AlgorithmIdentifier in the TorServiceDescriptorHash), the hash bytes +// (computed over the DER encoding of the ASN.1 SubjectPublicKey of the .onion +// service), and the number of bits in the hash bytes. +type TorServiceDescriptorHash struct { + Onion string `json:"onion"` + Algorithm pkix.AlgorithmIdentifier `json:"-"` + AlgorithmName string `json:"algorithm_name"` + Hash CertificateFingerprint `json:"hash"` + HashBits int `json:"hash_bits"` +} + +// parseTorServiceDescriptorSyntax parses the given pkix.Extension (assumed to +// have OID == oidBRTorServiceDescriptor) and returns a slice of parsed +// TorServiceDescriptorHash objects, or an error. An error will be returned if +// there are any structural errors related to the ASN.1 content (wrong tags, +// trailing data, missing fields, etc). +func parseTorServiceDescriptorSyntax(ext pkix.Extension) ([]*TorServiceDescriptorHash, error) { + // TorServiceDescriptorSyntax ::= + // SEQUENCE ( 1..MAX ) of TorServiceDescriptorHash + var seq asn1.RawValue + rest, err := asn1.Unmarshal(ext.Value, &seq) + if err != nil { + return nil, asn1.SyntaxError{ + Msg: "unable to unmarshal outer TorServiceDescriptor SEQUENCE", + } + } + if len(rest) != 0 { + return nil, asn1.SyntaxError{ + Msg: "trailing data after outer TorServiceDescriptor SEQUENCE", + } + } + if seq.Tag != asn1.TagSequence || seq.Class != asn1.ClassUniversal || !seq.IsCompound { + return nil, asn1.SyntaxError{ + Msg: "invalid outer TorServiceDescriptor SEQUENCE", + } + } + + var descriptors []*TorServiceDescriptorHash + rest = seq.Bytes + for len(rest) > 0 { + var descriptor *TorServiceDescriptorHash + descriptor, rest, err = parseTorServiceDescriptorHash(rest) + if err != nil { + return nil, err + } + descriptors = append(descriptors, descriptor) + } + return descriptors, nil +} + +// parseTorServiceDescriptorHash unmarshals a SEQUENCE from the provided data +// and parses a TorServiceDescriptorHash using the data contained in the +// sequence. The TorServiceDescriptorHash object and the remaining data are +// returned if no error occurs. +func parseTorServiceDescriptorHash(data []byte) (*TorServiceDescriptorHash, []byte, error) { + // TorServiceDescriptorHash:: = SEQUENCE { + // onionURI UTF8String + // algorithm AlgorithmIdentifier + // subjectPublicKeyHash BIT STRING + // } + var outerSeq asn1.RawValue + var err error + data, err = asn1.Unmarshal(data, &outerSeq) + if err != nil { + return nil, data, asn1.SyntaxError{ + Msg: "error unmarshaling TorServiceDescriptorHash SEQUENCE", + } + } + if outerSeq.Tag != asn1.TagSequence || + outerSeq.Class != asn1.ClassUniversal || + !outerSeq.IsCompound { + return nil, data, asn1.SyntaxError{ + Msg: "TorServiceDescriptorHash missing compound SEQUENCE tag", + } + } + fieldData := outerSeq.Bytes + + // Unmarshal and verify the structure of the onionURI UTF8String field. + var rawOnionURI asn1.RawValue + fieldData, err = asn1.Unmarshal(fieldData, &rawOnionURI) + if err != nil { + return nil, data, asn1.SyntaxError{ + Msg: "error unmarshaling TorServiceDescriptorHash onionURI", + } + } + if rawOnionURI.Tag != asn1.TagUTF8String || + rawOnionURI.Class != asn1.ClassUniversal || + rawOnionURI.IsCompound { + return nil, data, asn1.SyntaxError{ + Msg: "TorServiceDescriptorHash missing non-compound UTF8String tag", + } + } + + // Unmarshal and verify the structure of the algorithm UTF8String field. + var algorithm pkix.AlgorithmIdentifier + fieldData, err = asn1.Unmarshal(fieldData, &algorithm) + if err != nil { + return nil, nil, asn1.SyntaxError{ + Msg: "error unmarshaling TorServiceDescriptorHash algorithm", + } + } + + var algorithmName string + if algorithm.Algorithm.Equal(oidSHA256) { + algorithmName = "SHA256" + } else if algorithm.Algorithm.Equal(oidSHA384) { + algorithmName = "SHA384" + } else if algorithm.Algorithm.Equal(oidSHA512) { + algorithmName = "SHA512" + } else { + algorithmName = "Unknown" + } + + // Unmarshal and verify the structure of the Subject Public Key Hash BitString + // field. + var spkh asn1.BitString + fieldData, err = asn1.Unmarshal(fieldData, &spkh) + if err != nil { + return nil, data, asn1.SyntaxError{ + Msg: "error unmarshaling TorServiceDescriptorHash Hash", + } + } + + // There should be no trailing data after the TorServiceDescriptorHash + // SEQUENCE. + if len(fieldData) > 0 { + return nil, data, asn1.SyntaxError{ + Msg: "trailing data after TorServiceDescriptorHash", + } + } + + return &TorServiceDescriptorHash{ + Onion: string(rawOnionURI.Bytes), + Algorithm: algorithm, + AlgorithmName: algorithmName, + HashBits: spkh.BitLength, + Hash: CertificateFingerprint(spkh.Bytes), + }, data, nil +} diff --git a/vendor/github.com/zmap/zcrypto/x509/validation.go b/vendor/github.com/zmap/zcrypto/x509/validation.go new file mode 100644 index 0000000000..e582e54ff7 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/validation.go @@ -0,0 +1,60 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import "time" + +// Validation stores different validation levels for a given certificate +type Validation struct { + BrowserTrusted bool `json:"browser_trusted"` + BrowserError string `json:"browser_error,omitempty"` + MatchesDomain bool `json:"matches_domain,omitempty"` + Domain string `json:"-"` +} + +// ValidateWithStupidDetail fills out a Validation struct given a leaf +// certificate and intermediates / roots. If opts.DNSName is set, then it will +// also check if the domain matches. +// +// Deprecated: Use verifier.Verify() instead. +func (c *Certificate) ValidateWithStupidDetail(opts VerifyOptions) (chains []CertificateChain, validation *Validation, err error) { + + // Manually set the time, so that all verifies we do get the same time + if opts.CurrentTime.IsZero() { + opts.CurrentTime = time.Now() + } + + // XXX: Don't pass a KeyUsage to the Verify API + opts.KeyUsages = nil + domain := opts.DNSName + opts.DNSName = "" + + out := new(Validation) + out.Domain = domain + + if chains, _, _, err = c.Verify(opts); err != nil { + out.BrowserError = err.Error() + } else { + out.BrowserTrusted = true + } + + if domain != "" { + nameErr := c.VerifyHostname(domain) + if nameErr != nil { + out.MatchesDomain = false + } else { + out.MatchesDomain = true + } + + // Make sure we return an error if either chain building or hostname + // verification fails. + if err == nil && nameErr != nil { + err = nameErr + } + } + validation = out + + return +} diff --git a/vendor/github.com/zmap/zcrypto/x509/verify.go b/vendor/github.com/zmap/zcrypto/x509/verify.go new file mode 100644 index 0000000000..450f985c15 --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/verify.go @@ -0,0 +1,635 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package x509 + +import ( + "errors" + "fmt" + "net" + "strings" + "time" + "unicode/utf8" +) + +type InvalidReason int + +const ( + // NotAuthorizedToSign results when a certificate is signed by another + // which isn't marked as a CA certificate. + NotAuthorizedToSign InvalidReason = iota + + // Expired results when a certificate has expired, based on the time + // given in the VerifyOptions. + Expired + + // CANotAuthorizedForThisName results when an intermediate or root + // certificate has a name constraint which doesn't include the name + // being checked. + CANotAuthorizedForThisName + + // CANotAuthorizedForThisEmail results when an intermediate or root + // certificate has a name constraint which doesn't include the email + // being checked. + CANotAuthorizedForThisEmail + + // CANotAuthorizedForThisIP results when an intermediate or root + // certificate has a name constraint which doesn't include the IP + // being checked. + CANotAuthorizedForThisIP + + // CANotAuthorizedForThisDirectory results when an intermediate or root + // certificate has a name constraint which doesn't include the directory + // being checked. + CANotAuthorizedForThisDirectory + + // TooManyIntermediates results when a path length constraint is + // violated. + TooManyIntermediates + + // IncompatibleUsage results when the certificate's key usage indicates + // that it may only be used for a different purpose. + IncompatibleUsage + + // NameMismatch results when the subject name of a parent certificate + // does not match the issuer name in the child. + NameMismatch + + // NeverValid results when the certificate could never have been valid due to + // some date-related issue, e.g. NotBefore > NotAfter. + NeverValid + + // IsSelfSigned results when the certificate is self-signed and not a trusted + // root. + IsSelfSigned +) + +// CertificateInvalidError results when an odd error occurs. Users of this +// library probably want to handle all these errors uniformly. +type CertificateInvalidError struct { + Cert *Certificate + Reason InvalidReason +} + +func (e CertificateInvalidError) Error() string { + switch e.Reason { + case NotAuthorizedToSign: + return "x509: certificate is not authorized to sign other certificates" + case Expired: + return "x509: certificate has expired or is not yet valid" + case CANotAuthorizedForThisName: + return "x509: a root or intermediate certificate is not authorized to sign in this domain" + case CANotAuthorizedForThisEmail: + return "x509: a root or intermediate certificate is not authorized to sign this email address" + case CANotAuthorizedForThisIP: + return "x509: a root or intermediate certificate is not authorized to sign this IP address" + case CANotAuthorizedForThisDirectory: + return "x509: a root or intermediate certificate is not authorized to sign in this directory" + case TooManyIntermediates: + return "x509: too many intermediates for path length constraint" + case IncompatibleUsage: + return "x509: certificate specifies an incompatible key usage" + case NameMismatch: + return "x509: issuer name does not match subject from issuing certificate" + case NeverValid: + return "x509: certificate will never be valid" + } + return "x509: unknown error" +} + +// HostnameError results when the set of authorized names doesn't match the +// requested name. +type HostnameError struct { + Certificate *Certificate + Host string +} + +func (h HostnameError) Error() string { + c := h.Certificate + + var valid string + if ip := net.ParseIP(h.Host); ip != nil { + // Trying to validate an IP + if len(c.IPAddresses) == 0 { + return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs" + } + for _, san := range c.IPAddresses { + if len(valid) > 0 { + valid += ", " + } + valid += san.String() + } + } else { + if c.hasSANExtension() { + valid = strings.Join(c.DNSNames, ", ") + } else { + valid = c.Subject.CommonName + } + } + + if len(valid) == 0 { + return "x509: certificate is not valid for any names, but wanted to match " + h.Host + } + return "x509: certificate is valid for " + valid + ", not " + h.Host +} + +// UnknownAuthorityError results when the certificate issuer is unknown +type UnknownAuthorityError struct { + Cert *Certificate + // hintErr contains an error that may be helpful in determining why an + // authority wasn't found. + hintErr error + // hintCert contains a possible authority certificate that was rejected + // because of the error in hintErr. + hintCert *Certificate +} + +func (e UnknownAuthorityError) Error() string { + s := "x509: certificate signed by unknown authority" + if e.hintErr != nil { + certName := e.hintCert.Subject.CommonName + if len(certName) == 0 { + if len(e.hintCert.Subject.Organization) > 0 { + certName = e.hintCert.Subject.Organization[0] + } else { + certName = "serial:" + e.hintCert.SerialNumber.String() + } + } + s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName) + } + return s +} + +// SystemRootsError results when we fail to load the system root certificates. +type SystemRootsError struct { + Err error +} + +func (se SystemRootsError) Error() string { + msg := "x509: failed to load system roots and no roots provided" + if se.Err != nil { + return msg + "; " + se.Err.Error() + } + return msg +} + +// errNotParsed is returned when a certificate without ASN.1 contents is +// verified. Platform-specific verification needs the ASN.1 contents. +var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate") + +const maxIntermediateCount = 10 + +// VerifyOptions contains parameters for Certificate.Verify. It's a structure +// because other PKIX verification APIs have ended up needing many options. +type VerifyOptions struct { + DNSName string + EmailAddress string + IPAddress net.IP + + Intermediates *CertPool + Roots *CertPool // if nil, the system roots are used + CurrentTime time.Time // if zero, the current time is used + // KeyUsage specifies which Extended Key Usage values are acceptable. + // An empty list means ExtKeyUsageServerAuth. Key usage is considered a + // constraint down the chain which mirrors Windows CryptoAPI behaviour, + // but not the spec. To accept any key usage, include ExtKeyUsageAny. + KeyUsages []ExtKeyUsage +} + +const ( + leafCertificate = iota + intermediateCertificate + rootCertificate +) + +func matchNameConstraint(domain, constraint string) bool { + // The meaning of zero length constraints is not specified, but this + // code follows NSS and accepts them as matching everything. + if len(constraint) == 0 { + return true + } + + if len(domain) < len(constraint) { + return false + } + + prefixLen := len(domain) - len(constraint) + if !strings.EqualFold(domain[prefixLen:], constraint) { + return false + } + + if prefixLen == 0 { + return true + } + + isSubdomain := domain[prefixLen-1] == '.' + constraintHasLeadingDot := constraint[0] == '.' + return isSubdomain != constraintHasLeadingDot +} + +// NOTE: the stdlib function does many more checks and is preferable. For backwards compatibility using this version + +// isValid performs validity checks on the c. It will never return a +// date-related error. +func (c *Certificate) isValid(certType CertificateType, currentChain CertificateChain) error { + + // KeyUsage status flags are ignored. From Engineering Security, Peter + // Gutmann: A European government CA marked its signing certificates as + // being valid for encryption only, but no-one noticed. Another + // European CA marked its signature keys as not being valid for + // signatures. A different CA marked its own trusted root certificate + // as being invalid for certificate signing. Another national CA + // distributed a certificate to be used to encrypt data for the + // country’s tax authority that was marked as only being usable for + // digital signatures but not for encryption. Yet another CA reversed + // the order of the bit flags in the keyUsage due to confusion over + // encoding endianness, essentially setting a random keyUsage in + // certificates that it issued. Another CA created a self-invalidating + // certificate by adding a certificate policy statement stipulating + // that the certificate had to be used strictly as specified in the + // keyUsage, and a keyUsage containing a flag indicating that the RSA + // encryption key could only be used for Diffie-Hellman key agreement. + + if certType == CertificateTypeIntermediate && (!c.BasicConstraintsValid || !c.IsCA) { + return CertificateInvalidError{c, NotAuthorizedToSign} + } + + if c.BasicConstraintsValid && c.MaxPathLen >= 0 { + numIntermediates := len(currentChain) - 1 + if numIntermediates > c.MaxPathLen { + return CertificateInvalidError{c, TooManyIntermediates} + } + } + + if len(currentChain) > maxIntermediateCount { + return CertificateInvalidError{c, TooManyIntermediates} + } + + return nil +} + +// Verify attempts to verify c by building one or more chains from c to a +// certificate in opts.Roots, using certificates in opts.Intermediates if +// needed. If successful, it returns one or more chains where the first +// element of the chain is c and the last element is from opts.Roots. +// +// If opts.Roots is nil and system roots are unavailable the returned error +// will be of type SystemRootsError. +// +// WARNING: this doesn't do any revocation checking. +func (c *Certificate) Verify(opts VerifyOptions) (current, expired, never []CertificateChain, err error) { + + if opts.Roots == nil { + err = SystemRootsError{} + return + } + + err = c.isValid(CertificateTypeLeaf, nil) + if err != nil { + return + } + + candidateChains, err := c.buildChains(make(map[int][]CertificateChain), []*Certificate{c}, &opts) + if err != nil { + return + } + + keyUsages := opts.KeyUsages + if len(keyUsages) == 0 { + keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth} + } + + // If any key usage is acceptable then we're done. + hasKeyUsageAny := false + for _, usage := range keyUsages { + if usage == ExtKeyUsageAny { + hasKeyUsageAny = true + break + } + } + + var chains []CertificateChain + if hasKeyUsageAny { + chains = candidateChains + } else { + for _, candidate := range candidateChains { + if checkChainForKeyUsage(candidate, keyUsages) { + chains = append(chains, candidate) + } + } + } + + if len(chains) == 0 { + err = CertificateInvalidError{c, IncompatibleUsage} + return + } + + current, expired, never = FilterByDate(chains, opts.CurrentTime) + if len(current) == 0 { + if len(expired) > 0 { + err = CertificateInvalidError{c, Expired} + } else if len(never) > 0 { + err = CertificateInvalidError{c, NeverValid} + } + return + } + + if len(opts.DNSName) > 0 { + err = c.VerifyHostname(opts.DNSName) + if err != nil { + return + } + } + return +} + +func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate { + n := make([]*Certificate, len(chain)+1) + copy(n, chain) + n[len(chain)] = cert + return n +} + +// buildChains returns all chains of length < maxIntermediateCount. Chains begin +// the certificate being validated (chain[0] = c), and end at a root. It +// enforces that all intermediates can sign certificates, and checks signatures. +// It does not enforce expiration. +func (c *Certificate) buildChains(cache map[int][]CertificateChain, currentChain CertificateChain, opts *VerifyOptions) (chains []CertificateChain, err error) { + + // If the certificate being validated is a root, add the chain of length one + // containing just the root. Only do this on the first call to buildChains, + // when the len(currentChain) = 1. + if len(currentChain) == 1 && opts.Roots.Contains(c) { + chains = append(chains, CertificateChain{c}) + } + + if len(chains) == 0 && c.SelfSigned { + err = CertificateInvalidError{c, IsSelfSigned} + } + + // Find roots that signed c and have matching SKID/AKID and Subject/Issuer. + possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c) + + // If any roots are parents of c, create new chain for each one of them. + for _, rootNum := range possibleRoots { + root := opts.Roots.certs[rootNum] + err = root.isValid(CertificateTypeRoot, currentChain) + if err != nil { + continue + } + if !currentChain.CertificateInChain(root) { + chains = append(chains, currentChain.AppendToFreshChain(root)) + } + } + + // The root chains of length N+1 are now "done". Now we'll look for any + // intermediates that issue this certificate, meaning that any chain to a root + // through these intermediates is at least length N+2. + possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c) + + for _, intermediateNum := range possibleIntermediates { + intermediate := opts.Intermediates.certs[intermediateNum] + if opts.Roots.Contains(intermediate) { + continue + } + if currentChain.CertificateSubjectAndKeyInChain(intermediate) { + continue + } + err = intermediate.isValid(CertificateTypeIntermediate, currentChain) + if err != nil { + continue + } + + // We don't want to add any certificate to chains that doesn't somehow get + // to a root. We don't know if all chains through the intermediates will end + // at a root, so we slice off the back half of the chain and try to build + // that part separately. + childChains, ok := cache[intermediateNum] + if !ok { + childChains, err = intermediate.buildChains(cache, currentChain.AppendToFreshChain(intermediate), opts) + cache[intermediateNum] = childChains + } + chains = append(chains, childChains...) + } + + if len(chains) > 0 { + err = nil + } + + if len(chains) == 0 && err == nil { + hintErr := rootErr + hintCert := failedRoot + if hintErr == nil { + hintErr = intermediateErr + hintCert = failedIntermediate + } + err = UnknownAuthorityError{c, hintErr, hintCert} + } + + return +} + +func matchHostnames(pattern, host string) bool { + host = strings.TrimSuffix(host, ".") + pattern = strings.TrimSuffix(pattern, ".") + + if len(pattern) == 0 || len(host) == 0 { + return false + } + + patternParts := strings.Split(pattern, ".") + hostParts := strings.Split(host, ".") + + if len(patternParts) != len(hostParts) { + return false + } + + for i, patternPart := range patternParts { + if /*i == 0 &&*/ patternPart == "*" { + continue + } + if patternPart != hostParts[i] { + return false + } + } + + return true +} + +// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use +// an explicitly ASCII function to avoid any sharp corners resulting from +// performing Unicode operations on DNS labels. +func toLowerCaseASCII(in string) string { + // If the string is already lower-case then there's nothing to do. + isAlreadyLowerCase := true + for _, c := range in { + if c == utf8.RuneError { + // If we get a UTF-8 error then there might be + // upper-case ASCII bytes in the invalid sequence. + isAlreadyLowerCase = false + break + } + if 'A' <= c && c <= 'Z' { + isAlreadyLowerCase = false + break + } + } + + if isAlreadyLowerCase { + return in + } + + out := []byte(in) + for i, c := range out { + if 'A' <= c && c <= 'Z' { + out[i] += 'a' - 'A' + } + } + return string(out) +} + +// VerifyHostname returns nil if c is a valid certificate for the named host. +// Otherwise it returns an error describing the mismatch. +func (c *Certificate) VerifyHostname(h string) error { + // IP addresses may be written in [ ]. + candidateIP := h + if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' { + candidateIP = h[1 : len(h)-1] + } + if ip := net.ParseIP(candidateIP); ip != nil { + // We only match IP addresses against IP SANs. + // https://tools.ietf.org/html/rfc6125#appendix-B.2 + for _, candidate := range c.IPAddresses { + if ip.Equal(candidate) { + return nil + } + } + return HostnameError{c, candidateIP} + } + + lowered := toLowerCaseASCII(h) + + if c.hasSANExtension() { + for _, match := range c.DNSNames { + if matchHostnames(toLowerCaseASCII(match), lowered) { + return nil + } + } + // If Subject Alt Name is given, we ignore the common name. + } else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) { + return nil + } + + return HostnameError{c, h} +} + +func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool { + usages := make([]ExtKeyUsage, len(keyUsages)) + copy(usages, keyUsages) + + if len(chain) == 0 { + return false + } + + usagesRemaining := len(usages) + + // We walk down the list and cross out any usages that aren't supported + // by each certificate. If we cross out all the usages, then the chain + // is unacceptable. + +NextCert: + for i := len(chain) - 1; i >= 0; i-- { + cert := chain[i] + if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 { + // The certificate doesn't have any extended key usage specified. + continue + } + + for _, usage := range cert.ExtKeyUsage { + if usage == ExtKeyUsageAny { + // The certificate is explicitly good for any usage. + continue NextCert + } + } + + const invalidUsage ExtKeyUsage = -1 + + NextRequestedUsage: + for i, requestedUsage := range usages { + if requestedUsage == invalidUsage { + continue + } + + for _, usage := range cert.ExtKeyUsage { + if requestedUsage == usage { + continue NextRequestedUsage + } else if requestedUsage == ExtKeyUsageServerAuth && + (usage == ExtKeyUsageNetscapeServerGatedCrypto || + usage == ExtKeyUsageMicrosoftServerGatedCrypto) { + // In order to support COMODO + // certificate chains, we have to + // accept Netscape or Microsoft SGC + // usages as equal to ServerAuth. + continue NextRequestedUsage + } + } + + usages[i] = invalidUsage + usagesRemaining-- + if usagesRemaining == 0 { + return false + } + } + } + + return true +} + +// earlier returns the earlier of a and b +func earlier(a, b time.Time) time.Time { + if a.Before(b) { + return a + } + return b +} + +// later returns the later of a and b +func later(a, b time.Time) time.Time { + if a.After(b) { + return a + } + return b +} + +// check expirations divides chains into a set of disjoint chains, containing +// current chains valid now, expired chains that were valid at some point, and +// the set of chains that were never valid. +func FilterByDate(chains []CertificateChain, now time.Time) (current, expired, never []CertificateChain) { + for _, chain := range chains { + if len(chain) == 0 { + continue + } + leaf := chain[0] + lowerBound := leaf.NotBefore + upperBound := leaf.NotAfter + for _, c := range chain[1:] { + lowerBound = later(lowerBound, c.NotBefore) + upperBound = earlier(upperBound, c.NotAfter) + } + valid := lowerBound.Before(now) && upperBound.After(now) + wasValid := lowerBound.Before(upperBound) + if valid && !wasValid { + // Math/logic tells us this is impossible. + panic("valid && !wasValid should not be possible") + } + if valid { + current = append(current, chain) + } else if wasValid { + expired = append(expired, chain) + } else { + never = append(never, chain) + } + } + return +} diff --git a/vendor/github.com/zmap/zcrypto/x509/x509.go b/vendor/github.com/zmap/zcrypto/x509/x509.go new file mode 100644 index 0000000000..558e74647b --- /dev/null +++ b/vendor/github.com/zmap/zcrypto/x509/x509.go @@ -0,0 +1,2957 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package x509 parses X.509-encoded keys and certificates. +// +// Originally based on the go/crypto/x509 standard library, +// this package has now diverged enough that it is no longer +// updated with direct correspondence to new go releases. + +package x509 + +import ( + // all of the hash libraries need to be imported for side-effects, + // so that crypto.RegisterHash is called + _ "crypto/md5" + "crypto/sha256" + _ "crypto/sha512" + "io" + "strings" + + "bytes" + "crypto" + "crypto/dsa" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rsa" + "encoding/asn1" + "encoding/pem" + "errors" + "fmt" + "math/big" + "net" + "strconv" + "time" + + "github.com/weppos/publicsuffix-go/publicsuffix" + "github.com/zmap/zcrypto/x509/ct" + "github.com/zmap/zcrypto/x509/pkix" +) + +// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo +// in RFC 3280. +type pkixPublicKey struct { + Algo pkix.AlgorithmIdentifier + BitString asn1.BitString +} + +// ParsePKIXPublicKey parses a DER encoded public key. These values are +// typically found in PEM blocks with "BEGIN PUBLIC KEY". +// +// Supported key types include RSA, DSA, and ECDSA. Unknown key +// types result in an error. +// +// On success, pub will be of type *rsa.PublicKey, *dsa.PublicKey, +// or *ecdsa.PublicKey. +func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) { + var pki publicKeyInfo + if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after ASN.1 of public-key") + } + algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm) + if algo == UnknownPublicKeyAlgorithm { + return nil, errors.New("x509: unknown public key algorithm") + } + return parsePublicKey(algo, &pki) +} + +func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) { + switch pub := pub.(type) { + case *rsa.PublicKey: + publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{ + N: pub.N, + E: pub.E, + }) + if err != nil { + return nil, pkix.AlgorithmIdentifier{}, err + } + publicKeyAlgorithm.Algorithm = oidPublicKeyRSA + // This is a NULL parameters value which is required by + // https://tools.ietf.org/html/rfc3279#section-2.3.1. + publicKeyAlgorithm.Parameters = asn1.NullRawValue + case *ecdsa.PublicKey: + publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) + oid, ok := oidFromNamedCurve(pub.Curve) + if !ok { + return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve") + } + publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA + var paramBytes []byte + paramBytes, err = asn1.Marshal(oid) + if err != nil { + return + } + publicKeyAlgorithm.Parameters.FullBytes = paramBytes + case *AugmentedECDSA: + return marshalPublicKey(pub.Pub) + default: + return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported") + } + + return publicKeyBytes, publicKeyAlgorithm, nil +} + +// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format. +func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { + var publicKeyBytes []byte + var publicKeyAlgorithm pkix.AlgorithmIdentifier + var err error + + if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil { + return nil, err + } + + pkix := pkixPublicKey{ + Algo: publicKeyAlgorithm, + BitString: asn1.BitString{ + Bytes: publicKeyBytes, + BitLength: 8 * len(publicKeyBytes), + }, + } + + ret, _ := asn1.Marshal(pkix) + return ret, nil +} + +// These structures reflect the ASN.1 structure of X.509 certificates.: + +type certificate struct { + Raw asn1.RawContent + TBSCertificate tbsCertificate + SignatureAlgorithm pkix.AlgorithmIdentifier + SignatureValue asn1.BitString +} + +type tbsCertificate struct { + Raw asn1.RawContent + Version int `asn1:"optional,explicit,default:0,tag:0"` + SerialNumber *big.Int + SignatureAlgorithm pkix.AlgorithmIdentifier + Issuer asn1.RawValue + Validity validity + Subject asn1.RawValue + PublicKey publicKeyInfo + UniqueId asn1.BitString `asn1:"optional,tag:1"` + SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"` + Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"` +} + +type dsaAlgorithmParameters struct { + P, Q, G *big.Int +} + +type dsaSignature struct { + R, S *big.Int +} + +type ecdsaSignature dsaSignature + +type AugmentedECDSA struct { + Pub *ecdsa.PublicKey + Raw asn1.BitString +} + +type validity struct { + NotBefore, NotAfter time.Time +} + +type publicKeyInfo struct { + Raw asn1.RawContent + Algorithm pkix.AlgorithmIdentifier + PublicKey asn1.BitString +} + +// RFC 5280, 4.2.1.1 +type authKeyId struct { + Id []byte `asn1:"optional,tag:0"` +} + +type SignatureAlgorithmOID asn1.ObjectIdentifier + +type SignatureAlgorithm int + +const ( + UnknownSignatureAlgorithm SignatureAlgorithm = iota + MD2WithRSA + MD5WithRSA + SHA1WithRSA + SHA256WithRSA + SHA384WithRSA + SHA512WithRSA + DSAWithSHA1 + DSAWithSHA256 + ECDSAWithSHA1 + ECDSAWithSHA256 + ECDSAWithSHA384 + ECDSAWithSHA512 + SHA256WithRSAPSS + SHA384WithRSAPSS + SHA512WithRSAPSS +) + +func (algo SignatureAlgorithm) isRSAPSS() bool { + switch algo { + case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS: + return true + default: + return false + } +} + +var algoName = [...]string{ + MD2WithRSA: "MD2-RSA", + MD5WithRSA: "MD5-RSA", + SHA1WithRSA: "SHA1-RSA", + SHA256WithRSA: "SHA256-RSA", + SHA384WithRSA: "SHA384-RSA", + SHA512WithRSA: "SHA512-RSA", + SHA256WithRSAPSS: "SHA256-RSAPSS", + SHA384WithRSAPSS: "SHA384-RSAPSS", + SHA512WithRSAPSS: "SHA512-RSAPSS", + DSAWithSHA1: "DSA-SHA1", + DSAWithSHA256: "DSA-SHA256", + ECDSAWithSHA1: "ECDSA-SHA1", + ECDSAWithSHA256: "ECDSA-SHA256", + ECDSAWithSHA384: "ECDSA-SHA384", + ECDSAWithSHA512: "ECDSA-SHA512", +} + +func (algo SignatureAlgorithm) String() string { + if 0 < algo && int(algo) < len(algoName) { + return algoName[algo] + } + return strconv.Itoa(int(algo)) +} + +var keyAlgorithmNames = []string{ + "unknown_algorithm", + "RSA", + "DSA", + "ECDSA", +} + +type PublicKeyAlgorithm int + +const ( + UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota + RSA + DSA + ECDSA + total_key_algorithms +) + +// OIDs for signature algorithms +// +// pkcs-1 OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } +// +// +// RFC 3279 2.2.1 RSA Signature Algorithms +// +// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } +// +// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } +// +// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } +// +// dsaWithSha1 OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 } +// +// RFC 3279 2.2.3 ECDSA Signature Algorithm +// +// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) ansi-x962(10045) +// signatures(4) ecdsa-with-SHA1(1)} +// +// +// RFC 4055 5 PKCS #1 Version 1.5 +// +// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } +// +// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } +// +// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } +// +// +// RFC 5758 3.1 DSA Signature Algorithms +// +// dsaWithSha256 OBJECT IDENTIFIER ::= { +// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101) +// csor(3) algorithms(4) id-dsa-with-sha2(3) 2} +// +// RFC 5758 3.2 ECDSA Signature Algorithm +// +// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2) +// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 } +// +// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2) +// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 } +// +// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2) +// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 } + +var ( + oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} + oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} + oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} + oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} + oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} + oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} + oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} + oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} + oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} + oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} + oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} + oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} + oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} + + oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} + oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} + oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} + + oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8} + + // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA + // but it's specified by ISO. Microsoft's makecert.exe has been known + // to produce certificates with this OID. + oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29} +) + +var signatureAlgorithmDetails = []struct { + algo SignatureAlgorithm + oid asn1.ObjectIdentifier + pubKeyAlgo PublicKeyAlgorithm + hash crypto.Hash +}{ + {MD2WithRSA, oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */}, + {MD5WithRSA, oidSignatureMD5WithRSA, RSA, crypto.MD5}, + {SHA1WithRSA, oidSignatureSHA1WithRSA, RSA, crypto.SHA1}, + {SHA1WithRSA, oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1}, + {SHA256WithRSA, oidSignatureSHA256WithRSA, RSA, crypto.SHA256}, + {SHA384WithRSA, oidSignatureSHA384WithRSA, RSA, crypto.SHA384}, + {SHA512WithRSA, oidSignatureSHA512WithRSA, RSA, crypto.SHA512}, + {SHA256WithRSAPSS, oidSignatureRSAPSS, RSA, crypto.SHA256}, + {SHA384WithRSAPSS, oidSignatureRSAPSS, RSA, crypto.SHA384}, + {SHA512WithRSAPSS, oidSignatureRSAPSS, RSA, crypto.SHA512}, + {DSAWithSHA1, oidSignatureDSAWithSHA1, DSA, crypto.SHA1}, + {DSAWithSHA256, oidSignatureDSAWithSHA256, DSA, crypto.SHA256}, + {ECDSAWithSHA1, oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1}, + {ECDSAWithSHA256, oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256}, + {ECDSAWithSHA384, oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384}, + {ECDSAWithSHA512, oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512}, +} + +// pssParameters reflects the parameters in an AlgorithmIdentifier that +// specifies RSA PSS. See https://tools.ietf.org/html/rfc3447#appendix-A.2.3 +type pssParameters struct { + // The following three fields are not marked as + // optional because the default values specify SHA-1, + // which is no longer suitable for use in signatures. + Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"` + MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"` + SaltLength int `asn1:"explicit,tag:2"` + TrailerField int `asn1:"optional,explicit,tag:3,default:1"` +} + +// rsaPSSParameters returns an asn1.RawValue suitable for use as the Parameters +// in an AlgorithmIdentifier that specifies RSA PSS. +func rsaPSSParameters(hashFunc crypto.Hash) asn1.RawValue { + var hashOID asn1.ObjectIdentifier + + switch hashFunc { + case crypto.SHA256: + hashOID = oidSHA256 + case crypto.SHA384: + hashOID = oidSHA384 + case crypto.SHA512: + hashOID = oidSHA512 + } + + params := pssParameters{ + Hash: pkix.AlgorithmIdentifier{ + Algorithm: hashOID, + Parameters: asn1.NullRawValue, + }, + MGF: pkix.AlgorithmIdentifier{ + Algorithm: oidMGF1, + }, + SaltLength: hashFunc.Size(), + TrailerField: 1, + } + + mgf1Params := pkix.AlgorithmIdentifier{ + Algorithm: hashOID, + Parameters: asn1.NullRawValue, + } + + var err error + params.MGF.Parameters.FullBytes, err = asn1.Marshal(mgf1Params) + if err != nil { + panic(err) + } + + serialized, err := asn1.Marshal(params) + if err != nil { + panic(err) + } + + return asn1.RawValue{FullBytes: serialized} +} + +// GetSignatureAlgorithmFromAI converts asn1 AlgorithmIdentifier to SignatureAlgorithm int +func GetSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm { + if !ai.Algorithm.Equal(oidSignatureRSAPSS) { + for _, details := range signatureAlgorithmDetails { + if ai.Algorithm.Equal(details.oid) { + return details.algo + } + } + return UnknownSignatureAlgorithm + } + + // RSA PSS is special because it encodes important parameters + // in the Parameters. + + var params pssParameters + if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil { + return UnknownSignatureAlgorithm + } + + var mgf1HashFunc pkix.AlgorithmIdentifier + if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil { + return UnknownSignatureAlgorithm + } + + // PSS is greatly overburdened with options. This code forces + // them into three buckets by requiring that the MGF1 hash + // function always match the message hash function (as + // recommended in + // https://tools.ietf.org/html/rfc3447#section-8.1), that the + // salt length matches the hash length, and that the trailer + // field has the default value. + if !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes) || + !params.MGF.Algorithm.Equal(oidMGF1) || + !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) || + !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes) || + params.TrailerField != 1 { + return UnknownSignatureAlgorithm + } + + switch { + case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32: + return SHA256WithRSAPSS + case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48: + return SHA384WithRSAPSS + case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64: + return SHA512WithRSAPSS + } + + return UnknownSignatureAlgorithm +} + +// RFC 3279, 2.3 Public Key Algorithms +// +// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840) +// rsadsi(113549) pkcs(1) 1 } +// +// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 } +// +// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840) +// x9-57(10040) x9cm(4) 1 } +// +// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters +// +// id-ecPublicKey OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } +var ( + oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} + oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} + oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} +) + +func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm { + switch { + case oid.Equal(oidPublicKeyRSA): + return RSA + case oid.Equal(oidPublicKeyDSA): + return DSA + case oid.Equal(oidPublicKeyECDSA): + return ECDSA + } + return UnknownPublicKeyAlgorithm +} + +// RFC 5480, 2.1.1.1. Named Curve +// +// secp224r1 OBJECT IDENTIFIER ::= { +// iso(1) identified-organization(3) certicom(132) curve(0) 33 } +// +// secp256r1 OBJECT IDENTIFIER ::= { +// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) +// prime(1) 7 } +// +// secp384r1 OBJECT IDENTIFIER ::= { +// iso(1) identified-organization(3) certicom(132) curve(0) 34 } +// +// secp521r1 OBJECT IDENTIFIER ::= { +// iso(1) identified-organization(3) certicom(132) curve(0) 35 } +// +// NB: secp256r1 is equivalent to prime256v1 +var ( + oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} + oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} + oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} + oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} +) + +func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { + switch { + case oid.Equal(oidNamedCurveP224): + return elliptic.P224() + case oid.Equal(oidNamedCurveP256): + return elliptic.P256() + case oid.Equal(oidNamedCurveP384): + return elliptic.P384() + case oid.Equal(oidNamedCurveP521): + return elliptic.P521() + } + return nil +} + +func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { + switch curve { + case elliptic.P224(): + return oidNamedCurveP224, true + case elliptic.P256(): + return oidNamedCurveP256, true + case elliptic.P384(): + return oidNamedCurveP384, true + case elliptic.P521(): + return oidNamedCurveP521, true + } + + return nil, false +} + +// KeyUsage represents the set of actions that are valid for a given key. It's +// a bitmap of the KeyUsage* constants. +type KeyUsage int + +const ( + KeyUsageDigitalSignature KeyUsage = 1 << iota + KeyUsageContentCommitment + KeyUsageKeyEncipherment + KeyUsageDataEncipherment + KeyUsageKeyAgreement + KeyUsageCertSign + KeyUsageCRLSign + KeyUsageEncipherOnly + KeyUsageDecipherOnly +) + +// RFC 5280, 4.2.1.12 Extended Key Usage +// +// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } +// +// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } +// +// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } +// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } +// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } +// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } +// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } +// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } +//var ( +// oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} +// oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} +// oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} +// oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} +// oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} +// oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} +// oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} +// oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} +// oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} +// oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} +// oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3} +// oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1} +//) + +// ExtKeyUsage represents an extended set of actions that are valid for a given key. +// Each of the ExtKeyUsage* constants define a unique action. +type ExtKeyUsage int + +// TODO: slight differences in case in some names. Should be easy to align with stdlib. +// leaving for now to not break compatibility + +// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID. +var extKeyUsageOIDs = []struct { + extKeyUsage ExtKeyUsage + oid asn1.ObjectIdentifier +}{ + {ExtKeyUsageAny, oidExtKeyUsageAny}, + {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, + {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, + {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, + {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, + //{ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, + {ExtKeyUsageIpsecUser, oidExtKeyUsageIpsecEndSystem}, + //{ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, + {ExtKeyUsageIpsecTunnel, oidExtKeyUsageIpsecTunnel}, + //{ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, + {ExtKeyUsageIpsecUser, oidExtKeyUsageIpsecUser}, + {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, + //{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, + {ExtKeyUsageOcspSigning, oidExtKeyUsageOcspSigning}, + {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, + {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, +} + +// TODO: slight differences in case in some names. Should be easy to align with stdlib. +// leaving for now to not break compatibility + +// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID. +var nativeExtKeyUsageOIDs = []struct { + extKeyUsage ExtKeyUsage + oid asn1.ObjectIdentifier +}{ + {ExtKeyUsageAny, oidExtKeyUsageAny}, + {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, + {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, + {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, + {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, + {ExtKeyUsageIpsecEndSystem, oidExtKeyUsageIpsecEndSystem}, + {ExtKeyUsageIpsecTunnel, oidExtKeyUsageIpsecTunnel}, + {ExtKeyUsageIpsecUser, oidExtKeyUsageIpsecUser}, + {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, + {ExtKeyUsageOcspSigning, oidExtKeyUsageOcspSigning}, + {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, + {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, +} + +func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) { + s := oid.String() + eku, ok = ekuConstants[s] + return +} + +func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { + for _, pair := range nativeExtKeyUsageOIDs { + if eku == pair.extKeyUsage { + return pair.oid, true + } + } + return +} + +// A Certificate represents an X.509 certificate. +type Certificate struct { + Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature). + RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content. + RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo. + RawSubject []byte // DER encoded Subject + RawIssuer []byte // DER encoded Issuer + + Signature []byte + SignatureAlgorithm SignatureAlgorithm + + SelfSigned bool + + SignatureAlgorithmOID asn1.ObjectIdentifier + + PublicKeyAlgorithm PublicKeyAlgorithm + PublicKey interface{} + + PublicKeyAlgorithmOID asn1.ObjectIdentifier + + Version int + SerialNumber *big.Int + Issuer pkix.Name + Subject pkix.Name + NotBefore, NotAfter time.Time // Validity bounds. + ValidityPeriod int + KeyUsage KeyUsage + + IssuerUniqueId asn1.BitString + SubjectUniqueId asn1.BitString + + // Extensions contains raw X.509 extensions. When parsing certificates, + // this can be used to extract non-critical extensions that are not + // parsed by this package. When marshaling certificates, the Extensions + // field is ignored, see ExtraExtensions. + Extensions []pkix.Extension + + // ExtensionsMap contains raw x.509 extensions keyed by OID (in string + // representation). It allows fast membership testing of specific OIDs. Like + // the Extensions field this field is ignored when marshaling certificates. If + // multiple extensions with the same OID are present only the last + // pkix.Extension will be in this map. Consult the `Extensions` slice when it + // is required to process all extensions including duplicates. + ExtensionsMap map[string]pkix.Extension + + // ExtraExtensions contains extensions to be copied, raw, into any + // marshaled certificates. Values override any extensions that would + // otherwise be produced based on the other fields. The ExtraExtensions + // field is not populated when parsing certificates, see Extensions. + ExtraExtensions []pkix.Extension + + // UnhandledCriticalExtensions contains a list of extension IDs that + // were not (fully) processed when parsing. Verify will fail if this + // slice is non-empty, unless verification is delegated to an OS + // library which understands all the critical extensions. + // + // Users can access these extensions using Extensions and can remove + // elements from this slice if they believe that they have been + // handled. + UnhandledCriticalExtensions []asn1.ObjectIdentifier + + ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages. + UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. + + BasicConstraintsValid bool // if true then the next two fields are valid. + IsCA bool + + // MaxPathLen and MaxPathLenZero indicate the presence and + // value of the BasicConstraints' "pathLenConstraint". + // + // When parsing a certificate, a positive non-zero MaxPathLen + // means that the field was specified, -1 means it was unset, + // and MaxPathLenZero being true mean that the field was + // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false + // should be treated equivalent to -1 (unset). + // + // When generating a certificate, an unset pathLenConstraint + // can be requested with either MaxPathLen == -1 or using the + // zero value for both MaxPathLen and MaxPathLenZero. + MaxPathLen int + // MaxPathLenZero indicates that BasicConstraintsValid==true and + // MaxPathLen==0 should be interpreted as an actual Max path length + // of zero. Otherwise, that combination is interpreted as MaxPathLen + // not being set. + MaxPathLenZero bool + + SubjectKeyId []byte + AuthorityKeyId []byte + + // RFC 5280, 4.2.2.1 (Authority Information Access) + OCSPServer []string + IssuingCertificateURL []string + + // Subject Alternate Name values + OtherNames []pkix.OtherName + DNSNames []string + EmailAddresses []string + DirectoryNames []pkix.Name + EDIPartyNames []pkix.EDIPartyName + URIs []string + IPAddresses []net.IP + RegisteredIDs []asn1.ObjectIdentifier + + // Issuer Alternative Name values + IANOtherNames []pkix.OtherName + IANDNSNames []string + IANEmailAddresses []string + IANDirectoryNames []pkix.Name + IANEDIPartyNames []pkix.EDIPartyName + IANURIs []string + IANIPAddresses []net.IP + IANRegisteredIDs []asn1.ObjectIdentifier + + // Certificate Policies values + QualifierId [][]asn1.ObjectIdentifier + CPSuri [][]string + ExplicitTexts [][]asn1.RawValue + NoticeRefOrgnization [][]asn1.RawValue + NoticeRefNumbers [][]NoticeNumber + + ParsedExplicitTexts [][]string + ParsedNoticeRefOrganization [][]string + + // Name constraints + NameConstraintsCritical bool // if true then the name constraints are marked critical. + PermittedDNSNames []GeneralSubtreeString + ExcludedDNSNames []GeneralSubtreeString + PermittedEmailAddresses []GeneralSubtreeString + ExcludedEmailAddresses []GeneralSubtreeString + PermittedIPAddresses []GeneralSubtreeIP + ExcludedIPAddresses []GeneralSubtreeIP + PermittedDirectoryNames []GeneralSubtreeName + ExcludedDirectoryNames []GeneralSubtreeName + PermittedEdiPartyNames []GeneralSubtreeEdi + ExcludedEdiPartyNames []GeneralSubtreeEdi + PermittedRegisteredIDs []GeneralSubtreeOid + ExcludedRegisteredIDs []GeneralSubtreeOid + PermittedX400Addresses []GeneralSubtreeRaw + ExcludedX400Addresses []GeneralSubtreeRaw + + // CRL Distribution Points + CRLDistributionPoints []string + + PolicyIdentifiers []asn1.ObjectIdentifier + ValidationLevel CertValidationLevel + + // Fingerprints + FingerprintMD5 CertificateFingerprint + FingerprintSHA1 CertificateFingerprint + FingerprintSHA256 CertificateFingerprint + FingerprintNoCT CertificateFingerprint + + // SPKI + SPKIFingerprint CertificateFingerprint + SPKISubjectFingerprint CertificateFingerprint + TBSCertificateFingerprint CertificateFingerprint + + IsPrecert bool + + // Internal + validSignature bool + + // CT + SignedCertificateTimestampList []*ct.SignedCertificateTimestamp + + // QWACS + CABFOrganizationIdentifier *CABFOrganizationIdentifier + QCStatements *QCStatements + + // Used to speed up the zlint checks. Populated by the GetParsedDNSNames method. + parsedDNSNames []ParsedDomainName + // Used to speed up the zlint checks. Populated by the GetParsedCommonName method + parsedCommonName *ParsedDomainName + + // CAB Forum Tor Service Descriptor Hash Extensions (see EV Guidelines + // Appendix F) + TorServiceDescriptors []*TorServiceDescriptorHash +} + +// ParsedDomainName is a structure holding a parsed domain name (CommonName or +// DNS SAN) and a parsing error. +type ParsedDomainName struct { + DomainString string + ParsedDomain *publicsuffix.DomainName + ParseError error +} + +// GetParsedDNSNames returns a list of parsed SAN DNS names. It is used to cache the parsing result and +// speed up zlint linters. If invalidateCache is true, then the cache is repopulated with current list of string from +// Certificate.DNSNames. This parameter should always be false, unless the Certificate.DNSNames have been modified +// after calling GetParsedDNSNames the previous time. +func (c *Certificate) GetParsedDNSNames(invalidateCache bool) []ParsedDomainName { + if c.parsedDNSNames != nil && !invalidateCache { + return c.parsedDNSNames + } + c.parsedDNSNames = make([]ParsedDomainName, len(c.DNSNames)) + + for i := range c.DNSNames { + var parsedDomain, parseError = publicsuffix.ParseFromListWithOptions(publicsuffix.DefaultList, + c.DNSNames[i], + &publicsuffix.FindOptions{IgnorePrivate: true, DefaultRule: publicsuffix.DefaultRule}) + + c.parsedDNSNames[i].DomainString = c.DNSNames[i] + c.parsedDNSNames[i].ParsedDomain = parsedDomain + c.parsedDNSNames[i].ParseError = parseError + } + + return c.parsedDNSNames +} + +// GetParsedCommonName returns parsed subject CommonName. It is used to cache the parsing result and +// speed up zlint linters. If invalidateCache is true, then the cache is repopulated with current subject CommonName. +// This parameter should always be false, unless the Certificate.Subject.CommonName have been modified +// after calling GetParsedSubjectCommonName the previous time. +func (c *Certificate) GetParsedSubjectCommonName(invalidateCache bool) ParsedDomainName { + if c.parsedCommonName != nil && !invalidateCache { + return *c.parsedCommonName + } + + var parsedDomain, parseError = publicsuffix.ParseFromListWithOptions(publicsuffix.DefaultList, + c.Subject.CommonName, + &publicsuffix.FindOptions{IgnorePrivate: true, DefaultRule: publicsuffix.DefaultRule}) + + c.parsedCommonName = &ParsedDomainName{ + DomainString: c.Subject.CommonName, + ParsedDomain: parsedDomain, + ParseError: parseError, + } + + return *c.parsedCommonName +} + +// ErrUnsupportedAlgorithm results from attempting to perform an operation that +// involves algorithms that are not currently implemented. +var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented") + +// An InsecureAlgorithmError +type InsecureAlgorithmError SignatureAlgorithm + +func (e InsecureAlgorithmError) Error() string { + return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm(e)) +} + +// ConstraintViolationError results when a requested usage is not permitted by +// a certificate. For example: checking a signature when the public key isn't a +// certificate signing key. +type ConstraintViolationError struct{} + +func (ConstraintViolationError) Error() string { + return "x509: invalid signature: parent certificate cannot sign this kind of certificate" +} + +func (c *Certificate) Equal(other *Certificate) bool { + return bytes.Equal(c.Raw, other.Raw) +} + +func (c *Certificate) hasSANExtension() bool { + return oidInExtensions(oidExtensionSubjectAltName, c.Extensions) +} + +// Entrust have a broken root certificate (CN=Entrust.net Certification +// Authority (2048)) which isn't marked as a CA certificate and is thus invalid +// according to PKIX. +// We recognise this certificate by its SubjectPublicKeyInfo and exempt it +// from the Basic Constraints requirement. +// See http://www.entrust.net/knowledge-base/technote.cfm?tn=7869 +// +// TODO(agl): remove this hack once their reissued root is sufficiently +// widespread. +var entrustBrokenSPKI = []byte{ + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, + 0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, 0x05, + 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3, + 0x7f, 0xc7, 0x4b, 0x7e, 0x5a, 0x9f, 0xb3, 0xff, + 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, 0x10, + 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff, + 0x28, 0xce, 0xc0, 0xe6, 0x0e, 0x06, 0x91, 0x50, + 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, 0xd8, + 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6, + 0x96, 0xdc, 0xbc, 0xaa, 0xfa, 0x52, 0x77, 0x04, + 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, 0x3c, + 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65, + 0xf9, 0xc1, 0xb1, 0x3f, 0x72, 0x86, 0xf2, 0x38, + 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, 0xda, + 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9, + 0xc1, 0x65, 0x77, 0x76, 0x24, 0x4c, 0x98, 0xf7, + 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, 0x37, + 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde, + 0x20, 0x09, 0x49, 0x36, 0x24, 0x69, 0x42, 0xf6, + 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, 0x3c, + 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a, + 0xd7, 0xf7, 0x0a, 0x6f, 0xef, 0x2e, 0xd8, 0xd5, + 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, 0xe2, + 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc, + 0x51, 0x43, 0x9d, 0xe0, 0xb2, 0xc4, 0x67, 0xb4, + 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, 0x4b, + 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e, + 0x6c, 0x78, 0x90, 0x95, 0xde, 0xca, 0x3a, 0x48, + 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, 0x05, + 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09, + 0xe4, 0x1a, 0x15, 0xdc, 0x87, 0x23, 0xaa, 0xb2, + 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, 0x3d, + 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68, + 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, +} + +// CheckSignatureFrom verifies that the signature on c is a valid signature +// from parent. +func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) { + // RFC 5280, 4.2.1.9: + // "If the basic constraints extension is not present in a version 3 + // certificate, or the extension is present but the cA boolean is not + // asserted, then the certified public key MUST NOT be used to verify + // certificate signatures." + // (except for Entrust, see comment above entrustBrokenSPKI) + if (parent.Version == 3 && !parent.BasicConstraintsValid || + parent.BasicConstraintsValid && !parent.IsCA) && + !bytes.Equal(c.RawSubjectPublicKeyInfo, entrustBrokenSPKI) { + return ConstraintViolationError{} + } + + if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 { + return ConstraintViolationError{} + } + + if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm { + return ErrUnsupportedAlgorithm + } + + // TODO(agl): don't ignore the path length constraint. + + if !bytes.Equal(parent.RawSubject, c.RawIssuer) { + return errors.New("Mis-match issuer/subject") + } + + return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature) +} + +func CheckSignatureFromKey(publicKey interface{}, algo SignatureAlgorithm, signed, signature []byte) (err error) { + var hashType crypto.Hash + + switch algo { + // NOTE: exception to stdlib, allow MD5 algorithm + case MD5WithRSA: + hashType = crypto.MD5 + case SHA1WithRSA, DSAWithSHA1, ECDSAWithSHA1: + hashType = crypto.SHA1 + case SHA256WithRSA, SHA256WithRSAPSS, DSAWithSHA256, ECDSAWithSHA256: + hashType = crypto.SHA256 + case SHA384WithRSA, SHA384WithRSAPSS, ECDSAWithSHA384: + hashType = crypto.SHA384 + case SHA512WithRSA, SHA512WithRSAPSS, ECDSAWithSHA512: + hashType = crypto.SHA512 + //case MD2WithRSA, MD5WithRSA: + case MD2WithRSA: + return InsecureAlgorithmError(algo) + default: + return ErrUnsupportedAlgorithm + } + + if !hashType.Available() { + return ErrUnsupportedAlgorithm + } + h := hashType.New() + + h.Write(signed) + digest := h.Sum(nil) + + switch pub := publicKey.(type) { + case *rsa.PublicKey: + if algo.isRSAPSS() { + return rsa.VerifyPSS(pub, hashType, digest, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}) + } else { + return rsa.VerifyPKCS1v15(pub, hashType, digest, signature) + } + case *dsa.PublicKey: + dsaSig := new(dsaSignature) + if rest, err := asn1.Unmarshal(signature, dsaSig); err != nil { + return err + } else if len(rest) != 0 { + return errors.New("x509: trailing data after DSA signature") + } + if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 { + return errors.New("x509: DSA signature contained zero or negative values") + } + if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) { + return errors.New("x509: DSA verification failure") + } + return + case *ecdsa.PublicKey: + ecdsaSig := new(ecdsaSignature) + if rest, err := asn1.Unmarshal(signature, ecdsaSig); err != nil { + return err + } else if len(rest) != 0 { + return errors.New("x509: trailing data after ECDSA signature") + } + if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { + return errors.New("x509: ECDSA signature contained zero or negative values") + } + if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) { + return errors.New("x509: ECDSA verification failure") + } + return + case *AugmentedECDSA: + ecdsaSig := new(ecdsaSignature) + if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil { + return err + } + if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { + return errors.New("x509: ECDSA signature contained zero or negative values") + } + if !ecdsa.Verify(pub.Pub, digest, ecdsaSig.R, ecdsaSig.S) { + return errors.New("x509: ECDSA verification failure") + } + return + } + return ErrUnsupportedAlgorithm +} + +// CheckSignature verifies that signature is a valid signature over signed from +// c's public key. +func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) { + return CheckSignatureFromKey(c.PublicKey, algo, signed, signature) +} + +// CheckCRLSignature checks that the signature in crl is from c. +func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) error { + algo := GetSignatureAlgorithmFromAI(crl.SignatureAlgorithm) + return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign()) +} + +// UnhandledCriticalExtension results when the certificate contains an +// unimplemented X.509 extension marked as critical. +type UnhandledCriticalExtension struct { + oid asn1.ObjectIdentifier + message string +} + +func (h UnhandledCriticalExtension) Error() string { + return fmt.Sprintf("x509: unhandled critical extension: %s | %s", h.oid, h.message) +} + +// TimeInValidityPeriod returns true if NotBefore < t < NotAfter +func (c *Certificate) TimeInValidityPeriod(t time.Time) bool { + return c.NotBefore.Before(t) && c.NotAfter.After(t) +} + +// RFC 5280 4.2.1.4 +type policyInformation struct { + Policy asn1.ObjectIdentifier + Qualifiers []policyQualifierInfo `asn1:"optional"` +} + +type policyQualifierInfo struct { + PolicyQualifierId asn1.ObjectIdentifier + Qualifier asn1.RawValue +} + +type userNotice struct { + NoticeRef noticeReference `asn1:"optional"` + ExplicitText asn1.RawValue `asn1:"optional"` +} + +type noticeReference struct { + Organization asn1.RawValue + NoticeNumbers []int +} + +type NoticeNumber []int + +type generalSubtree struct { + Value asn1.RawValue `asn1:"optional"` + Min int `asn1:"tag:0,default:0,optional"` + Max int `asn1:"tag:1,optional"` +} + +type GeneralSubtreeString struct { + Data string + Max int + Min int +} + +type GeneralSubtreeIP struct { + Data net.IPNet + Max int + Min int +} + +type GeneralSubtreeName struct { + Data pkix.Name + Max int + Min int +} + +type GeneralSubtreeEdi struct { + Data pkix.EDIPartyName + Max int + Min int +} + +type GeneralSubtreeOid struct { + Data asn1.ObjectIdentifier + Max int + Min int +} + +type GeneralSubtreeRaw struct { + Data asn1.RawValue + Max int + Min int +} + +type basicConstraints struct { + IsCA bool `asn1:"optional"` + MaxPathLen int `asn1:"optional,default:-1"` +} + +// RFC 5280, 4.2.1.10 +type nameConstraints struct { + Permitted []generalSubtree `asn1:"optional,tag:0"` + Excluded []generalSubtree `asn1:"optional,tag:1"` +} + +// RFC 5280, 4.2.2.1 +type authorityInfoAccess struct { + Method asn1.ObjectIdentifier + Location asn1.RawValue +} + +// RFC 5280, 4.2.1.14 +type distributionPoint struct { + DistributionPoint distributionPointName `asn1:"optional,tag:0"` + Reason asn1.BitString `asn1:"optional,tag:1"` + CRLIssuer asn1.RawValue `asn1:"optional,tag:2"` +} + +type distributionPointName struct { + FullName asn1.RawValue `asn1:"optional,tag:0"` + RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` +} + +func maxValidationLevel(a, b CertValidationLevel) CertValidationLevel { + if a > b { + return a + } + return b +} + +func getMaxCertValidationLevel(oids []asn1.ObjectIdentifier) CertValidationLevel { + maxOID := UnknownValidationLevel + for _, oid := range oids { + if _, ok := ExtendedValidationOIDs[oid.String()]; ok { + return EV + } else if _, ok := OrganizationValidationOIDs[oid.String()]; ok { + maxOID = maxValidationLevel(maxOID, OV) + } else if _, ok := DomainValidationOIDs[oid.String()]; ok { + maxOID = maxValidationLevel(maxOID, DV) + } + } + return maxOID +} + +func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) { + asn1Data := keyData.PublicKey.RightAlign() + switch algo { + case RSA: + + // TODO: disabled since current behaviour does not expect it. Should be enabled though + // RSA public keys must have a NULL in the parameters + // (https://tools.ietf.org/html/rfc3279#section-2.3.1). + //if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) { + // return nil, errors.New("x509: RSA key missing NULL parameters") + //} + + p := new(pkcs1PublicKey) + rest, err := asn1.Unmarshal(asn1Data, p) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("x509: trailing data after RSA public key") + } + + if p.N.Sign() <= 0 { + return nil, errors.New("x509: RSA modulus is not a positive number") + } + if p.E <= 0 { + return nil, errors.New("x509: RSA public exponent is not a positive number") + } + + pub := &rsa.PublicKey{ + E: p.E, + N: p.N, + } + return pub, nil + case DSA: + var p *big.Int + rest, err := asn1.Unmarshal(asn1Data, &p) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("x509: trailing data after DSA public key") + } + paramsData := keyData.Algorithm.Parameters.FullBytes + params := new(dsaAlgorithmParameters) + rest, err = asn1.Unmarshal(paramsData, params) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("x509: trailing data after DSA parameters") + } + if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 { + return nil, errors.New("x509: zero or negative DSA parameter") + } + pub := &dsa.PublicKey{ + Parameters: dsa.Parameters{ + P: params.P, + Q: params.Q, + G: params.G, + }, + Y: p, + } + return pub, nil + case ECDSA: + paramsData := keyData.Algorithm.Parameters.FullBytes + namedCurveOID := new(asn1.ObjectIdentifier) + rest, err := asn1.Unmarshal(paramsData, namedCurveOID) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("x509: trailing data after ECDSA parameters") + } + namedCurve := namedCurveFromOID(*namedCurveOID) + if namedCurve == nil { + return nil, errors.New("x509: unsupported elliptic curve") + } + x, y := elliptic.Unmarshal(namedCurve, asn1Data) + if x == nil { + return nil, errors.New("x509: failed to unmarshal elliptic curve point") + } + key := &ecdsa.PublicKey{ + Curve: namedCurve, + X: x, + Y: y, + } + + pub := &AugmentedECDSA{ + Pub: key, + Raw: keyData.PublicKey, + } + return pub, nil + default: + return nil, nil + } +} + +func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) { + // RFC 5280, 4.2.1.6 + + // SubjectAltName ::= GeneralNames + // + // 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 } + var seq asn1.RawValue + var rest []byte + if rest, err = asn1.Unmarshal(value, &seq); err != nil { + return + } else if len(rest) != 0 { + err = errors.New("x509: trailing data after X.509 extension") + return + } + if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { + err = asn1.StructuralError{Msg: "bad SAN sequence"} + return + } + + rest = seq.Bytes + for len(rest) > 0 { + var v asn1.RawValue + rest, err = asn1.Unmarshal(rest, &v) + if err != nil { + return + } + switch v.Tag { + case 1: + emailAddresses = append(emailAddresses, string(v.Bytes)) + case 2: + dnsNames = append(dnsNames, string(v.Bytes)) + case 7: + switch len(v.Bytes) { + case net.IPv4len, net.IPv6len: + ipAddresses = append(ipAddresses, v.Bytes) + default: + err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes))) + return + } + } + } + + return +} + +func parseGeneralNames(value []byte) (otherNames []pkix.OtherName, dnsNames, emailAddresses, URIs []string, directoryNames []pkix.Name, ediPartyNames []pkix.EDIPartyName, ipAddresses []net.IP, registeredIDs []asn1.ObjectIdentifier, err error) { + // RFC 5280, 4.2.1.6 + + // SubjectAltName ::= GeneralNames + // + // 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 } + var seq asn1.RawValue + if _, err = asn1.Unmarshal(value, &seq); err != nil { + return + } + if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { + err = asn1.StructuralError{Msg: "bad SAN sequence"} + return + } + + rest := seq.Bytes + for len(rest) > 0 { + var v asn1.RawValue + rest, err = asn1.Unmarshal(rest, &v) + if err != nil { + return + } + switch v.Tag { + case 0: + var oName pkix.OtherName + _, err = asn1.UnmarshalWithParams(v.FullBytes, &oName, "tag:0") + if err != nil { + return + } + otherNames = append(otherNames, oName) + case 1: + emailAddresses = append(emailAddresses, string(v.Bytes)) + case 2: + dnsNames = append(dnsNames, string(v.Bytes)) + case 4: + var rdn pkix.RDNSequence + _, err = asn1.Unmarshal(v.Bytes, &rdn) + if err != nil { + return + } + var dir pkix.Name + dir.FillFromRDNSequence(&rdn) + directoryNames = append(directoryNames, dir) + case 5: + var ediName pkix.EDIPartyName + _, err = asn1.UnmarshalWithParams(v.FullBytes, &ediName, "tag:5") + if err != nil { + return + } + ediPartyNames = append(ediPartyNames, ediName) + case 6: + URIs = append(URIs, string(v.Bytes)) + case 7: + switch len(v.Bytes) { + case net.IPv4len, net.IPv6len: + ipAddresses = append(ipAddresses, v.Bytes) + default: + err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes))) + return + } + case 8: + var id asn1.ObjectIdentifier + _, err = asn1.UnmarshalWithParams(v.FullBytes, &id, "tag:8") + if err != nil { + return + } + registeredIDs = append(registeredIDs, id) + } + } + + return +} + +//TODO +func parseCertificate(in *certificate) (*Certificate, error) { + out := new(Certificate) + out.Raw = in.Raw + out.RawTBSCertificate = in.TBSCertificate.Raw + out.RawSubjectPublicKeyInfo = in.TBSCertificate.PublicKey.Raw + out.RawSubject = in.TBSCertificate.Subject.FullBytes + out.RawIssuer = in.TBSCertificate.Issuer.FullBytes + + // Fingerprints + out.FingerprintMD5 = MD5Fingerprint(in.Raw) + out.FingerprintSHA1 = SHA1Fingerprint(in.Raw) + out.FingerprintSHA256 = SHA256Fingerprint(in.Raw) + out.SPKIFingerprint = SHA256Fingerprint(in.TBSCertificate.PublicKey.Raw) + out.TBSCertificateFingerprint = SHA256Fingerprint(in.TBSCertificate.Raw) + + tbs := in.TBSCertificate + originalExtensions := in.TBSCertificate.Extensions + + // Blow away the raw data since it also includes CT data + tbs.Raw = nil + + // remove the CT extensions + extensions := make([]pkix.Extension, 0, len(originalExtensions)) + for _, extension := range originalExtensions { + if extension.Id.Equal(oidExtensionCTPrecertificatePoison) { + continue + } + if extension.Id.Equal(oidExtensionSignedCertificateTimestampList) { + continue + } + extensions = append(extensions, extension) + } + + tbs.Extensions = extensions + + tbsbytes, err := asn1.Marshal(tbs) + if err != nil { + return nil, err + } + if tbsbytes == nil { + return nil, asn1.SyntaxError{Msg: "Trailing data"} + } + out.FingerprintNoCT = SHA256Fingerprint(tbsbytes[:]) + + // Hash both SPKI and Subject to create a fingerprint that we can use to describe a CA + hasher := sha256.New() + hasher.Write(in.TBSCertificate.PublicKey.Raw) + hasher.Write(in.TBSCertificate.Subject.FullBytes) + out.SPKISubjectFingerprint = hasher.Sum(nil) + + out.Signature = in.SignatureValue.RightAlign() + out.SignatureAlgorithm = + GetSignatureAlgorithmFromAI(in.TBSCertificate.SignatureAlgorithm) + + out.SignatureAlgorithmOID = in.TBSCertificate.SignatureAlgorithm.Algorithm + + out.PublicKeyAlgorithm = + getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm) + out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey) + if err != nil { + return nil, err + } + + out.PublicKeyAlgorithmOID = in.TBSCertificate.PublicKey.Algorithm.Algorithm + out.Version = in.TBSCertificate.Version + 1 + out.SerialNumber = in.TBSCertificate.SerialNumber + + var issuer, subject pkix.RDNSequence + if _, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil { + return nil, err + } + if _, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil { + return nil, err + } + + out.Issuer.FillFromRDNSequence(&issuer) + out.Subject.FillFromRDNSequence(&subject) + + // Check if self-signed + if bytes.Equal(out.RawSubject, out.RawIssuer) { + // Possibly self-signed, check the signature against itself. + if err := out.CheckSignature(out.SignatureAlgorithm, out.RawTBSCertificate, out.Signature); err == nil { + out.SelfSigned = true + } + } + + out.NotBefore = in.TBSCertificate.Validity.NotBefore + out.NotAfter = in.TBSCertificate.Validity.NotAfter + + out.ValidityPeriod = int(out.NotAfter.Sub(out.NotBefore).Seconds()) + + out.IssuerUniqueId = in.TBSCertificate.UniqueId + out.SubjectUniqueId = in.TBSCertificate.SubjectUniqueId + + out.ExtensionsMap = make(map[string]pkix.Extension, len(in.TBSCertificate.Extensions)) + for _, e := range in.TBSCertificate.Extensions { + out.Extensions = append(out.Extensions, e) + out.ExtensionsMap[e.Id.String()] = e + + if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 { + switch e.Id[3] { + case 15: + // RFC 5280, 4.2.1.3 + var usageBits asn1.BitString + _, err := asn1.Unmarshal(e.Value, &usageBits) + + if err == nil { + var usage int + for i := 0; i < 9; i++ { + if usageBits.At(i) != 0 { + usage |= 1 << uint(i) + } + } + out.KeyUsage = KeyUsage(usage) + continue + } + case 19: + // RFC 5280, 4.2.1.9 + var constraints basicConstraints + _, err := asn1.Unmarshal(e.Value, &constraints) + + if err == nil { + out.BasicConstraintsValid = true + out.IsCA = constraints.IsCA + out.MaxPathLen = constraints.MaxPathLen + out.MaxPathLenZero = out.MaxPathLen == 0 + continue + } + case 17: + out.OtherNames, out.DNSNames, out.EmailAddresses, out.URIs, out.DirectoryNames, out.EDIPartyNames, out.IPAddresses, out.RegisteredIDs, err = parseGeneralNames(e.Value) + if err != nil { + return nil, err + } + + if len(out.DNSNames) > 0 || len(out.EmailAddresses) > 0 || len(out.IPAddresses) > 0 { + continue + } + // If we didn't parse any of the names then we + // fall through to the critical check below. + case 18: + out.IANOtherNames, out.IANDNSNames, out.IANEmailAddresses, out.IANURIs, out.IANDirectoryNames, out.IANEDIPartyNames, out.IANIPAddresses, out.IANRegisteredIDs, err = parseGeneralNames(e.Value) + if err != nil { + return nil, err + } + + if len(out.IANDNSNames) > 0 || len(out.IANEmailAddresses) > 0 || len(out.IANIPAddresses) > 0 { + continue + } + case 30: + // RFC 5280, 4.2.1.10 + + // NameConstraints ::= SEQUENCE { + // permittedSubtrees [0] GeneralSubtrees OPTIONAL, + // excludedSubtrees [1] GeneralSubtrees OPTIONAL } + // + // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree + // + // GeneralSubtree ::= SEQUENCE { + // base GeneralName, + // Min [0] BaseDistance DEFAULT 0, + // Max [1] BaseDistance OPTIONAL } + // + // BaseDistance ::= INTEGER (0..MAX) + + var constraints nameConstraints + _, err := asn1.Unmarshal(e.Value, &constraints) + if err != nil { + return nil, err + } + + if e.Critical { + out.NameConstraintsCritical = true + } + + for _, subtree := range constraints.Permitted { + switch subtree.Value.Tag { + case 1: + out.PermittedEmailAddresses = append(out.PermittedEmailAddresses, GeneralSubtreeString{Data: string(subtree.Value.Bytes), Max: subtree.Max, Min: subtree.Min}) + case 2: + out.PermittedDNSNames = append(out.PermittedDNSNames, GeneralSubtreeString{Data: string(subtree.Value.Bytes), Max: subtree.Max, Min: subtree.Min}) + case 3: + out.PermittedX400Addresses = append(out.PermittedX400Addresses, GeneralSubtreeRaw{Data: subtree.Value, Max: subtree.Max, Min: subtree.Min}) + case 4: + var rawdn pkix.RDNSequence + if _, err := asn1.Unmarshal(subtree.Value.Bytes, &rawdn); err != nil { + return out, err + } + var dn pkix.Name + dn.FillFromRDNSequence(&rawdn) + out.PermittedDirectoryNames = append(out.PermittedDirectoryNames, GeneralSubtreeName{Data: dn, Max: subtree.Max, Min: subtree.Min}) + case 5: + var ediName pkix.EDIPartyName + _, err = asn1.UnmarshalWithParams(subtree.Value.FullBytes, &ediName, "tag:5") + if err != nil { + return out, err + } + out.PermittedEdiPartyNames = append(out.PermittedEdiPartyNames, GeneralSubtreeEdi{Data: ediName, Max: subtree.Max, Min: subtree.Min}) + case 7: + switch len(subtree.Value.Bytes) { + case net.IPv4len * 2: + ip := net.IPNet{IP: subtree.Value.Bytes[:net.IPv4len], Mask: subtree.Value.Bytes[net.IPv4len:]} + out.PermittedIPAddresses = append(out.PermittedIPAddresses, GeneralSubtreeIP{Data: ip, Max: subtree.Max, Min: subtree.Min}) + case net.IPv6len * 2: + ip := net.IPNet{IP: subtree.Value.Bytes[:net.IPv6len], Mask: subtree.Value.Bytes[net.IPv6len:]} + out.PermittedIPAddresses = append(out.PermittedIPAddresses, GeneralSubtreeIP{Data: ip, Max: subtree.Max, Min: subtree.Min}) + default: + return out, errors.New("x509: certificate name constraint contained IP address range of length " + strconv.Itoa(len(subtree.Value.Bytes))) + } + case 8: + var id asn1.ObjectIdentifier + _, err = asn1.UnmarshalWithParams(subtree.Value.FullBytes, &id, "tag:8") + if err != nil { + return out, err + } + out.PermittedRegisteredIDs = append(out.PermittedRegisteredIDs, GeneralSubtreeOid{Data: id, Max: subtree.Max, Min: subtree.Min}) + } + } + for _, subtree := range constraints.Excluded { + switch subtree.Value.Tag { + case 1: + out.ExcludedEmailAddresses = append(out.ExcludedEmailAddresses, GeneralSubtreeString{Data: string(subtree.Value.Bytes), Max: subtree.Max, Min: subtree.Min}) + case 2: + out.ExcludedDNSNames = append(out.ExcludedDNSNames, GeneralSubtreeString{Data: string(subtree.Value.Bytes), Max: subtree.Max, Min: subtree.Min}) + case 3: + out.ExcludedX400Addresses = append(out.ExcludedX400Addresses, GeneralSubtreeRaw{Data: subtree.Value, Max: subtree.Max, Min: subtree.Min}) + case 4: + var rawdn pkix.RDNSequence + if _, err := asn1.Unmarshal(subtree.Value.Bytes, &rawdn); err != nil { + return out, err + } + var dn pkix.Name + dn.FillFromRDNSequence(&rawdn) + out.ExcludedDirectoryNames = append(out.ExcludedDirectoryNames, GeneralSubtreeName{Data: dn, Max: subtree.Max, Min: subtree.Min}) + case 5: + var ediName pkix.EDIPartyName + _, err = asn1.Unmarshal(subtree.Value.Bytes, &ediName) + if err != nil { + return out, err + } + out.ExcludedEdiPartyNames = append(out.ExcludedEdiPartyNames, GeneralSubtreeEdi{Data: ediName, Max: subtree.Max, Min: subtree.Min}) + case 7: + switch len(subtree.Value.Bytes) { + case net.IPv4len * 2: + ip := net.IPNet{IP: subtree.Value.Bytes[:net.IPv4len], Mask: subtree.Value.Bytes[net.IPv4len:]} + out.ExcludedIPAddresses = append(out.ExcludedIPAddresses, GeneralSubtreeIP{Data: ip, Max: subtree.Max, Min: subtree.Min}) + case net.IPv6len * 2: + ip := net.IPNet{IP: subtree.Value.Bytes[:net.IPv6len], Mask: subtree.Value.Bytes[net.IPv6len:]} + out.ExcludedIPAddresses = append(out.ExcludedIPAddresses, GeneralSubtreeIP{Data: ip, Max: subtree.Max, Min: subtree.Min}) + default: + return out, errors.New("x509: certificate name constraint contained IP address range of length " + strconv.Itoa(len(subtree.Value.Bytes))) + } + case 8: + var id asn1.ObjectIdentifier + _, err = asn1.Unmarshal(subtree.Value.Bytes, &id) + if err != nil { + return out, err + } + out.ExcludedRegisteredIDs = append(out.ExcludedRegisteredIDs, GeneralSubtreeOid{Data: id, Max: subtree.Max, Min: subtree.Min}) + } + } + continue + + case 31: + // RFC 5280, 4.2.1.14 + + // 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 } + + var cdp []distributionPoint + _, err := asn1.Unmarshal(e.Value, &cdp) + if err != nil { + return nil, err + } + + for _, dp := range cdp { + // Per RFC 5280, 4.2.1.13, one of distributionPoint or cRLIssuer may be empty. + if len(dp.DistributionPoint.FullName.Bytes) == 0 { + continue + } + + var n asn1.RawValue + dpName := dp.DistributionPoint.FullName.Bytes + // FullName is a GeneralNames, which is a SEQUENCE OF + // GeneralName, which in turn is a CHOICE. + // Per https://www.ietf.org/rfc/rfc5280.txt, multiple names + // for a single DistributionPoint give different pointers to + // the same CRL. + for len(dpName) > 0 { + dpName, err = asn1.Unmarshal(dpName, &n) + if err != nil { + return nil, err + } + if n.Tag == 6 { + out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes)) + } + } + } + continue + + case 35: + // RFC 5280, 4.2.1.1 + var a authKeyId + _, err = asn1.Unmarshal(e.Value, &a) + if err != nil { + return nil, err + } + out.AuthorityKeyId = a.Id + continue + + case 37: + // RFC 5280, 4.2.1.12. Extended Key Usage + + // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } + // + // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + // + // KeyPurposeId ::= OBJECT IDENTIFIER + + var keyUsage []asn1.ObjectIdentifier + _, err = asn1.Unmarshal(e.Value, &keyUsage) + if err != nil { + return nil, err + } + + for _, u := range keyUsage { + if extKeyUsage, ok := extKeyUsageFromOID(u); ok { + out.ExtKeyUsage = append(out.ExtKeyUsage, extKeyUsage) + } else { + out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u) + } + } + + continue + + case 14: + // RFC 5280, 4.2.1.2 + var keyid []byte + _, err = asn1.Unmarshal(e.Value, &keyid) + if err != nil { + return nil, err + } + out.SubjectKeyId = keyid + continue + + case 32: + // RFC 5280 4.2.1.4: Certificate Policies + var policies []policyInformation + if _, err = asn1.Unmarshal(e.Value, &policies); err != nil { + return nil, err + } + out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies)) + out.QualifierId = make([][]asn1.ObjectIdentifier, len(policies)) + out.ExplicitTexts = make([][]asn1.RawValue, len(policies)) + out.NoticeRefOrgnization = make([][]asn1.RawValue, len(policies)) + out.NoticeRefNumbers = make([][]NoticeNumber, len(policies)) + out.ParsedExplicitTexts = make([][]string, len(policies)) + out.ParsedNoticeRefOrganization = make([][]string, len(policies)) + out.CPSuri = make([][]string, len(policies)) + + for i, policy := range policies { + out.PolicyIdentifiers[i] = policy.Policy + // parse optional Qualifier for zlint + for _, qualifier := range policy.Qualifiers { + out.QualifierId[i] = append(out.QualifierId[i], qualifier.PolicyQualifierId) + userNoticeOID := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2} + cpsURIOID := asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1} + if qualifier.PolicyQualifierId.Equal(userNoticeOID) { + var un userNotice + if _, err = asn1.Unmarshal(qualifier.Qualifier.FullBytes, &un); err != nil { + return nil, err + } + if len(un.ExplicitText.Bytes) != 0 { + out.ExplicitTexts[i] = append(out.ExplicitTexts[i], un.ExplicitText) + out.ParsedExplicitTexts[i] = append(out.ParsedExplicitTexts[i], string(un.ExplicitText.Bytes)) + } + if un.NoticeRef.Organization.Bytes != nil || un.NoticeRef.NoticeNumbers != nil { + out.NoticeRefOrgnization[i] = append(out.NoticeRefOrgnization[i], un.NoticeRef.Organization) + out.NoticeRefNumbers[i] = append(out.NoticeRefNumbers[i], un.NoticeRef.NoticeNumbers) + out.ParsedNoticeRefOrganization[i] = append(out.ParsedNoticeRefOrganization[i], string(un.NoticeRef.Organization.Bytes)) + } + } + if qualifier.PolicyQualifierId.Equal(cpsURIOID) { + var cpsURIRaw asn1.RawValue + if _, err = asn1.Unmarshal(qualifier.Qualifier.FullBytes, &cpsURIRaw); err != nil { + return nil, err + } + out.CPSuri[i] = append(out.CPSuri[i], string(cpsURIRaw.Bytes)) + } + } + } + if out.SelfSigned { + out.ValidationLevel = UnknownValidationLevel + } else { + // See http://unmitigatedrisk.com/?p=203 + validationLevel := getMaxCertValidationLevel(out.PolicyIdentifiers) + if validationLevel == UnknownValidationLevel { + if (len(out.Subject.Organization) > 0 && out.Subject.Organization[0] == out.Subject.CommonName) || (len(out.Subject.OrganizationalUnit) > 0 && strings.Contains(out.Subject.OrganizationalUnit[0], "Domain Control Validated")) { + if len(out.Subject.Locality) == 0 && len(out.Subject.Province) == 0 && len(out.Subject.PostalCode) == 0 { + validationLevel = DV + } + } else if len(out.Subject.Organization) > 0 && out.Subject.Organization[0] == "Persona Not Validated" && strings.Contains(out.Issuer.CommonName, "StartCom") { + validationLevel = DV + } + } + out.ValidationLevel = validationLevel + } + } + } else if e.Id.Equal(oidExtensionAuthorityInfoAccess) { + // RFC 5280 4.2.2.1: Authority Information Access + var aia []authorityInfoAccess + if _, err = asn1.Unmarshal(e.Value, &aia); err != nil { + return nil, err + } + + for _, v := range aia { + // GeneralName: uniformResourceIdentifier [6] IA5String + if v.Location.Tag != 6 { + continue + } + if v.Method.Equal(oidAuthorityInfoAccessOcsp) { + out.OCSPServer = append(out.OCSPServer, string(v.Location.Bytes)) + } else if v.Method.Equal(oidAuthorityInfoAccessIssuers) { + out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes)) + } + } + } else if e.Id.Equal(oidExtensionSignedCertificateTimestampList) { + // SignedCertificateTimestamp + //var scts asn1.RawValue + var scts []byte + if _, err = asn1.Unmarshal(e.Value, &scts); err != nil { + return nil, err + } + // ignore length of + if len(scts) < 2 { + return nil, errors.New("malformed SCT extension: length field") + } + scts = scts[2:] + for len(scts) > 0 { + length := int(scts[1]) + (int(scts[0]) << 8) + if (length + 2) > len(scts) { + return nil, errors.New("malformed SCT extension: incomplete SCT") + } + sct, err := ct.DeserializeSCT(bytes.NewReader(scts[2 : length+2])) + if err != nil { + return nil, err + } + scts = scts[2+length:] + out.SignedCertificateTimestampList = append(out.SignedCertificateTimestampList, sct) + } + } else if e.Id.Equal(oidExtensionCTPrecertificatePoison) { + if e.Value[0] == 5 && e.Value[1] == 0 { + out.IsPrecert = true + continue + } else { + return nil, UnhandledCriticalExtension{e.Id, "Malformed precert poison"} + } + } else if e.Id.Equal(oidBRTorServiceDescriptor) { + descs, err := parseTorServiceDescriptorSyntax(e) + if err != nil { + return nil, err + } + out.TorServiceDescriptors = descs + } else if e.Id.Equal(oidExtCABFOrganizationID) { + cabf := CABFOrganizationIDASN{} + _, err := asn1.Unmarshal(e.Value, &cabf) + if err != nil { + return nil, err + } + out.CABFOrganizationIdentifier = &CABFOrganizationIdentifier{ + Scheme: cabf.RegistrationSchemeIdentifier, + Country: cabf.RegistrationCountry, + Reference: cabf.RegistrationReference, + State: cabf.RegistrationStateOrProvince, + } + } else if e.Id.Equal(oidExtQCStatements) { + rawStatements := QCStatementsASN{} + _, err := asn1.Unmarshal(e.Value, &rawStatements.QCStatements) + if err != nil { + return nil, err + } + qcStatements := QCStatements{} + if err := qcStatements.Parse(&rawStatements); err != nil { + return nil, err + } + out.QCStatements = &qcStatements + } + + //if e.Critical { + // return out, UnhandledCriticalExtension{e.Id} + //} + } + + return out, nil +} + +// ParseCertificate parses a single certificate from the given ASN.1 DER data. +func ParseCertificate(asn1Data []byte) (*Certificate, error) { + var cert certificate + rest, err := asn1.Unmarshal(asn1Data, &cert) + if err != nil { + return nil, err + } + if len(rest) > 0 { + return nil, asn1.SyntaxError{Msg: "trailing data"} + } + + return parseCertificate(&cert) +} + +// ParseCertificates parses one or more certificates from the given ASN.1 DER +// data. The certificates must be concatenated with no intermediate padding. +func ParseCertificates(asn1Data []byte) ([]*Certificate, error) { + var v []*certificate + + for len(asn1Data) > 0 { + cert := new(certificate) + var err error + asn1Data, err = asn1.Unmarshal(asn1Data, cert) + if err != nil { + return nil, err + } + v = append(v, cert) + } + + ret := make([]*Certificate, len(v)) + for i, ci := range v { + cert, err := parseCertificate(ci) + if err != nil { + return nil, err + } + ret[i] = cert + } + + return ret, nil +} + +func ParseTBSCertificate(asn1Data []byte) (*Certificate, error) { + var tbsCert tbsCertificate + rest, err := asn1.Unmarshal(asn1Data, &tbsCert) + if err != nil { + //log.Print("Err unmarshalling asn1Data", asn1Data, rest) + return nil, err + } + if len(rest) > 0 { + return nil, asn1.SyntaxError{Msg: "trailing data"} + } + return parseCertificate(&certificate{ + Raw: tbsCert.Raw, + TBSCertificate: tbsCert}) +} + +// SubjectAndKey represents a (subjecty, subject public key info) tuple. +type SubjectAndKey struct { + RawSubject []byte + RawSubjectPublicKeyInfo []byte + Fingerprint CertificateFingerprint + PublicKey interface{} + PublicKeyAlgorithm PublicKeyAlgorithm +} + +// SubjectAndKey returns a SubjectAndKey for this certificate. +func (c *Certificate) SubjectAndKey() *SubjectAndKey { + return &SubjectAndKey{ + RawSubject: c.RawSubject, + RawSubjectPublicKeyInfo: c.RawSubjectPublicKeyInfo, + Fingerprint: c.SPKISubjectFingerprint, + PublicKey: c.PublicKey, + PublicKeyAlgorithm: c.PublicKeyAlgorithm, + } +} + +func reverseBitsInAByte(in byte) byte { + b1 := in>>4 | in<<4 + b2 := b1>>2&0x33 | b1<<2&0xcc + b3 := b2>>1&0x55 | b2<<1&0xaa + return b3 +} + +// asn1BitLength returns the bit-length of bitString by considering the +// most-significant bit in a byte to be the "first" bit. This convention +// matches ASN.1, but differs from almost everything else. +func asn1BitLength(bitString []byte) int { + bitLen := len(bitString) * 8 + + for i := range bitString { + b := bitString[len(bitString)-i-1] + + for bit := uint(0); bit < 8; bit++ { + if (b>>bit)&1 == 1 { + return bitLen + } + bitLen-- + } + } + + return 0 +} + +var ( + oidExtensionSubjectKeyId = []int{2, 5, 29, 14} + oidExtensionKeyUsage = []int{2, 5, 29, 15} + oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37} + oidExtensionAuthorityKeyId = []int{2, 5, 29, 35} + oidExtensionBasicConstraints = []int{2, 5, 29, 19} + oidExtensionSubjectAltName = []int{2, 5, 29, 17} + oidExtensionIssuerAltName = []int{2, 5, 29, 18} + oidExtensionCertificatePolicies = []int{2, 5, 29, 32} + oidExtensionNameConstraints = []int{2, 5, 29, 30} + oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31} + oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1} + oidExtensionSignedCertificateTimestampList = []int{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} +) + +var ( + oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1} + oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2} +) + +// oidNotInExtensions returns whether an extension with the given oid exists in +// extensions. +func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool { + for _, e := range extensions { + if e.Id.Equal(oid) { + return true + } + } + return false +} + +// marshalSANs marshals a list of addresses into a the contents of an X.509 +// SubjectAlternativeName extension. +func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP) (derBytes []byte, err error) { + var rawValues []asn1.RawValue + for _, name := range dnsNames { + rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)}) + } + for _, email := range emailAddresses { + rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)}) + } + for _, rawIP := range ipAddresses { + // If possible, we always want to encode IPv4 addresses in 4 bytes. + ip := rawIP.To4() + if ip == nil { + ip = rawIP + } + rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip}) + } + return asn1.Marshal(rawValues) +} + +// NOTE ignoring authorityKeyID argument +func buildExtensions(template *Certificate, _ []byte) (ret []pkix.Extension, err error) { + ret = make([]pkix.Extension, 10 /* Max number of elements. */) + n := 0 + + if template.KeyUsage != 0 && + !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) { + ret[n].Id = oidExtensionKeyUsage + ret[n].Critical = true + + var a [2]byte + a[0] = reverseBitsInAByte(byte(template.KeyUsage)) + a[1] = reverseBitsInAByte(byte(template.KeyUsage >> 8)) + + l := 1 + if a[1] != 0 { + l = 2 + } + + ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: a[0:l], BitLength: l * 8}) + if err != nil { + return + } + n++ + } + + if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) && + !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) { + ret[n].Id = oidExtensionExtendedKeyUsage + + var oids []asn1.ObjectIdentifier + for _, u := range template.ExtKeyUsage { + if oid, ok := oidFromExtKeyUsage(u); ok { + oids = append(oids, oid) + } else { + panic("internal error") + } + } + + oids = append(oids, template.UnknownExtKeyUsage...) + + ret[n].Value, err = asn1.Marshal(oids) + if err != nil { + return + } + n++ + } + + if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) { + // Leaving MaxPathLen as zero indicates that no Max path + // length is desired, unless MaxPathLenZero is set. A value of + // -1 causes encoding/asn1 to omit the value as desired. + maxPathLen := template.MaxPathLen + if maxPathLen == 0 && !template.MaxPathLenZero { + maxPathLen = -1 + } + ret[n].Id = oidExtensionBasicConstraints + ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, maxPathLen}) + ret[n].Critical = true + if err != nil { + return + } + n++ + } + + if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) { + ret[n].Id = oidExtensionSubjectKeyId + ret[n].Value, err = asn1.Marshal(template.SubjectKeyId) + if err != nil { + return + } + n++ + } + + if len(template.AuthorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) { + ret[n].Id = oidExtensionAuthorityKeyId + ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId}) + if err != nil { + return + } + n++ + } + + if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) && + !oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) { + ret[n].Id = oidExtensionAuthorityInfoAccess + var aiaValues []authorityInfoAccess + for _, name := range template.OCSPServer { + aiaValues = append(aiaValues, authorityInfoAccess{ + Method: oidAuthorityInfoAccessOcsp, + Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}, + }) + } + for _, name := range template.IssuingCertificateURL { + aiaValues = append(aiaValues, authorityInfoAccess{ + Method: oidAuthorityInfoAccessIssuers, + Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}, + }) + } + ret[n].Value, err = asn1.Marshal(aiaValues) + if err != nil { + return + } + n++ + } + + if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) && + !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) { + ret[n].Id = oidExtensionSubjectAltName + ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses) + if err != nil { + return + } + n++ + } + + if len(template.PolicyIdentifiers) > 0 && + !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) { + ret[n].Id = oidExtensionCertificatePolicies + policies := make([]policyInformation, len(template.PolicyIdentifiers)) + for i, policy := range template.PolicyIdentifiers { + policies[i].Policy = policy + } + ret[n].Value, err = asn1.Marshal(policies) + if err != nil { + return + } + n++ + } + + // TODO: this can be cleaned up in go1.10 + if (len(template.PermittedEmailAddresses) > 0 || len(template.PermittedDNSNames) > 0 || len(template.PermittedDirectoryNames) > 0 || + len(template.PermittedIPAddresses) > 0 || len(template.ExcludedEmailAddresses) > 0 || len(template.ExcludedDNSNames) > 0 || + len(template.ExcludedDirectoryNames) > 0 || len(template.ExcludedIPAddresses) > 0) && + !oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) { + ret[n].Id = oidExtensionNameConstraints + if template.NameConstraintsCritical { + ret[n].Critical = true + } + + var out nameConstraints + + for _, permitted := range template.PermittedEmailAddresses { + out.Permitted = append(out.Permitted, generalSubtree{Value: asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(permitted.Data)}}) + } + for _, excluded := range template.ExcludedEmailAddresses { + out.Excluded = append(out.Excluded, generalSubtree{Value: asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(excluded.Data)}}) + } + for _, permitted := range template.PermittedDNSNames { + out.Permitted = append(out.Permitted, generalSubtree{Value: asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(permitted.Data)}}) + } + for _, excluded := range template.ExcludedDNSNames { + out.Excluded = append(out.Excluded, generalSubtree{Value: asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(excluded.Data)}}) + } + for _, permitted := range template.PermittedDirectoryNames { + var dn []byte + dn, err = asn1.Marshal(permitted.Data.ToRDNSequence()) + if err != nil { + return + } + out.Permitted = append(out.Permitted, generalSubtree{Value: asn1.RawValue{Tag: 4, Class: 2, IsCompound: true, Bytes: dn}}) + } + for _, excluded := range template.ExcludedDirectoryNames { + var dn []byte + dn, err = asn1.Marshal(excluded.Data.ToRDNSequence()) + if err != nil { + return + } + out.Excluded = append(out.Excluded, generalSubtree{Value: asn1.RawValue{Tag: 4, Class: 2, IsCompound: true, Bytes: dn}}) + } + for _, permitted := range template.PermittedIPAddresses { + ip := append(permitted.Data.IP, permitted.Data.Mask...) + out.Permitted = append(out.Permitted, generalSubtree{Value: asn1.RawValue{Tag: 7, Class: 2, Bytes: ip}}) + } + for _, excluded := range template.ExcludedIPAddresses { + ip := append(excluded.Data.IP, excluded.Data.Mask...) + out.Excluded = append(out.Excluded, generalSubtree{Value: asn1.RawValue{Tag: 7, Class: 2, Bytes: ip}}) + } + ret[n].Value, err = asn1.Marshal(out) + if err != nil { + return + } + n++ + } + + if len(template.CRLDistributionPoints) > 0 && + !oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) { + ret[n].Id = oidExtensionCRLDistributionPoints + + var crlDp []distributionPoint + for _, name := range template.CRLDistributionPoints { + rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)}) + + dp := distributionPoint{ + DistributionPoint: distributionPointName{ + FullName: asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: rawFullName}, + }, + } + crlDp = append(crlDp, dp) + } + + ret[n].Value, err = asn1.Marshal(crlDp) + if err != nil { + return + } + n++ + } + + // Adding another extension here? Remember to update the Max number + // of elements in the make() at the top of the function. + + return append(ret[:n], template.ExtraExtensions...), nil +} + +func subjectBytes(cert *Certificate) ([]byte, error) { + if len(cert.RawSubject) > 0 { + return cert.RawSubject, nil + } + + return asn1.Marshal(cert.Subject.ToRDNSequence()) +} + +// signingParamsForPublicKey returns the parameters to use for signing with +// priv. If requestedSigAlgo is not zero then it overrides the default +// signature algorithm. +func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { + var pubType PublicKeyAlgorithm + + switch pub := pub.(type) { + case *rsa.PublicKey: + pubType = RSA + hashFunc = crypto.SHA256 + sigAlgo.Algorithm = oidSignatureSHA256WithRSA + sigAlgo.Parameters = asn1.NullRawValue + + case *ecdsa.PublicKey: + pubType = ECDSA + + switch pub.Curve { + case elliptic.P224(), elliptic.P256(): + hashFunc = crypto.SHA256 + sigAlgo.Algorithm = oidSignatureECDSAWithSHA256 + case elliptic.P384(): + hashFunc = crypto.SHA384 + sigAlgo.Algorithm = oidSignatureECDSAWithSHA384 + case elliptic.P521(): + hashFunc = crypto.SHA512 + sigAlgo.Algorithm = oidSignatureECDSAWithSHA512 + default: + err = errors.New("x509: unknown elliptic curve") + } + + default: + err = errors.New("x509: only RSA and ECDSA keys supported") + } + + if err != nil { + return + } + + if requestedSigAlgo == 0 { + return + } + + found := false + for _, details := range signatureAlgorithmDetails { + if details.algo == requestedSigAlgo { + if details.pubKeyAlgo != pubType { + err = errors.New("x509: requested SignatureAlgorithm does not match private key type") + return + } + sigAlgo.Algorithm, hashFunc = details.oid, details.hash + if hashFunc == 0 { + err = errors.New("x509: cannot sign with hash function requested") + return + } + if requestedSigAlgo.isRSAPSS() { + sigAlgo.Parameters = rsaPSSParameters(hashFunc) + } + found = true + break + } + } + + if !found { + err = errors.New("x509: unknown SignatureAlgorithm") + } + + return +} + +// CreateCertificate creates a new certificate based on a template. +// The following members of template are used: AuthorityKeyId, +// BasicConstraintsValid, DNSNames, ExcludedDNSDomains, ExtKeyUsage, +// IsCA, KeyUsage, MaxPathLen, MaxPathLenZero, NotAfter, NotBefore, +// PermittedDNSDomains, PermittedDNSDomainsCritical, SerialNumber, +// SignatureAlgorithm, Subject, SubjectKeyId, and UnknownExtKeyUsage. +// +// The certificate is signed by parent. If parent is equal to template then the +// certificate is self-signed. The parameter pub is the public key of the +// signee and priv is the private key of the signer. +// +// The returned slice is the certificate in DER encoding. +// +// All keys types that are implemented via crypto.Signer are supported (This +// includes *rsa.PublicKey and *ecdsa.PublicKey.) +// +// The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any, +// unless the resulting certificate is self-signed. Otherwise the value from +// template will be used. +func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv interface{}) (cert []byte, err error) { + key, ok := priv.(crypto.Signer) + if !ok { + return nil, errors.New("x509: certificate private key does not implement crypto.Signer") + } + + if template.SerialNumber == nil { + return nil, errors.New("x509: no SerialNumber given") + } + + hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm) + if err != nil { + return nil, err + } + + publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub) + if err != nil { + return nil, err + } + + asn1Issuer, err := subjectBytes(parent) + if err != nil { + return + } + + asn1Subject, err := subjectBytes(template) + if err != nil { + return + } + + authorityKeyId := template.AuthorityKeyId + if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 { + authorityKeyId = parent.SubjectKeyId + } + + extensions, err := buildExtensions(template, authorityKeyId) + if err != nil { + return + } + + encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes} + c := tbsCertificate{ + Version: 2, + SerialNumber: template.SerialNumber, + SignatureAlgorithm: signatureAlgorithm, + Issuer: asn1.RawValue{FullBytes: asn1Issuer}, + Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()}, + Subject: asn1.RawValue{FullBytes: asn1Subject}, + PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey}, + Extensions: extensions, + } + + tbsCertContents, err := asn1.Marshal(c) + if err != nil { + return + } + + c.Raw = tbsCertContents + + h := hashFunc.New() + h.Write(tbsCertContents) + digest := h.Sum(nil) + + var signerOpts crypto.SignerOpts + signerOpts = hashFunc + if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() { + signerOpts = &rsa.PSSOptions{ + SaltLength: rsa.PSSSaltLengthEqualsHash, + Hash: hashFunc, + } + } + + var signature []byte + signature, err = key.Sign(rand, digest, signerOpts) + if err != nil { + return + } + + return asn1.Marshal(certificate{ + nil, + c, + signatureAlgorithm, + asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, + }) +} + +// pemCRLPrefix is the magic string that indicates that we have a PEM encoded +// CRL. +var pemCRLPrefix = []byte("-----BEGIN X509 CRL") + +// pemType is the type of a PEM encoded CRL. +var pemType = "X509 CRL" + +// ParseCRL parses a CRL from the given bytes. It's often the case that PEM +// encoded CRLs will appear where they should be DER encoded, so this function +// will transparently handle PEM encoding as long as there isn't any leading +// garbage. +func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) { + if bytes.HasPrefix(crlBytes, pemCRLPrefix) { + block, _ := pem.Decode(crlBytes) + if block != nil && block.Type == pemType { + crlBytes = block.Bytes + } + } + return ParseDERCRL(crlBytes) +} + +// ParseDERCRL parses a DER encoded CRL from the given bytes. +func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) { + certList := new(pkix.CertificateList) + if rest, err := asn1.Unmarshal(derBytes, certList); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after CRL") + } + return certList, nil +} + +// CreateCRL returns a DER encoded CRL, signed by this Certificate, that +// contains the given list of revoked certificates. +func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) { + key, ok := priv.(crypto.Signer) + if !ok { + return nil, errors.New("x509: certificate private key does not implement crypto.Signer") + } + + hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), 0) + if err != nil { + return nil, err + } + + // Force revocation times to UTC per RFC 5280. + revokedCertsUTC := make([]pkix.RevokedCertificate, len(revokedCerts)) + for i, rc := range revokedCerts { + rc.RevocationTime = rc.RevocationTime.UTC() + revokedCertsUTC[i] = rc + } + + tbsCertList := pkix.TBSCertificateList{ + Version: 1, + Signature: signatureAlgorithm, + Issuer: c.Subject.ToRDNSequence(), + ThisUpdate: now.UTC(), + NextUpdate: expiry.UTC(), + RevokedCertificates: revokedCertsUTC, + } + + // Authority Key Id + if len(c.SubjectKeyId) > 0 { + var aki pkix.Extension + aki.Id = oidExtensionAuthorityKeyId + aki.Value, err = asn1.Marshal(authKeyId{Id: c.SubjectKeyId}) + if err != nil { + return + } + tbsCertList.Extensions = append(tbsCertList.Extensions, aki) + } + + tbsCertListContents, err := asn1.Marshal(tbsCertList) + if err != nil { + return + } + + h := hashFunc.New() + h.Write(tbsCertListContents) + digest := h.Sum(nil) + + var signature []byte + signature, err = key.Sign(rand, digest, hashFunc) + if err != nil { + return + } + + return asn1.Marshal(pkix.CertificateList{ + TBSCertList: tbsCertList, + SignatureAlgorithm: signatureAlgorithm, + SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, + }) +} + +// CertificateRequest represents a PKCS #10, certificate signature request. +type CertificateRequest struct { + Raw []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature). + RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content. + RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo. + RawSubject []byte // DER encoded Subject. + + Version int + Signature []byte + SignatureAlgorithm SignatureAlgorithm + + PublicKeyAlgorithm PublicKeyAlgorithm + PublicKey interface{} + + Subject pkix.Name + + // Attributes is the dried husk of a bug and shouldn't be used. + Attributes []pkix.AttributeTypeAndValueSET + + // Extensions contains raw X.509 extensions. When parsing CSRs, this + // can be used to extract extensions that are not parsed by this + // package. + Extensions []pkix.Extension + + // ExtraExtensions contains extensions to be copied, raw, into any + // marshaled CSR. Values override any extensions that would otherwise + // be produced based on the other fields but are overridden by any + // extensions specified in Attributes. + // + // The ExtraExtensions field is not populated when parsing CSRs, see + // Extensions. + ExtraExtensions []pkix.Extension + + // Subject Alternate Name values. + DNSNames []string + EmailAddresses []string + IPAddresses []net.IP +} + +// These structures reflect the ASN.1 structure of X.509 certificate +// signature requests (see RFC 2986): + +type tbsCertificateRequest struct { + Raw asn1.RawContent + Version int + Subject asn1.RawValue + PublicKey publicKeyInfo + RawAttributes []asn1.RawValue `asn1:"tag:0"` +} + +type certificateRequest struct { + Raw asn1.RawContent + TBSCSR tbsCertificateRequest + SignatureAlgorithm pkix.AlgorithmIdentifier + SignatureValue asn1.BitString +} + +// oidExtensionRequest is a PKCS#9 OBJECT IDENTIFIER that indicates requested +// extensions in a CSR. +var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14} + +// newRawAttributes converts AttributeTypeAndValueSETs from a template +// CertificateRequest's Attributes into tbsCertificateRequest RawAttributes. +func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) { + var rawAttributes []asn1.RawValue + b, err := asn1.Marshal(attributes) + if err != nil { + return nil, err + } + rest, err := asn1.Unmarshal(b, &rawAttributes) + if err != nil { + return nil, err + } + if len(rest) != 0 { + return nil, errors.New("x509: failed to unmarshal raw CSR Attributes") + } + return rawAttributes, nil +} + +// parseRawAttributes Unmarshals RawAttributes intos AttributeTypeAndValueSETs. +func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeTypeAndValueSET { + var attributes []pkix.AttributeTypeAndValueSET + for _, rawAttr := range rawAttributes { + var attr pkix.AttributeTypeAndValueSET + rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr) + // Ignore attributes that don't parse into pkix.AttributeTypeAndValueSET + // (i.e.: challengePassword or unstructuredName). + if err == nil && len(rest) == 0 { + attributes = append(attributes, attr) + } + } + return attributes +} + +// parseCSRExtensions parses the attributes from a CSR and extracts any +// requested extensions. +func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error) { + // pkcs10Attribute reflects the Attribute structure from section 4.1 of + // https://tools.ietf.org/html/rfc2986. + type pkcs10Attribute struct { + Id asn1.ObjectIdentifier + Values []asn1.RawValue `asn1:"set"` + } + + var ret []pkix.Extension + for _, rawAttr := range rawAttributes { + var attr pkcs10Attribute + if rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr); err != nil || len(rest) != 0 || len(attr.Values) == 0 { + // Ignore attributes that don't parse. + continue + } + + if !attr.Id.Equal(oidExtensionRequest) { + continue + } + + var extensions []pkix.Extension + if _, err := asn1.Unmarshal(attr.Values[0].FullBytes, &extensions); err != nil { + return nil, err + } + ret = append(ret, extensions...) + } + + return ret, nil +} + +// CreateCertificateRequest creates a new certificate request based on a +// template. The following members of template are used: Attributes, DNSNames, +// EmailAddresses, ExtraExtensions, IPAddresses, SignatureAlgorithm, and +// Subject. The private key is the private key of the signer. +// +// The returned slice is the certificate request in DER encoding. +// +// All keys types that are implemented via crypto.Signer are supported (This +// includes *rsa.PublicKey and *ecdsa.PublicKey.) +func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) { + key, ok := priv.(crypto.Signer) + if !ok { + return nil, errors.New("x509: certificate private key does not implement crypto.Signer") + } + + var hashFunc crypto.Hash + var sigAlgo pkix.AlgorithmIdentifier + hashFunc, sigAlgo, err = signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm) + if err != nil { + return nil, err + } + + var publicKeyBytes []byte + var publicKeyAlgorithm pkix.AlgorithmIdentifier + publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(key.Public()) + if err != nil { + return nil, err + } + + var extensions []pkix.Extension + + if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) && + !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) { + sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses) + if err != nil { + return nil, err + } + + extensions = append(extensions, pkix.Extension{ + Id: oidExtensionSubjectAltName, + Value: sanBytes, + }) + } + + extensions = append(extensions, template.ExtraExtensions...) + + var attributes []pkix.AttributeTypeAndValueSET + attributes = append(attributes, template.Attributes...) + + if len(extensions) > 0 { + // specifiedExtensions contains all the extensions that we + // found specified via template.Attributes. + specifiedExtensions := make(map[string]bool) + + for _, atvSet := range template.Attributes { + if !atvSet.Type.Equal(oidExtensionRequest) { + continue + } + + for _, atvs := range atvSet.Value { + for _, atv := range atvs { + specifiedExtensions[atv.Type.String()] = true + } + } + } + + atvs := make([]pkix.AttributeTypeAndValue, 0, len(extensions)) + for _, e := range extensions { + if specifiedExtensions[e.Id.String()] { + // Attributes already contained a value for + // this extension and it takes priority. + continue + } + + atvs = append(atvs, pkix.AttributeTypeAndValue{ + // There is no place for the critical flag in a CSR. + Type: e.Id, + Value: e.Value, + }) + } + + // Append the extensions to an existing attribute if possible. + appended := false + for _, atvSet := range attributes { + if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 { + continue + } + + atvSet.Value[0] = append(atvSet.Value[0], atvs...) + appended = true + break + } + + // Otherwise, add a new attribute for the extensions. + if !appended { + attributes = append(attributes, pkix.AttributeTypeAndValueSET{ + Type: oidExtensionRequest, + Value: [][]pkix.AttributeTypeAndValue{ + atvs, + }, + }) + } + } + + asn1Subject := template.RawSubject + if len(asn1Subject) == 0 { + asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence()) + if err != nil { + return + } + } + + rawAttributes, err := newRawAttributes(attributes) + if err != nil { + return + } + + tbsCSR := tbsCertificateRequest{ + Version: 0, // PKCS #10, RFC 2986 + Subject: asn1.RawValue{FullBytes: asn1Subject}, + PublicKey: publicKeyInfo{ + Algorithm: publicKeyAlgorithm, + PublicKey: asn1.BitString{ + Bytes: publicKeyBytes, + BitLength: len(publicKeyBytes) * 8, + }, + }, + RawAttributes: rawAttributes, + } + + tbsCSRContents, err := asn1.Marshal(tbsCSR) + if err != nil { + return + } + tbsCSR.Raw = tbsCSRContents + + h := hashFunc.New() + h.Write(tbsCSRContents) + digest := h.Sum(nil) + + var signature []byte + signature, err = key.Sign(rand, digest, hashFunc) + if err != nil { + return + } + + return asn1.Marshal(certificateRequest{ + TBSCSR: tbsCSR, + SignatureAlgorithm: sigAlgo, + SignatureValue: asn1.BitString{ + Bytes: signature, + BitLength: len(signature) * 8, + }, + }) +} + +// ParseCertificateRequest parses a single certificate request from the +// given ASN.1 DER data. +func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) { + var csr certificateRequest + + rest, err := asn1.Unmarshal(asn1Data, &csr) + if err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, asn1.SyntaxError{Msg: "trailing data"} + } + + return parseCertificateRequest(&csr) +} + +func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) { + out := &CertificateRequest{ + Raw: in.Raw, + RawTBSCertificateRequest: in.TBSCSR.Raw, + RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw, + RawSubject: in.TBSCSR.Subject.FullBytes, + + Signature: in.SignatureValue.RightAlign(), + SignatureAlgorithm: GetSignatureAlgorithmFromAI(in.SignatureAlgorithm), + + PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm), + + Version: in.TBSCSR.Version, + Attributes: parseRawAttributes(in.TBSCSR.RawAttributes), + } + + var err error + out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey) + if err != nil { + return nil, err + } + + var subject pkix.RDNSequence + if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil { + return nil, err + } else if len(rest) != 0 { + return nil, errors.New("x509: trailing data after X.509 Subject") + } + + out.Subject.FillFromRDNSequence(&subject) + + if out.Extensions, err = parseCSRExtensions(in.TBSCSR.RawAttributes); err != nil { + return nil, err + } + + for _, extension := range out.Extensions { + if extension.Id.Equal(oidExtensionSubjectAltName) { + out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(extension.Value) + if err != nil { + return nil, err + } + } + } + + return out, nil +} + +// CheckSignature reports whether the signature on c is valid. +func (c *CertificateRequest) CheckSignature() error { + return CheckSignatureFromKey(c.PublicKey, c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature) +} diff --git a/vendor/github.com/zmap/zlint/v2/.goreleaser.yml b/vendor/github.com/zmap/zlint/v2/.goreleaser.yml new file mode 100644 index 0000000000..2b84be004b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/.goreleaser.yml @@ -0,0 +1,30 @@ +project_name: zlint +before: + hooks: + - go mod tidy +builds: + - + main: ./cmd/zlint/main.go + binary: zlint + env: + - CGO_ENABLED=0 + goos: + - linux + - freebsd + - windows + - darwin + goarch: + - amd64 +archives: + - + wrap_in_directory: true + replacements: + darwin: Darwin + linux: Linux + windows: Windows + amd64: x86_64 +snapshot: + name_template: "{{ .Tag }}-next" +release: + draft: true + prerelease: auto diff --git a/vendor/github.com/zmap/zlint/v2/LICENSE b/vendor/github.com/zmap/zlint/v2/LICENSE new file mode 100644 index 0000000000..b209ae0fca --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Regents of the University of Michigan + + Licensed 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. diff --git a/vendor/github.com/zmap/zlint/v2/lint/base.go b/vendor/github.com/zmap/zlint/v2/lint/base.go new file mode 100644 index 0000000000..7224eaf0fb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lint/base.go @@ -0,0 +1,96 @@ +package lint + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/util" +) + +// LintInterface is implemented by each Lint. +type LintInterface interface { + // Initialize runs once per-lint. It is called during RegisterLint(). + Initialize() error + + // CheckApplies runs once per certificate. It returns true if the Lint should + // run on the given certificate. If CheckApplies returns false, the Lint + // result is automatically set to NA without calling CheckEffective() or + // Run(). + CheckApplies(c *x509.Certificate) bool + + // Execute() is the body of the lint. It is called for every certificate for + // which CheckApplies() returns true. + Execute(c *x509.Certificate) *LintResult +} + +// A Lint struct represents a single lint, e.g. +// "e_basic_constraints_not_critical". It contains an implementation of LintInterface. +type Lint struct { + + // Name is a lowercase underscore-separated string describing what a given + // Lint checks. If Name beings with "w", the lint MUST NOT return Error, only + // Warn. If Name beings with "e", the Lint MUST NOT return Warn, only Error. + Name string `json:"name,omitempty"` + + // A human-readable description of what the Lint checks. Usually copied + // directly from the CA/B Baseline Requirements or RFC 5280. + Description string `json:"description,omitempty"` + + // The source of the check, e.g. "BRs: 6.1.6" or "RFC 5280: 4.1.2.6". + Citation string `json:"citation,omitempty"` + + // Programmatic source of the check, BRs, RFC5280, or ZLint + Source LintSource `json:"source"` + + // Lints automatically returns NE for all certificates where CheckApplies() is + // true but with NotBefore < EffectiveDate. This check is bypassed if + // EffectiveDate is zero. + EffectiveDate time.Time `json:"-"` + + // The implementation of the lint logic. + Lint LintInterface `json:"-"` +} + +// CheckEffective returns true if c was issued on or after the EffectiveDate. If +// EffectiveDate is zero, CheckEffective always returns true. +func (l *Lint) CheckEffective(c *x509.Certificate) bool { + if l.EffectiveDate.IsZero() || !l.EffectiveDate.After(c.NotBefore) { + return true + } + return false +} + +// Execute runs the lint against a certificate. For lints that are +// sourced from the CA/B Forum Baseline Requirements, we first determine +// if they are within the purview of the BRs. See LintInterface for details +// about the other methods called. The ordering is as follows: +// +// CheckApplies() +// CheckEffective() +// Execute() +func (l *Lint) Execute(cert *x509.Certificate) *LintResult { + if l.Source == CABFBaselineRequirements && !util.IsServerAuthCert(cert) { + return &LintResult{Status: NA} + } + if !l.Lint.CheckApplies(cert) { + return &LintResult{Status: NA} + } else if !l.CheckEffective(cert) { + return &LintResult{Status: NE} + } + res := l.Lint.Execute(cert) + return res +} diff --git a/vendor/github.com/zmap/zlint/v2/lint/registration.go b/vendor/github.com/zmap/zlint/v2/lint/registration.go new file mode 100644 index 0000000000..a51f76d81c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lint/registration.go @@ -0,0 +1,351 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package lint + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "regexp" + "sort" + "strings" + "sync" +) + +// FilterOptions is a struct used by Registry.Filter to create a sub registry +// containing only lints that meet the filter options specified. +// +// Source based exclusion/inclusion is evaluated before Lint name based +// exclusion/inclusion. In both cases exclusion is processed before inclusion. +// +// Only one of NameFilter or IncludeNames/ExcludeNames can be provided at +// a time. +type FilterOptions struct { + // NameFilter is a regexp used to filter lints by their name. It is mutually + // exclusive with IncludeNames and ExcludeNames. + NameFilter *regexp.Regexp + // IncludeNames is a case sensitive list of lint names to include in the + // registry being filtered. + IncludeNames []string + // ExcludeNames is a case sensitive list of lint names to exclude from the + // registry being filtered. + ExcludeNames []string + // IncludeSource is a SourceList of LintSource's to be included in the + // registry being filtered. + IncludeSources SourceList + // ExcludeSources is a SourceList of LintSources's to be excluded in the + // registry being filtered. + ExcludeSources SourceList +} + +// Empty returns true if the FilterOptions is empty and does not specify any +// elements to filter by. +func (opts FilterOptions) Empty() bool { + return opts.NameFilter == nil && + len(opts.IncludeNames) == 0 && + len(opts.ExcludeNames) == 0 && + len(opts.IncludeSources) == 0 && + len(opts.ExcludeSources) == 0 +} + +// Registry is an interface describing a collection of registered lints. +// A Registry instance can be given to zlint.LintCertificateEx() to control what +// lints are run for a given certificate. +// +// Typically users will interact with the global Registry returned by +// GlobalRegistry(), or a filtered Registry created by applying FilterOptions to +// the GlobalRegistry()'s Filter function. +type Registry interface { + // Names returns a list of all of the lint names that have been registered + // in string sorted order. + Names() []string + // Sources returns a SourceList of registered LintSources. The list is not + // sorted but can be sorted by the caller with sort.Sort() if required. + Sources() SourceList + // ByName returns a pointer to the registered lint with the given name, or nil + // if there is no such lint registered in the registry. + ByName(name string) *Lint + // BySource returns a list of registered lints that have the same LintSource as + // provided (or nil if there were no such lints in the registry). + BySource(s LintSource) []*Lint + // Filter returns a new Registry containing only lints that match the + // FilterOptions criteria. + Filter(opts FilterOptions) (Registry, error) + // WriteJSON writes a description of each registered lint as + // a JSON object, one object per line, to the provided writer. + WriteJSON(w io.Writer) +} + +// registryImpl implements the Registry interface to provide a global collection +// of Lints that have been registered. +type registryImpl struct { + sync.RWMutex + // lintsByName is a map of all registered lints by name. + lintsByName map[string]*Lint + // lintNames is a sorted list of all of the registered lint names. It is + // equivalent to collecting the keys from lintsByName into a slice and sorting + // them lexicographically. + lintNames []string + // lintsBySource is a map of all registered lints by source category. Lints + // are added to the lintsBySource map by RegisterLint. + lintsBySource map[LintSource][]*Lint +} + +var ( + // errNilLint is returned from registry.Register if the provided lint was nil. + errNilLint = errors.New("can not register a nil lint") + // errNilLintPtr is returned from registry.Register if the provided lint had + // a nil Lint field. + errNilLintPtr = errors.New("can not register a lint with a nil Lint pointer") + // errEmptyName is returned from registry.Register if the provided lint had an + // empty Name field. + errEmptyName = errors.New("can not register a lint with an empty Name") +) + +// errDuplicateName is returned from registry.Register if the provided lint had +// a Name field matching a lint that was previously registered. +type errDuplicateName struct { + lintName string +} + +func (e errDuplicateName) Error() string { + return fmt.Sprintf( + "can not register lint with name %q - it has already been registered", + e.lintName) +} + +// errBadInit is returned from registry.Register if the provided lint's +// Initialize function returned an error. +type errBadInit struct { + lintName string + err error +} + +func (e errBadInit) Error() string { + return fmt.Sprintf( + "failed to register lint with name %q - failed to Initialize: %q", + e.lintName, e.err) +} + +// register adds the provided lint to the Registry. If initialize is true then +// the lint's Initialize() function will be called before registering the lint. +// +// An error is returned if the lint or lint's Lint pointer is nil, if the Lint +// has an empty Name or if the Name was previously registered. +func (r *registryImpl) register(l *Lint, initialize bool) error { + if l == nil { + return errNilLint + } + if l.Lint == nil { + return errNilLintPtr + } + if l.Name == "" { + return errEmptyName + } + if existing := r.ByName(l.Name); existing != nil { + return &errDuplicateName{l.Name} + } + if initialize { + if err := l.Lint.Initialize(); err != nil { + return &errBadInit{l.Name, err} + } + } + r.Lock() + defer r.Unlock() + r.lintNames = append(r.lintNames, l.Name) + r.lintsByName[l.Name] = l + r.lintsBySource[l.Source] = append(r.lintsBySource[l.Source], l) + sort.Strings(r.lintNames) + return nil +} + +// ByName returns the Lint previously registered under the given name with +// Register, or nil if no matching lint name has been registered. +func (r *registryImpl) ByName(name string) *Lint { + r.RLock() + defer r.RUnlock() + return r.lintsByName[name] +} + +// Names returns a list of all of the lint names that have been registered +// in string sorted order. +func (r *registryImpl) Names() []string { + r.RLock() + defer r.RUnlock() + return r.lintNames +} + +// BySource returns a list of registered lints that have the same LintSource as +// provided (or nil if there were no such lints). +func (r *registryImpl) BySource(s LintSource) []*Lint { + r.RLock() + defer r.RUnlock() + return r.lintsBySource[s] +} + +// Sources returns a SourceList of registered LintSources. The list is not +// sorted but can be sorted by the caller with sort.Sort() if required. +func (r *registryImpl) Sources() SourceList { + r.RLock() + defer r.RUnlock() + var results SourceList + for k := range r.lintsBySource { + results = append(results, k) + } + return results +} + +// lintNamesToMap converts a list of lit names into a bool hashmap useful for +// filtering. If any of the lint names are not known by the registry an error is +// returned. +func (r *registryImpl) lintNamesToMap(names []string) (map[string]bool, error) { + if len(names) == 0 { + return nil, nil + } + + namesMap := make(map[string]bool, len(names)) + for _, n := range names { + n = strings.TrimSpace(n) + if l := r.ByName(n); l == nil { + return nil, fmt.Errorf("unknown lint name %q", n) + } + namesMap[n] = true + } + return namesMap, nil +} + +func sourceListToMap(sources SourceList) map[LintSource]bool { + if len(sources) == 0 { + return nil + } + sourceMap := make(map[LintSource]bool, len(sources)) + for _, s := range sources { + sourceMap[s] = true + } + return sourceMap +} + +// Filter creates a new Registry with only the lints that meet the FilterOptions +// criteria included. +// +// FilterOptions are applied in the following order of precedence: +// ExcludeSources > IncludeSources > NameFilter > ExcludeNames > IncludeNames +func (r *registryImpl) Filter(opts FilterOptions) (Registry, error) { + // If there's no filtering to be done, return the existing Registry. + if opts.Empty() { + return r, nil + } + + filteredRegistry := NewRegistry() + + sourceExcludes := sourceListToMap(opts.ExcludeSources) + sourceIncludes := sourceListToMap(opts.IncludeSources) + + nameExcludes, err := r.lintNamesToMap(opts.ExcludeNames) + if err != nil { + return nil, err + } + nameIncludes, err := r.lintNamesToMap(opts.IncludeNames) + if err != nil { + return nil, err + } + + if opts.NameFilter != nil && (len(nameExcludes) != 0 || len(nameIncludes) != 0) { + return nil, errors.New( + "FilterOptions.NameFilter cannot be used at the same time as " + + "FilterOptions.ExcludeNames or FilterOptions.IncludeNames") + } + + for _, name := range r.Names() { + l := r.ByName(name) + + if sourceExcludes != nil && sourceExcludes[l.Source] { + continue + } + if sourceIncludes != nil && !sourceIncludes[l.Source] { + continue + } + if opts.NameFilter != nil && !opts.NameFilter.MatchString(name) { + continue + } + if nameExcludes != nil && nameExcludes[name] { + continue + } + if nameIncludes != nil && !nameIncludes[name] { + continue + } + + // when adding lints to a filtered registry we do not want Initialize() to + // be called a second time, so provide false as the initialize argument. + if err := filteredRegistry.register(l, false); err != nil { + return nil, err + } + } + + return filteredRegistry, nil +} + +// WriteJSON writes a description of each registered lint as +// a JSON object, one object per line, to the provided writer. +func (r *registryImpl) WriteJSON(w io.Writer) { + enc := json.NewEncoder(w) + enc.SetEscapeHTML(false) + for _, name := range r.Names() { + _ = enc.Encode(r.ByName(name)) + } +} + +// NewRegistry constructs a Registry implementation that can be used to register +// lints. +func NewRegistry() *registryImpl { + return ®istryImpl{ + lintsByName: make(map[string]*Lint), + lintsBySource: make(map[LintSource][]*Lint), + } +} + +// globalRegistry is the Registry used by all loaded lints that call +// RegisterLint(). +var globalRegistry *registryImpl = NewRegistry() + +// RegisterLint must be called once for each lint to be executed. Normally, +// RegisterLint is called from the Go init() function of a lint implementation. +// +// RegsterLint will call l.Lint's Initialize() function as part of the +// registration process. +// +// IMPORTANT: RegisterLint will panic if given a nil lint, or a lint with a nil +// Lint pointer, or if the lint's Initialize function errors, or if the lint +// name matches a previously registered lint's name. These conditions all +// indicate a bug that should be addressed by a developer. +func RegisterLint(l *Lint) { + // RegisterLint always sets initialize to true. It's assumed this is called by + // the package init() functions and therefore must be doing the first + // initialization of a lint. + if err := globalRegistry.register(l, true); err != nil { + panic(fmt.Sprintf("RegisterLint error: %v\n", err.Error())) + } +} + +// GlobalRegistry is the Registry used by RegisterLint and contains all of the +// lints that are loaded. +// +// If you want to run only a subset of the globally registered lints use +// GloablRegistry().Filter with FilterOptions to create a filtered +// Registry. +func GlobalRegistry() Registry { + return globalRegistry +} diff --git a/vendor/github.com/zmap/zlint/v2/lint/result.go b/vendor/github.com/zmap/zlint/v2/lint/result.go new file mode 100644 index 0000000000..96c43ab00c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lint/result.go @@ -0,0 +1,106 @@ +package lint + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/json" + "fmt" + "strings" +) + +// LintStatus is an enum returned by lints inside of a LintResult. +type LintStatus int + +// Known LintStatus values +const ( + // Unused / unset LintStatus + Reserved LintStatus = 0 + + // Not Applicable + NA LintStatus = 1 + + // Not Effective + NE LintStatus = 2 + + Pass LintStatus = 3 + Notice LintStatus = 4 + Warn LintStatus = 5 + Error LintStatus = 6 + Fatal LintStatus = 7 +) + +var ( + // StatusLabelToLintStatus is used to work backwards from + // a LintStatus.String() to the LintStatus. This is used by + // LintStatus.Unmarshal. + StatusLabelToLintStatus = map[string]LintStatus{ + Reserved.String(): Reserved, + NA.String(): NA, + NE.String(): NE, + Pass.String(): Pass, + Notice.String(): Notice, + Warn.String(): Warn, + Error.String(): Error, + Fatal.String(): Fatal, + } +) + +// LintResult contains a LintStatus, and an optional human-readable description. +// The output of a lint is a LintResult. +type LintResult struct { + Status LintStatus `json:"result"` + Details string `json:"details,omitempty"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (e LintStatus) MarshalJSON() ([]byte, error) { + s := e.String() + return json.Marshal(s) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (e *LintStatus) UnmarshalJSON(data []byte) error { + key := strings.ReplaceAll(string(data), `"`, "") + if status, ok := StatusLabelToLintStatus[key]; ok { + *e = status + } else { + return fmt.Errorf("bad LintStatus JSON value: %s", string(data)) + } + return nil +} + +// String returns the canonical representation of a LintStatus as a string. +func (e LintStatus) String() string { + switch e { + case Reserved: + return "reserved" + case NA: + return "NA" + case NE: + return "NE" + case Pass: + return "pass" + case Notice: + return "info" + case Warn: + return "warn" + case Error: + return "error" + case Fatal: + return "fatal" + default: + return "" + } +} diff --git a/vendor/github.com/zmap/zlint/v2/lint/source.go b/vendor/github.com/zmap/zlint/v2/lint/source.go new file mode 100644 index 0000000000..28834da9ec --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lint/source.go @@ -0,0 +1,132 @@ +package lint + +import ( + "encoding/json" + "fmt" + "strings" +) + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// LintSource is a type representing a known lint source that lints cite +// requirements from. +type LintSource string + +const ( + UnknownLintSource LintSource = "Unknown" + RFC5280 LintSource = "RFC5280" + RFC5480 LintSource = "RFC5480" + RFC5891 LintSource = "RFC5891" + CABFBaselineRequirements LintSource = "CABF_BR" + CABFEVGuidelines LintSource = "CABF_EV" + MozillaRootStorePolicy LintSource = "Mozilla" + AppleCTPolicy LintSource = "Apple" + ZLint LintSource = "ZLint" + AWSLabs LintSource = "AWSLabs" + EtsiEsi LintSource = "ETSI_ESI" +) + +// UnmarshalJSON implements the json.Unmarshaler interface. It ensures that the +// unmarshaled value is a known LintSource. +func (s *LintSource) UnmarshalJSON(data []byte) error { + var throwAway string + if err := json.Unmarshal(data, &throwAway); err != nil { + return err + } + + switch LintSource(throwAway) { + case RFC5280, RFC5480, RFC5891, CABFBaselineRequirements, CABFEVGuidelines, MozillaRootStorePolicy, AppleCTPolicy, ZLint, AWSLabs, EtsiEsi: + *s = LintSource(throwAway) + return nil + default: + *s = UnknownLintSource + return fmt.Errorf("unknown LintSource value %q", throwAway) + } +} + +// FromString sets the LintSource value based on the source string provided +// (case sensitive). If the src string does not match any of the known +// LintSource's then s is set to the UnknownLintSource. +func (s *LintSource) FromString(src string) { + // Start with the unknown lint source + *s = UnknownLintSource + // Trim space and try to match a known value + src = strings.TrimSpace(src) + switch LintSource(src) { + case RFC5280: + *s = RFC5280 + case RFC5480: + *s = RFC5480 + case RFC5891: + *s = RFC5891 + case CABFBaselineRequirements: + *s = CABFBaselineRequirements + case CABFEVGuidelines: + *s = CABFEVGuidelines + case MozillaRootStorePolicy: + *s = MozillaRootStorePolicy + case AppleCTPolicy: + *s = AppleCTPolicy + case ZLint: + *s = ZLint + case AWSLabs: + *s = AWSLabs + case EtsiEsi: + *s = EtsiEsi + } +} + +// SourceList is a slice of LintSources that can be sorted. +type SourceList []LintSource + +// Len returns the length of the list. +func (l SourceList) Len() int { + return len(l) +} + +// Swap swaps the LintSource at index i and j in the list. +func (l SourceList) Swap(i, j int) { + l[i], l[j] = l[j], l[i] +} + +// Less compares the LintSources at index i and j lexicographically. +func (l SourceList) Less(i, j int) bool { + return l[i] < l[j] +} + +// FromString populates a SourceList (replacing any existing content) with the +// comma separated list of sources provided in raw. If any of the comma +// separated values are not known LintSource's an error is returned. +func (l *SourceList) FromString(raw string) error { + // Start with an empty list + *l = SourceList{} + + values := strings.Split(raw, ",") + for _, val := range values { + val = strings.TrimSpace(val) + if val == "" { + continue + } + // Populate the LintSource with the trimmed value. + var src LintSource + src.FromString(val) + // If the LintSource is UnknownLintSource then return an error. + if src == UnknownLintSource { + return fmt.Errorf("unknown lint source in list: %q", val) + } + *l = append(*l, src) + } + return nil +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/apple/lint_ct_sct_policy_count_unsatisfied.go b/vendor/github.com/zmap/zlint/v2/lints/apple/lint_ct_sct_policy_count_unsatisfied.go new file mode 100644 index 0000000000..df9fbfd8b6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/apple/lint_ct_sct_policy_count_unsatisfied.go @@ -0,0 +1,157 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package apple + +import ( + "fmt" + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/ct" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type sctPolicyCount struct{} + +// Initialize for a sctPolicyCount instance does nothing. +func (l *sctPolicyCount) Initialize() error { + return nil +} + +// CheckApplies returns true for any subscriber certificates that are not +// precertificates (e.g. that do not have the CT poison extension defined in RFC +// 6962. +func (l *sctPolicyCount) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && !util.IsExtInCert(c, util.CtPoisonOID) +} + +// Execute checks if the provided certificate has embedded SCTs from +// a sufficient number of unique CT logs to meet Apple's CT log policy[0], +// effective Oct 15th, 2018. +// +// The number of required SCTs from different logs is calculated based on the +// Certificate's lifetime. If the number of required SCTs are not embedded in +// the certificate a Notice level lint.LintResult is returned. +// +// | Certificate lifetime | # of SCTs from separate logs | +// ------------------------------------------------------- +// | Less than 15 months | 2 | +// | 15 to 27 months | 3 | +// | 27 to 39 months | 4 | +// | More than 39 months | 5 | +// ------------------------------------------------------- +// +// Important note 1: We can't know whether additional SCTs were presented +// alongside the certificate via OCSP stapling. This linter assumes only +// embedded SCTs are used and ignores the portion of the Apple policy related to +// SCTs delivered via OCSP. This is one limitation that restricts the linter's +// findings to Notice level. See more background discussion in Issue 226[1]. +// +// Important note 2: The linter doesn't maintain a list of Apple's trusted +// logs. The SCTs embedded in the certificate may not be from log's Apple +// actually trusts. Similarly the embedded SCT signatures are not validated +// in any way. +// +// [0]: https://support.apple.com/en-us/HT205280 +// [1]: https://github.com/zmap/zlint/issues/226 +func (l *sctPolicyCount) Execute(c *x509.Certificate) *lint.LintResult { + // Determine the required number of SCTs from separate logs + expected := appleCTPolicyExpectedSCTs(c) + + // If there are no SCTs then the job is easy. We can return a Notice + // lint.LintResult immediately. + if len(c.SignedCertificateTimestampList) == 0 && expected > 0 { + return &lint.LintResult{ + Status: lint.Notice, + Details: fmt.Sprintf( + "Certificate had 0 embedded SCTs. Browser policy may require %d for this certificate.", + expected), + } + } + + // Build a map from LogID to SCT so that we can count embedded SCTs by unique + // log. + sctsByLogID := make(map[ct.SHA256Hash]*ct.SignedCertificateTimestamp) + for _, sct := range c.SignedCertificateTimestampList { + sctsByLogID[sct.LogID] = sct + } + + // If the number of embedded SCTs from separate logs meets expected return + // a lint.Pass result. + if len(sctsByLogID) >= expected { + return &lint.LintResult{Status: lint.Pass} + } + + // Otherwise return a Notice result - there weren't enough SCTs embedded in + // the certificate. More must be provided by OCSP stapling if the certificate + // is to meet Apple's CT policy. + return &lint.LintResult{ + Status: lint.Notice, + Details: fmt.Sprintf( + "Certificate had %d embedded SCTs from distinct log IDs. "+ + "Browser policy may require %d for this certificate.", + len(sctsByLogID), expected), + } +} + +// appleCTPolicyExpectedSCTs returns a count of the number of SCTs expected to +// be embedded in the given certificate based on its lifetime. +// +// For this function the relevant portion of Apple's policy is the table +// "Number of embedded SCTs based on certificate lifetime" (Also reproduced in +// the `Execute` godoc comment). +func appleCTPolicyExpectedSCTs(cert *x509.Certificate) int { + // Lifetime is relative to the certificate's NotBefore date. + start := cert.NotBefore + + // Thresholds is an ordered array of lifetime periods and their expected # of + // SCTs. A lifetime period is defined by the cutoff date relative to the + // start of the certificate's lifetime. + thresholds := []struct { + CutoffDate time.Time + Expected int + }{ + // Start date ... 15 months + {CutoffDate: start.AddDate(0, 15, 0), Expected: 2}, + // Start date ... 27 months + {CutoffDate: start.AddDate(0, 27, 0), Expected: 3}, + // Start date ... 39 months + {CutoffDate: start.AddDate(0, 39, 0), Expected: 4}, + } + + // If the certificate's lifetime falls into any of the cutoff date ranges then + // we expect that range's expected # of SCTs for this certificate. This loop + // assumes the `thresholds` list is sorted in ascending order. + for _, threshold := range thresholds { + if cert.NotAfter.Before(threshold.CutoffDate) { + return threshold.Expected + } + } + + // The certificate had a validity > 39 months. + return 5 +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ct_sct_policy_count_unsatisfied", + Description: "Check if certificate has enough embedded SCTs to meet Apple CT Policy", + Citation: "https://support.apple.com/en-us/HT205280", + Source: lint.AppleCTPolicy, + EffectiveDate: util.AppleCTPolicyDate, + Lint: &sctPolicyCount{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go b/vendor/github.com/zmap/zlint/v2/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go new file mode 100644 index 0000000000..166321e36c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go @@ -0,0 +1,79 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package apple + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type serverCertValidityTooLong struct{} + +func (l *serverCertValidityTooLong) Initialize() error { + return nil +} + +func (l *serverCertValidityTooLong) CheckApplies(c *x509.Certificate) bool { + return util.IsServerAuthCert(c) && !c.IsCA +} + +func (l *serverCertValidityTooLong) Execute(c *x509.Certificate) *lint.LintResult { + // "398 days is measured with a day being equal to 86,400 seconds. Any time + // greater than this indicates an additional day of validity." + dayLength := 86400 * time.Second + // "TLS server certificates issued on or after September 1, 2020 00:00 GMT/UTC + // must not have a validity period greater than 398 days." + maxValidity := 398 * dayLength + // "We recommend that certificates be issued with a maximum validity of 397 days." + warnValidity := 397 * dayLength + + // RFC 5280, section 4.1.2.5: "The validity period for a certificate is the period + // of time from notBefore through notAfter, inclusive." + certValidity := c.NotAfter.Add(1 * time.Second).Sub(c.NotBefore) + + if certValidity > maxValidity { + return &lint.LintResult{Status: lint.Error} + } else if certValidity > warnValidity { + return &lint.LintResult{ + // RFC 2119 has SHOULD and RECOMMENDED as equal. Since Apple recommends + // 397 days we treat this as a lint.Warn result as a violation of + // a SHOULD. + Status: lint.Warn, + Details: "Apple recommends that certificates be issued with a maximum " + + "validity of 397 days.", + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_tls_server_cert_valid_time_longer_than_398_days", + Description: "TLS server certificates issued on or after September 1, 2020 " + + "00:00 GMT/UTC must not have a validity period greater than 398 days", + Citation: "https://support.apple.com/en-us/HT211025", + // TODO(@cpu): The Source should be `lint.ApplePolicy` or something similar. + // The "CT" bit is too specific. Unfortunately since the constant is + // exported by the `util` package we can't change it without bumping the + // major version. See https://github.com/zmap/zlint/issues/418 + Source: lint.AppleCTPolicy, + EffectiveDate: util.AppleReducedLifetimeDate, + Lint: &serverCertValidityTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_common_name_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_common_name_missing.go new file mode 100644 index 0000000000..b60352c8e4 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_common_name_missing.go @@ -0,0 +1,50 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caCommonNameMissing struct{} + +func (l *caCommonNameMissing) Initialize() error { + return nil +} + +func (l *caCommonNameMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsCACert(c) +} + +func (l *caCommonNameMissing) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName == "" { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_common_name_missing", + Description: "CA Certificates common name MUST be included.", + Citation: "BRs: 7.1.4.3.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV148Date, + Lint: &caCommonNameMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_invalid.go new file mode 100644 index 0000000000..d3d9bc81e8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_invalid.go @@ -0,0 +1,63 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +/************************************************ +BRs: 7.1.2.1e +The Certificate Subject MUST contain the following: +‐ countryName (OID 2.5.4.6). +This field MUST contain the two‐letter ISO 3166‐1 country code for the country +in which the CA’s place of business is located. +************************************************/ + +type caCountryNameInvalid struct{} + +func (l *caCountryNameInvalid) Initialize() error { + return nil +} + +func (l *caCountryNameInvalid) CheckApplies(c *x509.Certificate) bool { + return c.IsCA +} + +func (l *caCountryNameInvalid) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.Country != nil { + for _, j := range c.Subject.Country { + if !util.IsISOCountryCode(j) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.NA} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_country_name_invalid", + Description: "Root and Subordinate CA certificates MUST have a two-letter country code specified in ISO 3166-1", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caCountryNameInvalid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_missing.go new file mode 100644 index 0000000000..533de82a9f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_country_name_missing.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +/************************************************ +BRs: 7.1.2.1e +The Certificate Subject MUST contain the following: +‐ countryName (OID 2.5.4.6). +This field MUST contain the two‐letter ISO 3166‐1 country code for the country +in which the CA’s place of business is located. +************************************************/ + +type caCountryNameMissing struct{} + +func (l *caCountryNameMissing) Initialize() error { + return nil +} + +func (l *caCountryNameMissing) CheckApplies(c *x509.Certificate) bool { + return c.IsCA +} + +func (l *caCountryNameMissing) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.Country != nil && c.Subject.Country[0] != "" { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_country_name_missing", + Description: "Root and Subordinate CA certificates MUST have a countryName present in subject information", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caCountryNameMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_crl_sign_not_set.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_crl_sign_not_set.go new file mode 100644 index 0000000000..1627f938d5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_crl_sign_not_set.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +/************************************************ +BRs: 7.1.2.1b +This extension MUST be present and MUST be marked critical. Bit positions for +keyCertSign and cRLSign MUST be set. If the Root CA Private Key is used for +signing OCSP responses, then the digitalSignature bit MUST be set. +************************************************/ + +type caCRLSignNotSet struct{} + +func (l *caCRLSignNotSet) Initialize() error { + return nil +} + +func (l *caCRLSignNotSet) CheckApplies(c *x509.Certificate) bool { + return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *caCRLSignNotSet) Execute(c *x509.Certificate) *lint.LintResult { + if c.KeyUsage&x509.KeyUsageCRLSign != 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_crl_sign_not_set", + Description: "Root and Subordinate CA certificate keyUsage extension's crlSign bit MUST be set", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caCRLSignNotSet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_digital_signature_not_set.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_digital_signature_not_set.go new file mode 100644 index 0000000000..62b43ed0af --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_digital_signature_not_set.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1b: Root CA Certificate keyUsage +This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set. +If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set. + +BRs: 7.1.2.2e: Subordinate CA Certificate keyUsage +This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set. +If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caDigSignNotSet struct{} + +func (l *caDigSignNotSet) Initialize() error { + return nil +} + +func (l *caDigSignNotSet) CheckApplies(c *x509.Certificate) bool { + return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *caDigSignNotSet) Execute(c *x509.Certificate) *lint.LintResult { + if c.KeyUsage&x509.KeyUsageDigitalSignature != 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Notice} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_ca_digital_signature_not_set", + Description: "Root and Subordinate CA Certificates that wish to use their private key for signing OCSP responses will not be able to without their digital signature set", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caDigSignNotSet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_is_ca.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_is_ca.go new file mode 100644 index 0000000000..3bc6b0929e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_is_ca.go @@ -0,0 +1,63 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caIsCA struct{} + +type basicConstraints struct { + IsCA bool `asn1:"optional"` + MaxPathLen int `asn1:"optional,default:-1"` +} + +func (l *caIsCA) Initialize() error { + return nil +} + +func (l *caIsCA) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) && c.KeyUsage&x509.KeyUsageCertSign != 0 && util.IsExtInCert(c, util.BasicConstOID) +} + +func (l *caIsCA) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.BasicConstOID) + var constraints basicConstraints + _, err := asn1.Unmarshal(e.Value, &constraints) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if constraints.IsCA { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_is_ca", + Description: "Root and Sub CA Certificate: The CA field MUST be set to true.", + Citation: "BRs: 7.1.2.1, BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caIsCA{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_cert_sign_not_set.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_cert_sign_not_set.go new file mode 100644 index 0000000000..1fa55a77e7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_cert_sign_not_set.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1b +This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set. +If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caKeyCertSignNotSet struct{} + +func (l *caKeyCertSignNotSet) Initialize() error { + return nil +} + +func (l *caKeyCertSignNotSet) CheckApplies(c *x509.Certificate) bool { + return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *caKeyCertSignNotSet) Execute(c *x509.Certificate) *lint.LintResult { + if c.KeyUsage&x509.KeyUsageCertSign != 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_key_cert_sign_not_set", + Description: "Root CA Certificate: Bit positions for keyCertSign and cRLSign MUST be set.", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caKeyCertSignNotSet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_missing.go new file mode 100644 index 0000000000..a06ee9b51a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_missing.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.3 +Conforming CAs MUST include this extension in certificates that + contain public keys that are used to validate digital signatures on + other public key certificates or CRLs. When present, conforming CAs + SHOULD mark this extension as critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caKeyUsageMissing struct{} + +func (l *caKeyUsageMissing) Initialize() error { + return nil +} + +func (l *caKeyUsageMissing) CheckApplies(c *x509.Certificate) bool { + return c.IsCA +} + +func (l *caKeyUsageMissing) Execute(c *x509.Certificate) *lint.LintResult { + if c.KeyUsage != x509.KeyUsage(0) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_key_usage_missing", + Description: "Root and Subordinate CA certificate keyUsage extension MUST be present", + Citation: "BRs: 7.1.2.1, RFC 5280: 4.2.1.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC3280Date, + Lint: &caKeyUsageMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_not_critical.go new file mode 100644 index 0000000000..51cddfe993 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_key_usage_not_critical.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1b +This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set. +If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caKeyUsageNotCrit struct{} + +func (l *caKeyUsageNotCrit) Initialize() error { + return nil +} + +func (l *caKeyUsageNotCrit) CheckApplies(c *x509.Certificate) bool { + return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *caKeyUsageNotCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.KeyUsageOID); e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_key_usage_not_critical", + Description: "Root and Subordinate CA certificate keyUsage extension MUST be marked as critical", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caKeyUsageNotCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_organization_name_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_organization_name_missing.go new file mode 100644 index 0000000000..7fe8fd9518 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ca_organization_name_missing.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1e +The Certificate Subject MUST contain the following: organizationName (OID 2.5.4.10): This field MUST be present and the contents MUST contain either the Subject CA’s name or DBA as verified under Section 3.2.2.2. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caOrganizationNameMissing struct{} + +func (l *caOrganizationNameMissing) Initialize() error { + return nil +} + +func (l *caOrganizationNameMissing) CheckApplies(c *x509.Certificate) bool { + return c.IsCA +} + +func (l *caOrganizationNameMissing) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.Organization != nil && c.Subject.Organization[0] != "" { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_organization_name_missing", + Description: "Root and Subordinate CA certificates MUST have a organizationName present in subject information", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caOrganizationNameMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_locality.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_locality.go new file mode 100644 index 0000000000..01070614df --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_locality.go @@ -0,0 +1,52 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// If the Certificate asserts the policy identifier of 2.23.140.1.2.1, then it MUST NOT include +// organizationName, streetAddress, localityName, stateOrProvinceName, or postalCode in the Subject field. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certPolicyConflictsWithLocality struct{} + +func (l *certPolicyConflictsWithLocality) Initialize() error { + return nil +} + +func (l *certPolicyConflictsWithLocality) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && !util.IsCACert(cert) +} + +func (l *certPolicyConflictsWithLocality) Execute(cert *x509.Certificate) *lint.LintResult { + if util.TypeInName(&cert.Subject, util.LocalityNameOID) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_dv_conflicts_with_locality", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, locality name MUST NOT be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &certPolicyConflictsWithLocality{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_org.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_org.go new file mode 100644 index 0000000000..96a0cde11b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_org.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// If the Certificate asserts the policy identifier of 2.23.140.1.2.1, then it MUST NOT include +// organizationName, streetAddress, localityName, stateOrProvinceName, or postalCode in the Subject field. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certPolicyConflictsWithOrg struct{} + +func (l *certPolicyConflictsWithOrg) Initialize() error { + return nil +} + +func (l *certPolicyConflictsWithOrg) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && !util.IsCACert(cert) +} + +func (l *certPolicyConflictsWithOrg) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.OrganizationNameOID) { + out.Status = lint.Error + } else { + out.Status = lint.Pass + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_dv_conflicts_with_org", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, organization name MUST NOT be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &certPolicyConflictsWithOrg{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_postal.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_postal.go new file mode 100644 index 0000000000..5bef5ca198 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_postal.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// If the Certificate asserts the policy identifier of 2.23.140.1.2.1, then it MUST NOT include +// organizationName, streetAddress, localityName, stateOrProvinceName, or postalCode in the Subject field. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certPolicyConflictsWithPostal struct{} + +func (l *certPolicyConflictsWithPostal) Initialize() error { + return nil +} + +func (l *certPolicyConflictsWithPostal) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && !util.IsCACert(cert) +} + +func (l *certPolicyConflictsWithPostal) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.PostalCodeOID) { + out.Status = lint.Error + } else { + out.Status = lint.Pass + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_dv_conflicts_with_postal", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, postalCode MUST NOT be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &certPolicyConflictsWithPostal{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_province.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_province.go new file mode 100644 index 0000000000..b32d3a82f9 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_province.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// If the Certificate asserts the policy identifier of 2.23.140.1.2.1, then it MUST NOT include +// organizationName, streetAddress, localityName, stateOrProvinceName, or postalCode in the Subject field. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certPolicyConflictsWithProvince struct{} + +func (l *certPolicyConflictsWithProvince) Initialize() error { + return nil +} + +func (l *certPolicyConflictsWithProvince) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && !util.IsCACert(cert) +} + +func (l *certPolicyConflictsWithProvince) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.StateOrProvinceNameOID) { + out.Status = lint.Error + } else { + out.Status = lint.Pass + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_dv_conflicts_with_province", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, stateOrProvinceName MUST NOT be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &certPolicyConflictsWithProvince{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_street.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_street.go new file mode 100644 index 0000000000..15dcc0f5e6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_dv_conflicts_with_street.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// If the Certificate asserts the policy identifier of 2.23.140.1.2.1, then it MUST NOT include +// organizationName, streetAddress, localityName, stateOrProvinceName, or postalCode in the Subject field. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certPolicyConflictsWithStreet struct{} + +func (l *certPolicyConflictsWithStreet) Initialize() error { + return nil +} + +func (l *certPolicyConflictsWithStreet) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && !util.IsCACert(cert) +} + +func (l *certPolicyConflictsWithStreet) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.StreetAddressOID) { + out.Status = lint.Error + } else { + out.Status = lint.Pass + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_dv_conflicts_with_street", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, streetAddress MUST NOT be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &certPolicyConflictsWithStreet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_iv_requires_personal_name.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_iv_requires_personal_name.go new file mode 100644 index 0000000000..826864d515 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_iv_requires_personal_name.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*If the Certificate asserts the policy identifier of 2.23.140.1.2.3, then it MUST also include (i) either organizationName or givenName and surname, (ii) localityName (to the extent such field is required under Section 7.1.4.2.2), (iii) stateOrProvinceName (to the extent required under Section 7.1.4.2.2), and (iv) countryName in the Subject field.*/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyRequiresPersonalName struct{} + +func (l *CertPolicyRequiresPersonalName) Initialize() error { + return nil +} + +func (l *CertPolicyRequiresPersonalName) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRIndividualValidatedOID) && !util.IsCACert(cert) +} + +func (l *CertPolicyRequiresPersonalName) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.OrganizationNameOID) || (util.TypeInName(&cert.Subject, util.GivenNameOID) && util.TypeInName(&cert.Subject, util.SurnameOID)) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_iv_requires_personal_name", + Description: "If certificate policy 2.23.140.1.2.3 is included, either organizationName or givenName and surname MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV131Date, + Lint: &CertPolicyRequiresPersonalName{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_ov_requires_org.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_ov_requires_org.go new file mode 100644 index 0000000000..a573a1751f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cab_ov_requires_org.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*If the Certificate asserts the policy identifier of 2.23.140.1.2.2, then it MUST also include organizationName, localityName (to the extent such field is required under Section 7.1.4.2.2), stateOrProvinceName (to the extent such field is required under Section 7.1.4.2.2), and countryName in the Subject field.*/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyRequiresOrg struct{} + +func (l *CertPolicyRequiresOrg) Initialize() error { + return nil +} + +func (l *CertPolicyRequiresOrg) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BROrganizationValidatedOID) && !util.IsCACert(cert) +} + +func (l *CertPolicyRequiresOrg) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.OrganizationNameOID) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cab_ov_requires_org", + Description: "If certificate policy 2.23.140.1.2.2 is included, organizationName MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &CertPolicyRequiresOrg{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_country.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_country.go new file mode 100644 index 0000000000..07d742b293 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_country.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*If the Certificate asserts the policy identifier of 2.23.140.1.2.3, then it MUST also include (i) either organizationName or givenName and surname, (ii) localityName (to the extent such field is required under Section 7.1.4.2.2), (iii) stateOrProvinceName (to the extent required under Section 7.1.4.2.2), and (iv) countryName in the Subject field.*/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyIVRequiresCountry struct{} + +func (l *CertPolicyIVRequiresCountry) Initialize() error { + return nil +} + +func (l *CertPolicyIVRequiresCountry) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRIndividualValidatedOID) +} + +func (l *CertPolicyIVRequiresCountry) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.CountryNameOID) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_policy_iv_requires_country", + Description: "If certificate policy 2.23.140.1.2.3 is included, countryName MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV131Date, + Lint: &CertPolicyIVRequiresCountry{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_province_or_locality.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_province_or_locality.go new file mode 100644 index 0000000000..b669a30c0d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_iv_requires_province_or_locality.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// 7.1.6.1: If the Certificate asserts the policy identifier of 2.23.140.1.2.3, then it MUST also include (i) either organizationName or givenName and surname, (ii) localityName (to the extent such field is required under Section 7.1.4.2.2), (iii) stateOrProvinceName (to the extent required under Section 7.1.4.2.2), and (iv) countryName in the Subject field. +// 7.1.4.2.2 applies only to subscriber certificates. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyIVRequiresProvinceOrLocal struct{} + +func (l *CertPolicyIVRequiresProvinceOrLocal) Initialize() error { + return nil +} + +func (l *CertPolicyIVRequiresProvinceOrLocal) CheckApplies(cert *x509.Certificate) bool { + return util.IsSubscriberCert(cert) && util.SliceContainsOID(cert.PolicyIdentifiers, util.BRIndividualValidatedOID) +} + +func (l *CertPolicyIVRequiresProvinceOrLocal) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.LocalityNameOID) || util.TypeInName(&cert.Subject, util.StateOrProvinceNameOID) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_policy_iv_requires_province_or_locality", + Description: "If certificate policy 2.23.140.1.2.3 is included, localityName or stateOrProvinceName MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV131Date, + Lint: &CertPolicyIVRequiresProvinceOrLocal{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_country.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_country.go new file mode 100644 index 0000000000..e9296f5ffe --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_country.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*If the Certificate asserts the policy identifier of 2.23.140.1.2.2, then it MUST also include organizationName, localityName (to the extent such field is required under Section 7.1.4.2.2), stateOrProvinceName (to the extent such field is required under Section 7.1.4.2.2), and countryName in the Subject field.*/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyOVRequiresCountry struct{} + +func (l *CertPolicyOVRequiresCountry) Initialize() error { + return nil +} + +func (l *CertPolicyOVRequiresCountry) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BROrganizationValidatedOID) +} + +func (l *CertPolicyOVRequiresCountry) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.CountryNameOID) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_policy_ov_requires_country", + Description: "If certificate policy 2.23.140.1.2.2 is included, countryName MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &CertPolicyOVRequiresCountry{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_province_or_locality.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_province_or_locality.go new file mode 100644 index 0000000000..f61aeb652e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_cert_policy_ov_requires_province_or_locality.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// 7.1.6.1: If the Certificate asserts the policy identifier of 2.23.140.1.2.2, then it MUST also include organizationName, localityName (to the extent such field is required under Section 7.1.4.2.2), stateOrProvinceName (to the extent such field is required under Section 7.1.4.2.2), and countryName in the Subject field.*/ +// 7.1.4.2.2 applies only to subscriber certificates. + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertPolicyOVRequiresProvinceOrLocal struct{} + +func (l *CertPolicyOVRequiresProvinceOrLocal) Initialize() error { + return nil +} + +func (l *CertPolicyOVRequiresProvinceOrLocal) CheckApplies(cert *x509.Certificate) bool { + return util.IsSubscriberCert(cert) && util.SliceContainsOID(cert.PolicyIdentifiers, util.BROrganizationValidatedOID) +} + +func (l *CertPolicyOVRequiresProvinceOrLocal) Execute(cert *x509.Certificate) *lint.LintResult { + var out lint.LintResult + if util.TypeInName(&cert.Subject, util.LocalityNameOID) || util.TypeInName(&cert.Subject, util.StateOrProvinceNameOID) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_policy_ov_requires_province_or_locality", + Description: "If certificate policy 2.23.140.1.2.2 is included, localityName or stateOrProvinceName MUST be included in subject", + Citation: "BRs: 7.1.6.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &CertPolicyOVRequiresProvinceOrLocal{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dh_params_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dh_params_missing.go new file mode 100644 index 0000000000..16072eb446 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dh_params_missing.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/dsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dsaParamsMissing struct{} + +func (l *dsaParamsMissing) Initialize() error { + return nil +} + +func (l *dsaParamsMissing) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.DSA +} + +func (l *dsaParamsMissing) Execute(c *x509.Certificate) *lint.LintResult { + dsaKey, ok := c.PublicKey.(*dsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.Fatal} + } + params := dsaKey.Parameters + if params.P.BitLen() == 0 || params.Q.BitLen() == 0 || params.G.BitLen() == 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dsa_params_missing", + Description: "DSA: Certificates MUST include all domain parameters", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &dsaParamsMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_bad_character_in_label.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_bad_character_in_label.go new file mode 100644 index 0000000000..053255d8f6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_bad_character_in_label.go @@ -0,0 +1,64 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "regexp" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameProperCharacters struct { + CompiledExpression *regexp.Regexp +} + +func (l *DNSNameProperCharacters) Initialize() error { + const dnsNameRegexp = `^(\*\.)?(\?\.)*([A-Za-z0-9*_-]+\.)*[A-Za-z0-9*_-]*$` + var err error + l.CompiledExpression, err = regexp.Compile(dnsNameRegexp) + + return err +} + +func (l *DNSNameProperCharacters) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameProperCharacters) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + if !l.CompiledExpression.MatchString(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Error} + } + } + for _, dns := range c.DNSNames { + if !l.CompiledExpression.MatchString(dns) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_bad_character_in_label", + Description: "Characters in labels of DNSNames MUST be alphanumeric, - , _ or *", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameProperCharacters{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_check_left_label_wildcard.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_check_left_label_wildcard.go new file mode 100644 index 0000000000..41c014a38c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_check_left_label_wildcard.go @@ -0,0 +1,67 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameLeftLabelWildcardCheck struct{} + +func (l *DNSNameLeftLabelWildcardCheck) Initialize() error { + return nil +} + +func (l *DNSNameLeftLabelWildcardCheck) CheckApplies(c *x509.Certificate) bool { + return true +} + +func wildcardInLeftLabelIncorrect(domain string) bool { + labels := strings.Split(domain, ".") + if len(labels) >= 1 { + leftLabel := labels[0] + if strings.Contains(leftLabel, "*") && leftLabel != "*" { + return true + } + } + return false +} + +func (l *DNSNameLeftLabelWildcardCheck) Execute(c *x509.Certificate) *lint.LintResult { + if wildcardInLeftLabelIncorrect(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Error} + } + for _, dns := range c.DNSNames { + if wildcardInLeftLabelIncorrect(dns) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_left_label_wildcard_correct", + Description: "Wildcards in the left label of DNSName should only be *", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameLeftLabelWildcardCheck{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_bare_iana_suffix.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_bare_iana_suffix.go new file mode 100644 index 0000000000..1d320e6bec --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_bare_iana_suffix.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dnsNameContainsBareIANASuffix struct{} + +func (l *dnsNameContainsBareIANASuffix) Initialize() error { + return nil +} + +func (l *dnsNameContainsBareIANASuffix) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *dnsNameContainsBareIANASuffix) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + if util.IsInTLDMap(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Error} + } + } + for _, dns := range c.DNSNames { + if util.IsInTLDMap(dns) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_contains_bare_iana_suffix", + Description: "DNSNames should not contain a bare IANA suffix.", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &dnsNameContainsBareIANASuffix{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_empty_label.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_empty_label.go new file mode 100644 index 0000000000..7a4db420b0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_contains_empty_label.go @@ -0,0 +1,68 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameEmptyLabel struct{} + +func (l *DNSNameEmptyLabel) Initialize() error { + return nil +} + +func (l *DNSNameEmptyLabel) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func domainHasEmptyLabel(domain string) bool { + labels := strings.Split(domain, ".") + for _, elem := range labels { + if elem == "" { + return true + } + } + return false +} + +func (l *DNSNameEmptyLabel) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + if domainHasEmptyLabel(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Error} + } + } + for _, dns := range c.DNSNames { + if domainHasEmptyLabel(dns) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_empty_label", + Description: "DNSNames should not have an empty label.", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameEmptyLabel{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_hyphen_in_sld.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_hyphen_in_sld.go new file mode 100644 index 0000000000..aecb9a0ada --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_hyphen_in_sld.go @@ -0,0 +1,67 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameHyphenInSLD struct{} + +func (l *DNSNameHyphenInSLD) Initialize() error { + return nil +} + +func (l *DNSNameHyphenInSLD) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameHyphenInSLD) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + domainInfo := c.GetParsedSubjectCommonName(false) + if domainInfo.ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.HasPrefix(domainInfo.ParsedDomain.SLD, "-") || strings.HasSuffix(domainInfo.ParsedDomain.SLD, "-") { + return &lint.LintResult{Status: lint.Error} + } + } + parsedSANDNSNames := c.GetParsedDNSNames(false) + for i := range c.GetParsedDNSNames(false) { + if parsedSANDNSNames[i].ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.HasPrefix(parsedSANDNSNames[i].ParsedDomain.SLD, "-") || + strings.HasSuffix(parsedSANDNSNames[i].ParsedDomain.SLD, "-") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_hyphen_in_sld", + Description: "DNSName should not have a hyphen beginning or ending the SLD", + Citation: "BRs 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC5280Date, + Lint: &DNSNameHyphenInSLD{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_label_too_long.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_label_too_long.go new file mode 100644 index 0000000000..78fafbf689 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_label_too_long.go @@ -0,0 +1,70 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameLabelLengthTooLong struct{} + +func (l *DNSNameLabelLengthTooLong) Initialize() error { + return nil +} + +func (l *DNSNameLabelLengthTooLong) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func labelLengthTooLong(domain string) bool { + labels := strings.Split(domain, ".") + for _, label := range labels { + if len(label) > 63 { + return true + } + } + return false +} + +func (l *DNSNameLabelLengthTooLong) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + labelTooLong := labelLengthTooLong(c.Subject.CommonName) + if labelTooLong { + return &lint.LintResult{Status: lint.Error} + } + } + for _, dns := range c.DNSNames { + labelTooLong := labelLengthTooLong(dns) + if labelTooLong { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_label_too_long", + Description: "DNSName labels MUST be less than or equal to 63 characters", + Citation: "RFC 1035", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameLabelLengthTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_right_label_valid_tld.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_right_label_valid_tld.go new file mode 100644 index 0000000000..b2e211364b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_right_label_valid_tld.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameValidTLD struct{} + +func (l *DNSNameValidTLD) Initialize() error { + return nil +} + +func (l *DNSNameValidTLD) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameValidTLD) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + if !util.HasValidTLD(c.Subject.CommonName, c.NotBefore) { + return &lint.LintResult{Status: lint.Error} + } + } + for _, dns := range c.DNSNames { + if !util.HasValidTLD(dns, c.NotBefore) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_not_valid_tld", + Description: "DNSNames must have a valid TLD.", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameValidTLD{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_sld.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_sld.go new file mode 100644 index 0000000000..92337b6a3e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_sld.go @@ -0,0 +1,67 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameUnderscoreInSLD struct{} + +func (l *DNSNameUnderscoreInSLD) Initialize() error { + return nil +} + +func (l *DNSNameUnderscoreInSLD) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameUnderscoreInSLD) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + domainInfo := c.GetParsedSubjectCommonName(false) + if domainInfo.ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.Contains(domainInfo.ParsedDomain.SLD, "_") { + return &lint.LintResult{Status: lint.Error} + } + } + + parsedSANDNSNames := c.GetParsedDNSNames(false) + for i := range c.GetParsedDNSNames(false) { + if parsedSANDNSNames[i].ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.Contains(parsedSANDNSNames[i].ParsedDomain.SLD, "_") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_underscore_in_sld", + Description: "DNSName should not have underscore in SLD", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC5280Date, + Lint: &DNSNameUnderscoreInSLD{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_trd.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_trd.go new file mode 100644 index 0000000000..0b7ecd602b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_underscore_in_trd.go @@ -0,0 +1,68 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameUnderscoreInTRD struct{} + +func (l *DNSNameUnderscoreInTRD) Initialize() error { + return nil +} + +func (l *DNSNameUnderscoreInTRD) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameUnderscoreInTRD) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + domainInfo := c.GetParsedSubjectCommonName(false) + if domainInfo.ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.Contains(domainInfo.ParsedDomain.TRD, "_") { + return &lint.LintResult{Status: lint.Warn} + } + } + + parsedSANDNSNames := c.GetParsedDNSNames(false) + for i := range c.GetParsedDNSNames(false) { + if parsedSANDNSNames[i].ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + if strings.Contains(parsedSANDNSNames[i].ParsedDomain.TRD, "_") { + return &lint.LintResult{Status: lint.Warn} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_dnsname_underscore_in_trd", + Description: "DNSName should not have an underscore in labels left of the ETLD+1", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC5280Date, + Lint: &DNSNameUnderscoreInTRD{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_left_of_public_suffix.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_left_of_public_suffix.go new file mode 100644 index 0000000000..f3a3151cd0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_left_of_public_suffix.go @@ -0,0 +1,67 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameWildcardLeftofPublicSuffix struct{} + +func (l *DNSNameWildcardLeftofPublicSuffix) Initialize() error { + return nil +} + +func (l *DNSNameWildcardLeftofPublicSuffix) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.DNSNamesExist(c) +} + +func (l *DNSNameWildcardLeftofPublicSuffix) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" && !util.CommonNameIsIP(c) { + domainInfo := c.GetParsedSubjectCommonName(false) + if domainInfo.ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + + if domainInfo.ParsedDomain.SLD == "*" { + return &lint.LintResult{Status: lint.Warn} + } + } + + parsedSANDNSNames := c.GetParsedDNSNames(false) + for i := range c.GetParsedDNSNames(false) { + if parsedSANDNSNames[i].ParseError != nil { + return &lint.LintResult{Status: lint.NA} + } + + if parsedSANDNSNames[i].ParsedDomain.SLD == "*" { + return &lint.LintResult{Status: lint.Warn} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_dnsname_wildcard_left_of_public_suffix", + Description: "the CA MUST establish and follow a documented procedure[^pubsuffix] that determines if the wildcard character occurs in the first label position to the left of a “registry‐controlled” label or “public suffix”", + Citation: "BRs: 3.2.2.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameWildcardLeftofPublicSuffix{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_only_in_left_label.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_only_in_left_label.go new file mode 100644 index 0000000000..8a72b0ef02 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dnsname_wildcard_only_in_left_label.go @@ -0,0 +1,69 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameWildcardOnlyInLeftlabel struct{} + +func (l *DNSNameWildcardOnlyInLeftlabel) Initialize() error { + return nil +} + +func (l *DNSNameWildcardOnlyInLeftlabel) CheckApplies(c *x509.Certificate) bool { + return true +} + +func wildcardNotInLeftLabel(domain string) bool { + labels := strings.Split(domain, ".") + if len(labels) > 1 { + labels = labels[1:] + for _, label := range labels { + if strings.Contains(label, "*") { + return true + } + } + } + return false +} + +func (l *DNSNameWildcardOnlyInLeftlabel) Execute(c *x509.Certificate) *lint.LintResult { + if wildcardNotInLeftLabel(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Error} + } + for _, dns := range c.DNSNames { + if wildcardNotInLeftLabel(dns) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dnsname_wildcard_only_in_left_label", + Description: "DNSName should not have wildcards except in the left-most label", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &DNSNameWildcardOnlyInLeftlabel{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go new file mode 100644 index 0000000000..20690250d0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go @@ -0,0 +1,66 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/dsa" + "math/big" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dsaSubgroup struct{} + +func (l *dsaSubgroup) Initialize() error { + return nil +} + +func (l *dsaSubgroup) CheckApplies(c *x509.Certificate) bool { + if c.PublicKeyAlgorithm != x509.DSA { + return false + } + if _, ok := c.PublicKey.(*dsa.PublicKey); !ok { + return false + } + return true +} + +func (l *dsaSubgroup) Execute(c *x509.Certificate) *lint.LintResult { + dsaKey, ok := c.PublicKey.(*dsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.NA} + } + output := big.Int{} + + // Enforce that Y^Q == 1 mod P, e.g. that Order(Y) == Q mod P. + output.Exp(dsaKey.Y, dsaKey.Q, dsaKey.P) + if output.Cmp(big.NewInt(1)) == 0 { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dsa_correct_order_in_subgroup", + Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &dsaSubgroup{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_improper_modulus_or_divisor_size.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_improper_modulus_or_divisor_size.go new file mode 100644 index 0000000000..e964bf28d1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_improper_modulus_or_divisor_size.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/dsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dsaImproperSize struct{} + +func (l *dsaImproperSize) Initialize() error { + return nil +} + +func (l *dsaImproperSize) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.DSA +} + +func (l *dsaImproperSize) Execute(c *x509.Certificate) *lint.LintResult { + dsaKey, ok := c.PublicKey.(*dsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.NA} + } + L := dsaKey.Parameters.P.BitLen() + N := dsaKey.Parameters.Q.BitLen() + if (L == 2048 && N == 224) || (L == 2048 && N == 256) || (L == 3072 && N == 256) { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dsa_improper_modulus_or_divisor_size", + Description: "Certificates MUST meet the following requirements for DSA algorithm type and key size: L=2048 and N=224,256 or L=3072 and N=256", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &dsaImproperSize{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go new file mode 100644 index 0000000000..8284b45eab --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/dsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dsaTooShort struct{} + +func (l *dsaTooShort) Initialize() error { + return nil +} + +func (l *dsaTooShort) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.DSA +} + +func (l *dsaTooShort) Execute(c *x509.Certificate) *lint.LintResult { + dsaKey, ok := c.PublicKey.(*dsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.NA} + } + dsaParams := dsaKey.Parameters + L := dsaParams.P.BitLen() + N := dsaParams.Q.BitLen() + if L >= 2048 && N >= 244 { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dsa_shorter_than_2048_bits", + Description: "DSA modulus size must be at least 2048 bits", + Citation: "BRs: 6.1.5", + // Refer to BRs: 6.1.5, taking the statement "Before 31 Dec 2010" literally + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &dsaTooShort{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_unique_correct_representation.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_unique_correct_representation.go new file mode 100644 index 0000000000..7ea60092ee --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_dsa_unique_correct_representation.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/dsa" + "math/big" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type dsaUniqueCorrectRepresentation struct{} + +func (l *dsaUniqueCorrectRepresentation) Initialize() error { + return nil +} + +func (l *dsaUniqueCorrectRepresentation) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.DSA +} + +func (l *dsaUniqueCorrectRepresentation) Execute(c *x509.Certificate) *lint.LintResult { + dsaKey, ok := c.PublicKey.(*dsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.NA} + } + // Verify that 2 ≤ y ≤ p-2. + two := big.NewInt(2) + pMinusTwo := big.NewInt(0) + pMinusTwo.Sub(dsaKey.P, two) + if two.Cmp(dsaKey.Y) > 0 || dsaKey.Y.Cmp(pMinusTwo) > 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_dsa_unique_correct_representation", + Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &dsaUniqueCorrectRepresentation{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ec_improper_curves.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ec_improper_curves.go new file mode 100644 index 0000000000..985db91c9b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ec_improper_curves.go @@ -0,0 +1,71 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 6.1.5 +Certificates MUST meet the following requirements for algorithm type and key size. +ECC Curve: NIST P-256, P-384, or P-521 +************************************************/ + +import ( + "crypto/ecdsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ecImproperCurves struct{} + +func (l *ecImproperCurves) Initialize() error { + return nil +} + +func (l *ecImproperCurves) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.ECDSA +} + +func (l *ecImproperCurves) Execute(c *x509.Certificate) *lint.LintResult { + /* Declare theKey to be a ECDSA Public Key */ + var theKey *ecdsa.PublicKey + /* Need to do different things based on what c.PublicKey is */ + switch keyType := c.PublicKey.(type) { + case *x509.AugmentedECDSA: + theKey = keyType.Pub + case *ecdsa.PublicKey: + theKey = keyType + } + /* Now can actually check the params */ + theParams := theKey.Curve.Params() + switch theParams.Name { + case "P-256", "P-384", "P-521": + return &lint.LintResult{Status: lint.Pass} + default: + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ec_improper_curves", + Description: "Only one of NIST P‐256, P‐384, or P‐521 can be used", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + // Refer to BRs: 6.1.5, taking the statement "Before 31 Dec 2010" literally + EffectiveDate: util.ZeroDate, + Lint: &ecImproperCurves{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip.go new file mode 100644 index 0000000000..c13b95db1c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_nc_intersects_reserved_ip.go @@ -0,0 +1,63 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.5 +(b) For each iPAddress range in permittedSubtrees, the CA MUST confirm that the +Applicant has been assigned the iPAddress range or has been authorized by the +assigner to act on the assignee's behalf. + +BRs: 7.1.4.2.1 +CAs SHALL NOT issue certificates with a subjectAlternativeName extension or +Subject commonName field containing a Reserved IP Address or Internal Name. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type NCReservedIPNet struct{} + +func (l *NCReservedIPNet) Initialize() error { + return nil +} + +func (l *NCReservedIPNet) CheckApplies(c *x509.Certificate) bool { + return c.NotAfter.After(util.NoReservedIP) && util.IsExtInCert(c, util.NameConstOID) +} + +func (l *NCReservedIPNet) Execute(c *x509.Certificate) *lint.LintResult { + for _, constraint := range c.PermittedIPAddresses { + if util.IntersectsIANAReserved(constraint.Data) { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_nc_intersects_reserved_ip", + Description: "iPAddress name constraint intersects an IANA reserved network", + Citation: "BRs: 7.1.5 / 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &NCReservedIPNet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_contains_reserved_ip.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_contains_reserved_ip.go new file mode 100644 index 0000000000..46b8f148b5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_contains_reserved_ip.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.4.2.1 +Also as of the Effective Date, the CA SHALL NOT +issue a certificate with an Expiry Date later than +1 November 2015 with a subjectAlternativeName extension +or Subject commonName field containing a Reserved IP +Address or Internal Name. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANReservedIP struct{} + +func (l *SANReservedIP) Initialize() error { + return nil +} + +func (l *SANReservedIP) CheckApplies(c *x509.Certificate) bool { + return c.NotAfter.After(util.NoReservedIP) +} + +func (l *SANReservedIP) Execute(c *x509.Certificate) *lint.LintResult { + for _, ip := range c.IPAddresses { + if util.IsIANAReserved(ip) { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_contains_reserved_ip", + Description: "Effective October 1, 2016, CAs must revoke all unexpired certificates that contains a reserved IP or internal name.", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANReservedIP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_critical_with_subject_dn.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_critical_with_subject_dn.go new file mode 100644 index 0000000000..5f0522fabb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_critical_with_subject_dn.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +Further, if the only subject identity included in the certificate is an + alternative name form (e.g., an electronic mail address), then the subject + distinguished name MUST be empty (an empty sequence), and the subjectAltName + extension MUST be present. If the subject field contains an empty sequence, + then the issuing CA MUST include a subjectAltName extension that is marked as + critical. When including the subjectAltName extension in a certificate that + has a non-empty subject distinguished name, conforming CAs SHOULD mark the + subjectAltName extension as non-critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtSANCriticalWithSubjectDN struct{} + +func (l *ExtSANCriticalWithSubjectDN) Initialize() error { + return nil +} + +func (l *ExtSANCriticalWithSubjectDN) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.SubjectAlternateNameOID) +} + +func (l *ExtSANCriticalWithSubjectDN) Execute(cert *x509.Certificate) *lint.LintResult { + san := util.GetExtFromCert(cert, util.SubjectAlternateNameOID) + if san.Critical && util.NotAllNameFieldsAreEmpty(&cert.Subject) { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_san_critical_with_subject_dn", + Description: "If the subject contains a distinguished name, subjectAlternateName SHOULD be non-critical", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC5280Date, + Lint: &ExtSANCriticalWithSubjectDN{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_directory_name_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_directory_name_present.go new file mode 100644 index 0000000000..8662a3af93 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_directory_name_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDirName struct{} + +func (l *SANDirName) Initialize() error { + return nil +} + +func (l *SANDirName) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDirName) Execute(c *x509.Certificate) *lint.LintResult { + if c.DirectoryNames != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_directory_name_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANDirName{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_edi_party_name_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_edi_party_name_present.go new file mode 100644 index 0000000000..1cce293ed0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_edi_party_name_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANEDI struct{} + +func (l *SANEDI) Initialize() error { + return nil +} + +func (l *SANEDI) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANEDI) Execute(c *x509.Certificate) *lint.LintResult { + if c.EDIPartyNames != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_edi_party_name_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANEDI{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_missing.go new file mode 100644 index 0000000000..af8fbb8497 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_missing.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.4.2.1 +Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANMissing struct{} + +func (l *SANMissing) Initialize() error { + return nil +} + +func (l *SANMissing) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *SANMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.SubjectAlternateNameOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_missing", + Description: "Subscriber certificates MUST contain the Subject Alternate Name extension", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_other_name_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_other_name_present.go new file mode 100644 index 0000000000..255cc9886e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_other_name_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANOtherName struct{} + +func (l *SANOtherName) Initialize() error { + return nil +} + +func (l *SANOtherName) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANOtherName) Execute(c *x509.Certificate) *lint.LintResult { + if c.OtherNames != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_other_name_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types.", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANOtherName{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_registered_id_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_registered_id_present.go new file mode 100644 index 0000000000..fd2467cd7a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_registered_id_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANRegId struct{} + +func (l *SANRegId) Initialize() error { + return nil +} + +func (l *SANRegId) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANRegId) Execute(c *x509.Certificate) *lint.LintResult { + if c.RegisteredIDs != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_registered_id_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types.", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANRegId{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_rfc822_name_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_rfc822_name_present.go new file mode 100644 index 0000000000..c2f76ef691 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_rfc822_name_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANRfc822 struct{} + +func (l *SANRfc822) Initialize() error { + return nil +} + +func (l *SANRfc822) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANRfc822) Execute(c *x509.Certificate) *lint.LintResult { + if c.EmailAddresses != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_rfc822_name_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types.", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANRfc822{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_uniform_resource_identifier_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_uniform_resource_identifier_present.go new file mode 100644 index 0000000000..50e6a54bc6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_san_uniform_resource_identifier_present.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.4.2.1. Subject Alternative Name Extension +Certificate Field: extensions:subjectAltName +Required/Optional: Required +Contents: This extension MUST contain at least one entry. Each entry MUST be either a dNSName containing +the Fully‐Qualified Domain Name or an iPAddress containing the IP address of a server. The CA MUST +confirm that the Applicant controls the Fully‐Qualified Domain Name or IP address or has been granted the +right to use it by the Domain Name Registrant or IP address assignee, as appropriate. +Wildcard FQDNs are permitted. +*************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANURI struct{} + +func (l *SANURI) Initialize() error { + return nil +} + +func (l *SANURI) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANURI) Execute(c *x509.Certificate) *lint.LintResult { + if c.URIs != nil { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_uniform_resource_identifier_present", + Description: "The Subject Alternate Name extension MUST contain only 'dnsName' and 'ipaddress' name types", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &SANURI{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_tor_service_descriptor_hash_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_tor_service_descriptor_hash_invalid.go new file mode 100644 index 0000000000..ae11908cca --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_ext_tor_service_descriptor_hash_invalid.go @@ -0,0 +1,220 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_br + +import ( + "fmt" + "net/url" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type torServiceDescHashInvalid struct{} + +func (l *torServiceDescHashInvalid) Initialize() error { + // There is nothing to initialize for a torServiceDescHashInvalid linter. + return nil +} + +// CheckApplies returns true if the TorServiceDescriptor extension is present +// or if the certificate is an EV subscriber certificate with one or more +// subject names ending in `.onion`. +func (l *torServiceDescHashInvalid) CheckApplies(c *x509.Certificate) bool { + ext := util.GetExtFromCert(c, util.BRTorServiceDescriptor) + return ext != nil || (util.IsSubscriberCert(c) && + util.CertificateSubjInTLD(c, util.OnionTLD) && + util.IsEV(c.PolicyIdentifiers)) +} + +// failResult is a small utility function for creating a failed lint result. +func failResult(format string, args ...interface{}) *lint.LintResult { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf(format, args...), + } +} + +// torServiceDescExtName is a common string prefix used in many lint result +// detail messages to identify the extension at fault. +var torServiceDescExtName = fmt.Sprintf( + "TorServiceDescriptor extension (oid %s)", + util.BRTorServiceDescriptor.String()) + +// lintOnionURL verifies that an Onion URI value from a TorServiceDescriptorHash +// is: +// +// 1) a valid parseable url. +// 2) a URL with a non-empty hostname +// 3) a URL with an https:// protocol scheme +// +// If all of the above hold then nil is returned. If any of the above conditions +// are not met an error lint result pointer is returned. +func lintOnionURL(onion string) *lint.LintResult { + if onionURL, err := url.Parse(onion); err != nil { + return failResult( + "%s contained "+ + "TorServiceDescriptorHash object with invalid Onion URI", + torServiceDescExtName) + } else if onionURL.Host == "" { + return failResult( + "%s contained "+ + "TorServiceDescriptorHash object with Onion URI missing a hostname", + torServiceDescExtName) + } else if onionURL.Scheme != "https" { + return failResult( + "%s contained "+ + "TorServiceDescriptorHash object with Onion URI using a non-HTTPS "+ + "protocol scheme", + torServiceDescExtName) + } + return nil +} + +// Execute will lint the provided certificate. An lint.Error lint.LintResult will be +// returned if: +// +// 1) There is no TorServiceDescriptor extension present and it's required +// 2) There were no TorServiceDescriptors parsed by zcrypto +// 3) There are TorServiceDescriptorHash entries with an invalid Onion URL. +// 4) There are TorServiceDescriptorHash entries with an unknown hash +// algorithm or incorrect hash bit length. +// 5) There is a TorServiceDescriptorHash entry that doesn't correspond to +// an onion subject in the cert. +// 6) There is an onion subject in the cert that doesn't correspond to +// a TorServiceDescriptorHash, if required. +func (l *torServiceDescHashInvalid) Execute(c *x509.Certificate) *lint.LintResult { + // If the certificate is EV, the BRTorServiceDescriptor extension is required. + // We know that `CheckApplies` will only apply if the certificate has the + // extension or that it's required, so this will only fail when it's + // required. + if ext := util.GetExtFromCert(c, util.BRTorServiceDescriptor); ext == nil { + return failResult( + "certificate contained a %s domain but is missing a TorServiceDescriptor "+ + "extension (oid %s)", + util.OnionTLD, util.BRTorServiceDescriptor.String()) + } + + // The certificate should have at least one TorServiceDescriptorHash in the + // TorServiceDescriptor extension. + descriptors := c.TorServiceDescriptors + if len(descriptors) == 0 { + return failResult( + "certificate contained a %s domain but TorServiceDescriptor "+ + "extension (oid %s) had no TorServiceDescriptorHash objects", + util.OnionTLD, util.BRTorServiceDescriptor.String()) + } + + // Build a map of all the eTLD+1 onion subjects in the cert to compare against + // the service descriptors. + onionETLDPlusOneMap := make(map[string]string) + for _, subj := range append(c.DNSNames, c.Subject.CommonName) { + if !strings.HasSuffix(subj, util.OnionTLD) { + continue + } + labels := strings.Split(subj, ".") + if len(labels) < 2 { + return failResult("certificate contained a %s domain with too few "+ + "labels: %q", + util.OnionTLD, subj) + } + eTLDPlusOne := strings.Join(labels[len(labels)-2:], ".") + onionETLDPlusOneMap[eTLDPlusOne] = subj + } + + expectedHashBits := map[string]int{ + "SHA256": 256, + "SHA384": 384, + "SHA512": 512, + } + + // Build a map of onion hostname -> TorServiceDescriptorHash using the parsed + // TorServiceDescriptors from zcrypto. + descriptorMap := make(map[string]*x509.TorServiceDescriptorHash) + for _, descriptor := range descriptors { + // each descriptor's Onion URL must be valid + if errResult := lintOnionURL(descriptor.Onion); errResult != nil { + return errResult + } + // each descriptor should have a known hash algorithm and the correct + // corresponding size of hash. + if expectedBits, found := expectedHashBits[descriptor.AlgorithmName]; !found { + return failResult( + "%s contained a TorServiceDescriptorHash for Onion URI %q with an "+ + "unknown hash algorithm", + torServiceDescExtName, descriptor.Onion) + } else if expectedBits != descriptor.HashBits { + return failResult( + "%s contained a TorServiceDescriptorHash with hash algorithm %q but "+ + "only %d bits of hash not %d", + torServiceDescExtName, descriptor.AlgorithmName, + descriptor.HashBits, expectedBits) + } + // NOTE(@cpu): Throwing out the err result here because lintOnionURL already + // ensured the URL is valid. + url, _ := url.Parse(descriptor.Onion) + hostname := url.Hostname() + // there should only be one TorServiceDescriptorHash for each Onion hostname. + if _, exists := descriptorMap[hostname]; exists { + return failResult( + "%s contained more than one TorServiceDescriptorHash for base "+ + "Onion URI %q", + torServiceDescExtName, descriptor.Onion) + } + // there shouldn't be a TorServiceDescriptorHash for a Onion hostname that + // isn't an eTLD+1 in the certificate's subjects. + if _, found := onionETLDPlusOneMap[hostname]; !found { + return failResult( + "%s contained a TorServiceDescriptorHash with a hostname (%q) not "+ + "present as a subject in the certificate", + torServiceDescExtName, hostname) + } + descriptorMap[hostname] = descriptor + } + + // For EV certificates, every `.onion` name is required to have a + // TorServiceDescriptorHash, so check if any of the onion subjects in the + // certificate don't have a TorServiceDescriptorHash for the eTLD+1 in the + // descriptorMap. + // See also https://github.com/cabforum/documents/issues/190 + if util.IsEV(c.PolicyIdentifiers) { + for eTLDPlusOne, subjDomain := range onionETLDPlusOneMap { + if _, found := descriptorMap[eTLDPlusOne]; !found { + return failResult( + "%s subject domain name %q does not have a corresponding "+ + "TorServiceDescriptorHash for its eTLD+1", + util.OnionTLD, subjDomain) + } + } + } + + // Everything checks out! + return &lint.LintResult{ + Status: lint.Pass, + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_tor_service_descriptor_hash_invalid", + Description: "certificates with v2 .onion names need valid TorServiceDescriptors in extension", + Citation: "BRs: Ballot 201, Ballot SC27", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV201Date, + Lint: &torServiceDescHashInvalid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_extra_subject_common_names.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_extra_subject_common_names.go new file mode 100644 index 0000000000..a827e21729 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_extra_subject_common_names.go @@ -0,0 +1,52 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_br + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type extraSubjectCommonNames struct{} + +func (l *extraSubjectCommonNames) Initialize() error { + return nil +} + +func (l *extraSubjectCommonNames) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *extraSubjectCommonNames) Execute(c *x509.Certificate) *lint.LintResult { + // Multiple subject commonName fields are not expressly prohibited by section + // 7.1.4.2.2 but do seem to run afoul of the intent. For that reason we return + // only a lint.Warn level finding here. + if len(c.Subject.CommonNames) > 1 { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_extra_subject_common_names", + Description: "if present the subject commonName field MUST contain a single IP address or Fully-Qualified Domain Name", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &extraSubjectCommonNames{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_invalid_certificate_version.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_invalid_certificate_version.go new file mode 100644 index 0000000000..c190e56787 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_invalid_certificate_version.go @@ -0,0 +1,53 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +Certificates MUST be of type X.509 v3. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type InvalidCertificateVersion struct{} + +func (l *InvalidCertificateVersion) Initialize() error { + return nil +} + +func (l *InvalidCertificateVersion) CheckApplies(cert *x509.Certificate) bool { + return true +} + +func (l *InvalidCertificateVersion) Execute(cert *x509.Certificate) *lint.LintResult { + if cert.Version != 3 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_invalid_certificate_version", + Description: "Certificates MUST be of type X.590 v3", + Citation: "BRs: 7.1.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV130Date, + Lint: &InvalidCertificateVersion{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_root_ca_rsa_mod_less_than_2048_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_root_ca_rsa_mod_less_than_2048_bits.go new file mode 100644 index 0000000000..222c973505 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_root_ca_rsa_mod_less_than_2048_bits.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCaModSize struct{} + +func (l *rootCaModSize) Initialize() error { + return nil +} + +func (l *rootCaModSize) CheckApplies(c *x509.Certificate) bool { + issueDate := c.NotBefore + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA && util.IsRootCA(c) && issueDate.Before(util.NoRSA1024RootDate) +} + +func (l *rootCaModSize) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.N.BitLen() < 2048 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_old_root_ca_rsa_mod_less_than_2048_bits", + Description: "In a validity period beginning on or before 31 Dec 2010, root CA certificates using RSA public key algorithm MUST use a 2048 bit modulus", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &rootCaModSize{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_ca_rsa_mod_less_than_1024_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_ca_rsa_mod_less_than_1024_bits.go new file mode 100644 index 0000000000..882299916c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_ca_rsa_mod_less_than_1024_bits.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// CHANGE THIS COMMENT TO MATCH SOURCE TEXT + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCaModSize struct{} + +func (l *subCaModSize) Initialize() error { + return nil +} + +func (l *subCaModSize) CheckApplies(c *x509.Certificate) bool { + issueDate := c.NotBefore + endDate := c.NotAfter + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && util.IsSubCA(c) && issueDate.Before(util.NoRSA1024RootDate) && endDate.Before(util.NoRSA1024Date) +} + +func (l *subCaModSize) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.N.BitLen() < 1024 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_old_sub_ca_rsa_mod_less_than_1024_bits", + Description: "In a validity period beginning on or before 31 Dec 2010 and ending on or before 31 Dec 2013, subordinate CA certificates using RSA public key algorithm MUST use a 1024 bit modulus", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + // since effective date should be checked against end date in this specific case, putting time check into checkApplies instead, ZeroDate here to automatically pass NE test + EffectiveDate: util.ZeroDate, + Lint: &subCaModSize{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_cert_rsa_mod_less_than_1024_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_cert_rsa_mod_less_than_1024_bits.go new file mode 100644 index 0000000000..f3cf306e9a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_old_sub_cert_rsa_mod_less_than_1024_bits.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subModSize struct{} + +func (l *subModSize) Initialize() error { + return nil +} + +func (l *subModSize) CheckApplies(c *x509.Certificate) bool { + endDate := c.NotAfter + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA && !util.IsCACert(c) && endDate.Before(util.NoRSA1024Date) +} + +func (l *subModSize) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.N.BitLen() < 1024 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_old_sub_cert_rsa_mod_less_than_1024_bits", + Description: "In a validity period ending on or before 31 Dec 2013, subscriber certificates using RSA public key algorithm MUST use a 1024 bit modulus", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + // since effective date should be checked against end date in this specific case, putting time check into checkApplies instead, ZeroDate here to automatically pass NE test + EffectiveDate: util.ZeroDate, + Lint: &subModSize{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_public_key_type_not_allowed.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_public_key_type_not_allowed.go new file mode 100644 index 0000000000..ebc29a5618 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_public_key_type_not_allowed.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type publicKeyAllowed struct{} + +func (l *publicKeyAllowed) Initialize() error { + return nil +} + +func (l *publicKeyAllowed) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *publicKeyAllowed) Execute(c *x509.Certificate) *lint.LintResult { + alg := c.PublicKeyAlgorithm + if alg != x509.UnknownPublicKeyAlgorithm { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_public_key_type_not_allowed", + Description: "Certificates MUST have RSA, DSA, or ECDSA public key type", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &publicKeyAllowed{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_basic_constraints_path_len_constraint_field_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_basic_constraints_path_len_constraint_field_present.go new file mode 100644 index 0000000000..6c46d36e29 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_basic_constraints_path_len_constraint_field_present.go @@ -0,0 +1,71 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************ +7.1.2.1. Root CA Certificate +a. basicConstraints +This extension MUST appear as a critical extension. The cA field MUST be set true. The pathLenConstraint field SHOULD NOT be present. +***********************************************************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCaPathLenPresent struct{} + +func (l *rootCaPathLenPresent) Initialize() error { + return nil +} + +func (l *rootCaPathLenPresent) CheckApplies(c *x509.Certificate) bool { + return util.IsRootCA(c) && util.IsExtInCert(c, util.BasicConstOID) +} + +func (l *rootCaPathLenPresent) Execute(c *x509.Certificate) *lint.LintResult { + bc := util.GetExtFromCert(c, util.BasicConstOID) + var seq asn1.RawValue + var isCa bool + _, err := asn1.Unmarshal(bc.Value, &seq) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(seq.Bytes) == 0 { + return &lint.LintResult{Status: lint.Pass} + } + rest, err := asn1.Unmarshal(seq.Bytes, &isCa) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(rest) > 0 { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_root_ca_basic_constraints_path_len_constraint_field_present", + Description: "Root CA certificate basicConstraint extension pathLenConstraint field SHOULD NOT be present", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &rootCaPathLenPresent{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_contains_cert_policy.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_contains_cert_policy.go new file mode 100644 index 0000000000..91994f9ebd --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_contains_cert_policy.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1c certificatePolicies +This extension SHOULD NOT be present. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCAContainsCertPolicy struct{} + +func (l *rootCAContainsCertPolicy) Initialize() error { + return nil +} + +func (l *rootCAContainsCertPolicy) CheckApplies(c *x509.Certificate) bool { + return util.IsRootCA(c) +} + +func (l *rootCAContainsCertPolicy) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.CertPolicyOID) { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_root_ca_contains_cert_policy", + Description: "Root CA Certificate: certificatePolicies SHOULD NOT be present.", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &rootCAContainsCertPolicy{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_extended_key_usage_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_extended_key_usage_present.go new file mode 100644 index 0000000000..d9c1925a63 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_extended_key_usage_present.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.1d extendedKeyUsage +This extension MUST NOT be present. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCAContainsEKU struct{} + +func (l *rootCAContainsEKU) Initialize() error { + return nil +} + +func (l *rootCAContainsEKU) CheckApplies(c *x509.Certificate) bool { + return util.IsRootCA(c) +} + +func (l *rootCAContainsEKU) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.EkuSynOid) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_root_ca_extended_key_usage_present", + Description: "Root CA Certificate: extendedKeyUsage MUST NOT be present.t", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &rootCAContainsEKU{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_must_be_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_must_be_critical.go new file mode 100644 index 0000000000..91329ce5b5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_must_be_critical.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCAKeyUsageMustBeCritical struct{} + +func (l *rootCAKeyUsageMustBeCritical) Initialize() error { + return nil +} + +func (l *rootCAKeyUsageMustBeCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsRootCA(c) && util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *rootCAKeyUsageMustBeCritical) Execute(c *x509.Certificate) *lint.LintResult { + keyUsageExtension := util.GetExtFromCert(c, util.KeyUsageOID) + if keyUsageExtension.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_root_ca_key_usage_must_be_critical", + Description: "Root CA certificates MUST have Key Usage Extension marked critical", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC2459Date, + Lint: &rootCAKeyUsageMustBeCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_present.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_present.go new file mode 100644 index 0000000000..cbd7aba4e3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_root_ca_key_usage_present.go @@ -0,0 +1,50 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rootCAKeyUsagePresent struct{} + +func (l *rootCAKeyUsagePresent) Initialize() error { + return nil +} + +func (l *rootCAKeyUsagePresent) CheckApplies(c *x509.Certificate) bool { + return util.IsRootCA(c) +} + +func (l *rootCAKeyUsagePresent) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.KeyUsageOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_root_ca_key_usage_present", + Description: "Root CA certificates MUST have Key Usage Extension Present", + Citation: "BRs: 7.1.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.RFC2459Date, + Lint: &rootCAKeyUsagePresent{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_factors_smaller_than_752_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_factors_smaller_than_752_bits.go new file mode 100644 index 0000000000..e851d59f94 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_factors_smaller_than_752_bits.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************** +6.1.6. Public Key Parameters Generation and Quality Checking +RSA: The CA SHALL confirm that the value of the public exponent is an odd number equal to 3 or more. Additionally, the public exponent SHOULD be in the range between 216+1 and 2256-1. The modulus SHOULD also have the following characteristics: an odd number, not the power of a prime, and have no factors smaller than 752. [Citation: Section 5.3.3, NIST SP 800‐89]. +**************************************************************************************************/ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaModSmallFactor struct{} + +func (l *rsaModSmallFactor) Initialize() error { + return nil +} + +func (l *rsaModSmallFactor) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaModSmallFactor) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if util.PrimeNoSmallerThan752(key.N) { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Warn} + +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_rsa_mod_factors_smaller_than_752", + Description: "RSA: Modulus SHOULD also have the following characteristics: no factors smaller than 752", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV113Date, + Lint: &rsaModSmallFactor{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_less_than_2048_bits.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_less_than_2048_bits.go new file mode 100644 index 0000000000..d7eaef41db --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_less_than_2048_bits.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedTestsKeySize struct{} + +func (l *rsaParsedTestsKeySize) Initialize() error { + return nil +} + +func (l *rsaParsedTestsKeySize) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA && c.NotAfter.After(util.NoRSA1024Date.Add(-1)) +} + +func (l *rsaParsedTestsKeySize) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.N.BitLen() < 2048 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_rsa_mod_less_than_2048_bits", + Description: "For certificates valid after 31 Dec 2013, all certificates using RSA public key algorithm MUST have 2048 bits of modulus", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &rsaParsedTestsKeySize{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_not_odd.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_not_odd.go new file mode 100644 index 0000000000..0c2b54b62a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_mod_not_odd.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"BRs: 6.1.6" +RSA: The CA SHALL confirm that the value of the public exponent is an odd number equal to 3 or more. Additionally, the public exponent SHOULD be in the range between 2^16+1 and 2^256-1. The modulus SHOULD also have the following characteristics: an odd number, not the power of a prime, and have no factors smaller than 752. [Citation: Section 5.3.3, NIST SP 800-89]. +*******************************************************************************************************/ + +import ( + "crypto/rsa" + "math/big" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedTestsKeyModOdd struct{} + +func (l *rsaParsedTestsKeyModOdd) Initialize() error { + return nil +} + +func (l *rsaParsedTestsKeyModOdd) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaParsedTestsKeyModOdd) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + z := big.NewInt(0) + if (z.Mod(key.N, big.NewInt(2)).Cmp(big.NewInt(1))) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_rsa_mod_not_odd", + Description: "RSA: Modulus SHOULD also have the following characteristics: an odd number", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV113Date, + Lint: &rsaParsedTestsKeyModOdd{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_in_range.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_in_range.go new file mode 100644 index 0000000000..07733454f8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_in_range.go @@ -0,0 +1,65 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"BRs: 6.1.6" +RSA: The CA SHALL confirm that the value of the public exponent is an odd number equal to 3 or more. Additionally, the public exponent SHOULD be in the range between 2^16+1 and 2^256-1. The modulus SHOULD also have the following characteristics: an odd number, not the power of a prime, and have no factors smaller than 752. [Citation: Section 5.3.3, NIST SP 800-89]. +*******************************************************************************************************/ + +import ( + "crypto/rsa" + "math/big" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedTestsExpInRange struct { + upperBound *big.Int +} + +func (l *rsaParsedTestsExpInRange) Initialize() error { + l.upperBound = &big.Int{} + l.upperBound.Exp(big.NewInt(2), big.NewInt(256), nil) + return nil +} + +func (l *rsaParsedTestsExpInRange) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaParsedTestsExpInRange) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + exponent := key.E + const lowerBound = 65536 // 2^16 + 1 + if exponent > lowerBound && l.upperBound.Cmp(big.NewInt(int64(exponent))) == 1 { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Warn} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_rsa_public_exponent_not_in_range", + Description: "RSA: Public exponent SHOULD be in the range between 2^16 + 1 and 2^256 - 1", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV113Date, + Lint: &rsaParsedTestsExpInRange{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_odd.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_odd.go new file mode 100644 index 0000000000..a1be9438f6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_not_odd.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"BRs: 6.1.6" +RSA: The CA SHALL confirm that the value of the public exponent is an odd number equal to 3 or more. Additionally, the public exponent SHOULD be in the range between 2^16+1 and 2^256-1. The modulus SHOULD also have the following characteristics: an odd number, not the power of a prime, and have no factors smaller than 752. [Citation: Section 5.3.3, NIST SP 800-89]. +*******************************************************************************************************/ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedTestsKeyExpOdd struct{} + +func (l *rsaParsedTestsKeyExpOdd) Initialize() error { + return nil +} + +func (l *rsaParsedTestsKeyExpOdd) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaParsedTestsKeyExpOdd) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.E%2 == 1 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_rsa_public_exponent_not_odd", + Description: "RSA: Value of public exponent is an odd number equal to 3 or more.", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV113Date, + Lint: &rsaParsedTestsKeyExpOdd{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_too_small.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_too_small.go new file mode 100644 index 0000000000..f4179175b3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_rsa_public_exponent_too_small.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"BRs: 6.1.6" +RSA: The CA SHALL confirm that the value of the public exponent is an odd number equal to 3 or more. Additionally, the public exponent SHOULD be in the range between 2^16+1 and 2^256-1. The modulus SHOULD also have the following characteristics: an odd number, not the power of a prime, and have no factors smaller than 752. [Citation: Section 5.3.3, NIST SP 800-89]. +*******************************************************************************************************/ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedTestsExpBounds struct{} + +func (l *rsaParsedTestsExpBounds) Initialize() error { + return nil +} + +func (l *rsaParsedTestsExpBounds) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaParsedTestsExpBounds) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.E >= 3 { //If Cmp returns 1, means N > E + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_rsa_public_exponent_too_small", + Description: "RSA: Value of public exponent is an odd number equal to 3 or more.", + Citation: "BRs: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV113Date, + Lint: &rsaParsedTestsExpBounds{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_invalid.go new file mode 100644 index 0000000000..4dcfe09738 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_invalid.go @@ -0,0 +1,151 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +https://tools.ietf.org/html/rfc7686#section-1 + + Note that .onion names are required to conform with DNS name syntax + (as defined in Section 3.5 of [RFC1034] and Section 2.1 of + [RFC1123]), as they will still be exposed to DNS implementations. + + See [tor-address] and [tor-rendezvous] for the details of the + creation and use of .onion names. + +Baseline Requirements, v1.6.9, Appendix C (Ballot SC27) + +The Domain Name MUST contain at least two labels, where the right-most label +is "onion", and the label immediately preceding the right-most "onion" label +is a valid Version 3 Onion Address, as defined in section 6 of the Tor +Rendezvous Specification - Version 3 located at +https://spec.torproject.org/rend-spec-v3. + +Explanation: +Since CA/Browser Forum Ballot 144, `.onion` names have been permitted, +predating the ratification of RFC 7686. RFC 7686 introduced a normative +dependency on the Tor address and rendezvous specifications, which describe +v2 addresses. As the EV Guidelines have, since v1.5.3, required that the CA +obtain a demonstration of control from the Applicant, which effectively +requires the `.onion` name to be well-formed, even prior to RFC 7686. + +See also https://github.com/cabforum/documents/issues/191 +*******************************************************************/ + +package cabf_br + +import ( + "fmt" + "regexp" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +var ( + // Per 2.4 of Rendezvous v2: + // Valid onion addresses contain 16 characters in a-z2-7 plus ".onion" + onionV2Len = 16 + + // Per 1.2 of Rendezvous v3: + // A hidden service's name is its long term master identity key. This is + // encoded as a hostname by encoding the entire key in Base 32, including + // a version byte and a checksum, and then appending the string ".onion" + // at the end. The result is a 56-character domain name. + onionV3Len = 56 + + // Per RFC 4648, Section 6, the Base-32 alphabet is A-Z, 2-7, and =. + // Because v2/v3 addresses are always aligned, they should never be padded, + // and so omit = from the character set, as it's also not permitted in a + // domain in the "preferred name syntax". Because `.onion` names appear in + // DNS, which is case insensitive, the alphabet is extended to include a-z, + // as the names are tested for well-formedness prior to normalization to + // uppercase. + base32SubsetRegex = regexp.MustCompile(`^[a-zA-Z2-7]+$`) +) + +type onionNotValid struct{} + +func (l *onionNotValid) Initialize() error { + return nil +} + +// CheckApplies returns true if the certificate contains one or more subject +// names ending in `.onion`. +func (l *onionNotValid) CheckApplies(c *x509.Certificate) bool { + // TODO(sleevi): This should also be extended to support nameConstraints + // in the future. + return util.CertificateSubjInTLD(c, util.OnionTLD) +} + +// Execute will lint the provided certificate. A lint.Error lint.LintResult will +// be returned if: +// +// 1) The certificate contains a Tor Rendezvous Spec v2 address and is not an +// EV certificate (BRs: Appendix C). +// 2) The certificate contains a `.onion` subject name/SAN that is neither a +// Rendezvous Spec v2 or v3 address. +func (l *onionNotValid) Execute(c *x509.Certificate) *lint.LintResult { + for _, subj := range append(c.DNSNames, c.Subject.CommonName) { + if !strings.HasSuffix(subj, util.OnionTLD) { + continue + } + labels := strings.Split(subj, ".") + if len(labels) < 2 { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("certificate contained a %s domain with too "+ + "few labels: %q", util.OnionTLD, subj), + } + } + onionDomain := labels[len(labels)-2] + if len(onionDomain) == onionV2Len { + // Onion v2 address. These are only permitted for EV, per BRs Appendix C. + if !util.IsEV(c.PolicyIdentifiers) { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("%q is a v2 address, but the certificate is not "+ + "EV", subj), + } + } + } else if len(onionDomain) == onionV3Len { + // Onion v3 address. Permitted for all certificates by CA/Browser Forum + // Ballot SC27. + } else { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("%q is not a v2 or v3 Tor address", subj), + } + } + if !base32SubsetRegex.MatchString(onionDomain) { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("%q contains invalid characters not permitted "+ + "within base-32", subj), + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_dns_name_onion_invalid", + Description: "certificates with a .onion subject name must be issued in accordance with the Tor address/rendezvous specification", + Citation: "RFC 7686, EVGs v1.7.2: Appendix F, BRs v1.6.9: Appendix C", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.OnionOnlyEVDate, + Lint: &onionNotValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_not_ev_cert.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_not_ev_cert.go new file mode 100644 index 0000000000..8693ff09f0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_san_dns_name_onion_not_ev_cert.go @@ -0,0 +1,69 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_br + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type onionNotEV struct{} + +func (l *onionNotEV) Initialize() error { + return nil +} + +// This lint only applies for certificates issued before CA/Browser Forum +// Ballot SC27, which permitted .onion within non-EV certificates +func (l *onionNotEV) CheckApplies(c *x509.Certificate) bool { + return c.NotBefore.Before(util.CABFBRs_1_6_9_Date) && + util.IsSubscriberCert(c) && + util.CertificateSubjInTLD(c, util.OnionTLD) +} + +// Execute returns an lint.Error lint.LintResult if the certificate is not an EV +// certificate. CheckApplies has already verified the certificate contains one +// or more `.onion` subjects and so it must be an EV certificate. +func (l *onionNotEV) Execute(c *x509.Certificate) *lint.LintResult { + /* + * Effective May 1, 2015, each CA SHALL revoke all unexpired Certificates with an + * Internal Name using onion as the right-most label in an entry in the + * subjectAltName Extension or commonName field unless such Certificate was + * issued in accordance with Appendix F of the EV Guidelines. + */ + if !util.IsEV(c.PolicyIdentifiers) { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf( + "certificate contains one or more %s subject domains but is not an EV certificate", + util.OnionTLD), + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_dns_name_onion_not_ev_cert", + Description: "certificates with a .onion subject name must be issued in accordance with EV Guidelines", + Citation: "CABF Ballot 144", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.OnionOnlyEVDate, + Lint: &onionNotEV{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_signature_algorithm_not_supported.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_signature_algorithm_not_supported.go new file mode 100644 index 0000000000..7183087b05 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_signature_algorithm_not_supported.go @@ -0,0 +1,87 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +var ( + // Any of the following x509.SignatureAlgorithms are acceptable per §6.1.5 of + // the BRs. + passSigAlgs = map[x509.SignatureAlgorithm]bool{ + x509.SHA256WithRSA: true, + x509.SHA384WithRSA: true, + x509.SHA512WithRSA: true, + x509.DSAWithSHA256: true, + x509.ECDSAWithSHA256: true, + x509.ECDSAWithSHA384: true, + x509.ECDSAWithSHA512: true, + // NOTE: BRs section §6.1.5 does not include SHA1 digest algorithms in the + // current version. We allow these here for historic reasons and check for + // SHA1 usage after the deprecation date in the separate + // `e_sub_cert_or_sub_ca_using_sha1` lint. + x509.SHA1WithRSA: true, + x509.DSAWithSHA1: true, + x509.ECDSAWithSHA1: true, + } + // The BRs do not forbid the use of RSA-PSS as a signature scheme in + // certificates but it is not broadly supported by user-agents. Since + // the BRs do not forbid the practice we return a warning result. + // NOTE: The Mozilla root program policy *does* forbid their use since v2.7. + // This should be covered by a lint scoped to the Mozilla source instead of in + // this CABF lint. + warnSigAlgs = map[x509.SignatureAlgorithm]bool{ + x509.SHA256WithRSAPSS: true, + x509.SHA384WithRSAPSS: true, + x509.SHA512WithRSAPSS: true, + } +) + +type signatureAlgorithmNotSupported struct{} + +func (l *signatureAlgorithmNotSupported) Initialize() error { + return nil +} + +func (l *signatureAlgorithmNotSupported) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *signatureAlgorithmNotSupported) Execute(c *x509.Certificate) *lint.LintResult { + sigAlg := c.SignatureAlgorithm + status := lint.Error + if passSigAlgs[sigAlg] { + status = lint.Pass + } else if warnSigAlgs[sigAlg] { + status = lint.Warn + } + return &lint.LintResult{ + Status: status, + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_signature_algorithm_not_supported", + Description: "Certificates MUST meet the following requirements for algorithm Source: SHA-1*, SHA-256, SHA-384, SHA-512", + Citation: "BRs: 6.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &signatureAlgorithmNotSupported{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_does_not_contain_issuing_ca_url.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_does_not_contain_issuing_ca_url.go new file mode 100644 index 0000000000..628a41c5d2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_does_not_contain_issuing_ca_url.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************** +CAB 7.1.2.2c +With the exception of stapling, which is noted below, this extension MUST be present. It MUST NOT be +marked critical, and it MUST contain the HTTP URL of the Issuing CA’s OCSP responder (accessMethod += 1.3.6.1.5.5.7.48.1). It SHOULD also contain the HTTP URL of the Issuing CA’s certificate +(accessMethod = 1.3.6.1.5.5.7.48.2). +************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCaIssuerUrl struct{} + +func (l *subCaIssuerUrl) Initialize() error { + return nil +} + +func (l *subCaIssuerUrl) CheckApplies(c *x509.Certificate) bool { + return util.IsCACert(c) && !util.IsRootCA(c) +} + +func (l *subCaIssuerUrl) Execute(c *x509.Certificate) *lint.LintResult { + for _, url := range c.IssuingCertificateURL { + if strings.HasPrefix(url, "http://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Warn} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_ca_aia_does_not_contain_issuing_ca_url", + Description: "Subordinate CA Certificate: authorityInformationAccess SHOULD also contain the HTTP URL of the Issuing CA's certificate.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCaIssuerUrl{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_marked_critical.go new file mode 100644 index 0000000000..e2c776cd32 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_marked_critical.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCaAIAMarkedCritical struct{} + +func (l *subCaAIAMarkedCritical) Initialize() error { + return nil +} + +func (l *subCaAIAMarkedCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.AiaOID) +} + +func (l *subCaAIAMarkedCritical) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.AiaOID) + if e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_aia_marked_critical", + Description: "Subordinate CA Certificate: authorityInformationAccess MUST NOT be marked critical", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + Lint: &subCaAIAMarkedCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_missing.go new file mode 100644 index 0000000000..37517d99c6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_aia_missing.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************** +CAB 7.1.2.2c +With the exception of stapling, which is noted below, this extension MUST be present. It MUST NOT be +marked critical, and it MUST contain the HTTP URL of the Issuing CA’s OCSP responder (accessMethod += 1.3.6.1.5.5.7.48.1). It SHOULD also contain the HTTP URL of the Issuing CA’s certificate +(accessMethod = 1.3.6.1.5.5.7.48.2). +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caAiaMissing struct{} + +func (l *caAiaMissing) Initialize() error { + return nil +} + +func (l *caAiaMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsCACert(c) && !util.IsRootCA(c) +} + +func (l *caAiaMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.AiaOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_aia_missing", + Description: "Subordinate CA Certificate: authorityInformationAccess MUST be present, with the exception of stapling.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &caAiaMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_marked_critical.go new file mode 100644 index 0000000000..282f162c5f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_marked_critical.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2a certificatePolicies +This extension MUST be present and SHOULD NOT be marked critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCACertPolicyCrit struct{} + +func (l *subCACertPolicyCrit) Initialize() error { + return nil +} + +func (l *subCACertPolicyCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.CertPolicyOID) +} + +func (l *subCACertPolicyCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.CertPolicyOID); e.Critical { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } + +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_ca_certificate_policies_marked_critical", + Description: "Subordinate CA certificates certificatePolicies extension should not be marked as critical", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCACertPolicyCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_missing.go new file mode 100644 index 0000000000..2d19901ae3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_certificate_policies_missing.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2a certificatePolicies +This extension MUST be present and SHOULD NOT be marked critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCACertPolicyMissing struct{} + +func (l *subCACertPolicyMissing) Initialize() error { + return nil +} + +func (l *subCACertPolicyMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) +} + +func (l *subCACertPolicyMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.CertPolicyOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_certificate_policies_missing", + Description: "Subordinate CA certificates must have a certificatePolicies extension", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCACertPolicyMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_does_not_contain_url.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_does_not_contain_url.go new file mode 100644 index 0000000000..5156b0b0fb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_does_not_contain_url.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2b cRLDistributionPoints +This extension MUST be present and MUST NOT be marked critical. +It MUST contain the HTTP URL of the CA’s CRL service. +************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCACRLDistNoUrl struct{} + +func (l *subCACRLDistNoUrl) Initialize() error { + return nil +} + +func (l *subCACRLDistNoUrl) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *subCACRLDistNoUrl) Execute(c *x509.Certificate) *lint.LintResult { + for _, s := range c.CRLDistributionPoints { + if strings.HasPrefix(s, "http://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_crl_distribution_points_does_not_contain_url", + Description: "Subordinate CA Certificate: cRLDistributionPoints MUST contain the HTTP URL of the CA's CRL service.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCACRLDistNoUrl{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_marked_critical.go new file mode 100644 index 0000000000..3d87ffb63e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_marked_critical.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2b cRLDistributionPoints +This extension MUST be present and MUST NOT be marked critical. +It MUST contain the HTTP URL of the CA’s CRL service. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCACRLDistCrit struct{} + +func (l *subCACRLDistCrit) Initialize() error { + return nil +} + +func (l *subCACRLDistCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *subCACRLDistCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.CrlDistOID); e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_crl_distribution_points_marked_critical", + Description: "Subordinate CA Certificate: cRLDistributionPoints MUST be present and MUST NOT be marked critical.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCACRLDistCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_missing.go new file mode 100644 index 0000000000..a476e4b10b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_crl_distribution_points_missing.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2b cRLDistributionPoints +This extension MUST be present and MUST NOT be marked critical. +It MUST contain the HTTP URL of the CA’s CRL service. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCACRLDistMissing struct{} + +func (l *subCACRLDistMissing) Initialize() error { + return nil +} + +func (l *subCACRLDistMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) +} + +func (l *subCACRLDistMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.CrlDistOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_ca_crl_distribution_points_missing", + Description: "Subordinate CA Certificate: cRLDistributionPoints MUST be present and MUST NOT be marked critical.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCACRLDistMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_critical.go new file mode 100644 index 0000000000..d94c509f22 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_critical.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.2.2g extkeyUsage (optional) +For Subordinate CA Certificates to be Technically constrained in line with section 7.1.5, then either the value +id‐kp‐serverAuth [RFC5280] or id‐kp‐clientAuth [RFC5280] or both values MUST be present**. +Other values MAY be present. +If present, this extension SHOULD be marked non‐critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCAEKUCrit struct{} + +func (l *subCAEKUCrit) Initialize() error { + return nil +} + +func (l *subCAEKUCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.EkuSynOid) +} + +func (l *subCAEKUCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.EkuSynOid); e.Critical { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_ca_eku_critical", + Description: "Subordinate CA certificate extkeyUsage extension should be marked non-critical if present", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV116Date, + Lint: &subCAEKUCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_missing.go new file mode 100644 index 0000000000..8b015d0fb0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_missing.go @@ -0,0 +1,50 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCAEKUMissing struct{} + +func (l *subCAEKUMissing) Initialize() error { + return nil +} + +func (l *subCAEKUMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) +} + +func (l *subCAEKUMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.EkuSynOid) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Notice} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_sub_ca_eku_missing", + Description: "To be considered Technically Constrained, the Subordinate CA certificate MUST have extkeyUsage extension", + Citation: "BRs: 7.1.5", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCAEKUMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_valid_fields.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_valid_fields.go new file mode 100644 index 0000000000..ed47ac3d35 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_eku_valid_fields.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCAEKUValidFields struct{} + +func (l *subCAEKUValidFields) Initialize() error { + return nil +} + +func (l *subCAEKUValidFields) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && util.IsExtInCert(c, util.EkuSynOid) +} + +func (l *subCAEKUValidFields) Execute(c *x509.Certificate) *lint.LintResult { + validFieldsPresent := false + for _, ekuValue := range c.ExtKeyUsage { + if ekuValue == x509.ExtKeyUsageServerAuth || + ekuValue == x509.ExtKeyUsageClientAuth { + validFieldsPresent = true + } + } + if validFieldsPresent { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Notice} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_sub_ca_eku_not_technically_constrained", + Description: "Subordinate CA extkeyUsage, either id-kp-serverAuth or id-kp-clientAuth or both values MUST be present to be technically constrained.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV116Date, + Lint: &subCAEKUValidFields{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_name_constraints_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_name_constraints_not_critical.go new file mode 100644 index 0000000000..4dc382efe0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_ca_name_constraints_not_critical.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +CA Brower Forum Baseline Requirements, Section 7.1.2.2: + + f. nameConstraints (optional) +If present, this extension SHOULD be marked critical*. + +* Non-critical Name Constraints are an exception to RFC 5280 (4.2.1.10), however, they MAY be used until the +Name Constraints extension is supported by Application Software Suppliers whose software is used by a +substantial portion of Relying Parties worldwide +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubCANameConstraintsNotCritical struct{} + +func (l *SubCANameConstraintsNotCritical) Initialize() error { + return nil +} + +func (l *SubCANameConstraintsNotCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsSubCA(cert) && util.IsExtInCert(cert, util.NameConstOID) +} + +func (l *SubCANameConstraintsNotCritical) Execute(cert *x509.Certificate) *lint.LintResult { + if ski := util.GetExtFromCert(cert, util.NameConstOID); ski.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_ca_name_constraints_not_critical", + Description: "Subordinate CA Certificate: NameConstraints if present, SHOULD be marked critical.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABV102Date, + Lint: &SubCANameConstraintsNotCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go new file mode 100644 index 0000000000..11a58cdaaf --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +BRs: 7.1.2.3 +cRLDistributionPoints +This extension MAY be present. If present, it MUST NOT be marked critical, and it MUST contain the +HTTP URL of the CA’s CRL service. See Section 13.2.1 for details. +*************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertIssuerUrl struct{} + +func (l *subCertIssuerUrl) Initialize() error { + return nil +} + +func (l *subCertIssuerUrl) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertIssuerUrl) Execute(c *x509.Certificate) *lint.LintResult { + for _, url := range c.IssuingCertificateURL { + if strings.HasPrefix(url, "http://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Warn} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_cert_aia_does_not_contain_issuing_ca_url", + Description: "Subscriber certificates authorityInformationAccess extension should contain the HTTP URL of the issuing CA’s certificate", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertIssuerUrl{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go new file mode 100644 index 0000000000..0e9dae824a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go @@ -0,0 +1,62 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************** +BRs: 7.1.2.3 +authorityInformationAccess +With the exception of stapling, which is noted below, this extension MUST be present. It MUST NOT be +marked critical, and it MUST contain the HTTP URL of the Issuing CA’s OCSP responder (accessMethod += 1.3.6.1.5.5.7.48.1). It SHOULD also contain the HTTP URL of the Issuing CA’s certificate +(accessMethod = 1.3.6.1.5.5.7.48.2). See Section 13.2.1 for details. +***************************************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertOcspUrl struct{} + +func (l *subCertOcspUrl) Initialize() error { + return nil +} + +func (l *subCertOcspUrl) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *subCertOcspUrl) Execute(c *x509.Certificate) *lint.LintResult { + for _, url := range c.OCSPServer { + if strings.HasPrefix(url, "http://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_aia_does_not_contain_ocsp_url", + Description: "Subscriber Certificate: authorityInformationAccess MUST contain the HTTP URL of the Issuing CA's OSCP responder.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertOcspUrl{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_marked_critical.go new file mode 100644 index 0000000000..043ff1ddc1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_marked_critical.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertAiaMarkedCritical struct{} + +func (l *subCertAiaMarkedCritical) Initialize() error { + return nil +} + +func (l *subCertAiaMarkedCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.AiaOID) +} + +func (l *subCertAiaMarkedCritical) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.AiaOID) + if e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_aia_marked_critical", + Description: "Subscriber Certificate: authorityInformationAccess MUST NOT be marked critical", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertAiaMarkedCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_missing.go new file mode 100644 index 0000000000..0869a6873c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_aia_missing.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************** +BRs: 7.1.2.3 +authorityInformationAccess +With the exception of stapling, which is noted below, this extension MUST be present. It MUST NOT be +marked critical, and it MUST contain the HTTP URL of the Issuing CA’s OCSP responder (accessMethod += 1.3.6.1.5.5.7.48.1). It SHOULD also contain the HTTP URL of the Issuing CA’s certificate +(accessMethod = 1.3.6.1.5.5.7.48.2). See Section 13.2.1 for details. +***************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertAiaMissing struct{} + +func (l *subCertAiaMissing) Initialize() error { + return nil +} + +func (l *subCertAiaMissing) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *subCertAiaMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.AiaOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_aia_missing", + Description: "Subscriber Certiifcate: authorityInformationAccess MUST be present, with the exception of stapling.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertAiaMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_cert_policy_empty.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_cert_policy_empty.go new file mode 100644 index 0000000000..e2da7c99ae --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_cert_policy_empty.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************************** +BRs: 7.1.6.4 +Subscriber Certificates +A Certificate issued to a Subscriber MUST contain one or more policy identifier(s), defined by the Issuing CA, in +the Certificate’s certificatePolicies extension that indicates adherence to and complIANce with these Requirements. +CAs complying with these Requirements MAY also assert one of the reserved policy OIDs in such Certificates. +*********************************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertPolicyEmpty struct{} + +func (l *subCertPolicyEmpty) Initialize() error { + return nil +} + +func (l *subCertPolicyEmpty) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *subCertPolicyEmpty) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.CertPolicyOID) && c.PolicyIdentifiers != nil { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_cert_policy_empty", + Description: "Subscriber certificates must contain at least one policy identifier that indicates adherence to CAB standards", + Citation: "BRs: 7.1.6.4", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertPolicyEmpty{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_marked_critical.go new file mode 100644 index 0000000000..7123db1d29 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_marked_critical.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/****************************************************************************** +BRs: 7.1.2.3 +certificatePolicies +This extension MUST be present and SHOULD NOT be marked critical. +******************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertPolicyCrit struct{} + +func (l *subCertPolicyCrit) Initialize() error { + return nil +} + +func (l *subCertPolicyCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CertPolicyOID) +} + +func (l *subCertPolicyCrit) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.CertPolicyOID) + if !e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_cert_certificate_policies_marked_critical", + Description: "Subscriber Certificate: certificatePolicies MUST be present and SHOULD NOT be marked critical.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertPolicyCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_missing.go new file mode 100644 index 0000000000..6abe6d0fb3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_certificate_policies_missing.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/****************************************************************************** +BRs: 7.1.2.3 +certificatePolicies +This extension MUST be present and SHOULD NOT be marked critical. +******************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertPolicy struct{} + +func (l *subCertPolicy) Initialize() error { + return nil +} + +func (l *subCertPolicy) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *subCertPolicy) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.CertPolicyOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_certificate_policies_missing", + Description: "Subscriber Certificate: certificatePolicies MUST be present and SHOULD NOT be marked critical.", + Citation: "BRs: 7.1.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertPolicy{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_country_name_must_appear.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_country_name_must_appear.go new file mode 100644 index 0000000000..48a8ae59ac --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_country_name_must_appear.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertCountryNameMustAppear struct{} + +func (l *subCertCountryNameMustAppear) Initialize() error { + return nil +} + +func (l *subCertCountryNameMustAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertCountryNameMustAppear) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.Organization) > 0 || len(c.Subject.GivenName) > 0 || len(c.Subject.Surname) > 0 { + if len(c.Subject.Country) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_country_name_must_appear", + Description: "Subscriber Certificate: subject:countryName MUST appear if the subject:organizationName field, subject:givenName field, or subject:surname fields are present.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertCountryNameMustAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_does_not_contain_url.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_does_not_contain_url.go new file mode 100644 index 0000000000..fa541e7a09 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_does_not_contain_url.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +BRs: 7.1.2.3 +cRLDistributionPoints +This extension MAY be present. If present, it MUST NOT be marked critical, and it MUST contain the HTTP +URL of the CA’s CRL service. +*******************************************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCRLDistNoURL struct{} + +func (l *subCRLDistNoURL) Initialize() error { + return nil +} + +func (l *subCRLDistNoURL) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *subCRLDistNoURL) Execute(c *x509.Certificate) *lint.LintResult { + for _, s := range c.CRLDistributionPoints { + if strings.HasPrefix(s, "http://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_crl_distribution_points_does_not_contain_url", + Description: "Subscriber certificate cRLDistributionPoints extension must contain the HTTP URL of the CA’s CRL service", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCRLDistNoURL{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_marked_critical.go new file mode 100644 index 0000000000..f313e2f52d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_crl_distribution_points_marked_critical.go @@ -0,0 +1,58 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +BRs: 7.1.2.3 +cRLDistributionPoints +This extension MAY be present. If present, it MUST NOT be marked critical, and it MUST contain the HTTP +URL of the CA’s CRL service. +*******************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCrlDistCrit struct{} + +func (l *subCrlDistCrit) Initialize() error { + return nil +} + +func (l *subCrlDistCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *subCrlDistCrit) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.CrlDistOID) + if !e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_crl_distribution_points_marked_critical", + Description: "Subscriber Certiifcate: cRLDistributionPoints MUST NOT be marked critical, and MUST contain the HTTP URL of the CA's CRL service.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCrlDistCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_extra_values.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_extra_values.go new file mode 100644 index 0000000000..1a40895ef7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_extra_values.go @@ -0,0 +1,64 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +BRs: 7.1.2.3 +extKeyUsage (required) +Either the value id-kp-serverAuth [RFC5280] or id-kp-clientAuth [RFC5280] or both values MUST be present. id-kp-emailProtection [RFC5280] MAY be present. Other values SHOULD NOT be present. +*******************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subExtKeyUsageLegalUsage struct{} + +func (l *subExtKeyUsageLegalUsage) Initialize() error { + return nil +} + +func (l *subExtKeyUsageLegalUsage) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && c.ExtKeyUsage != nil +} + +func (l *subExtKeyUsageLegalUsage) Execute(c *x509.Certificate) *lint.LintResult { + for _, kp := range c.ExtKeyUsage { + if kp == x509.ExtKeyUsageServerAuth || + kp == x509.ExtKeyUsageClientAuth || + kp == x509.ExtKeyUsageEmailProtection { + // If we find any of these three, considered passing, continue + continue + } else { + // A bad usage was found, report and leave + return &lint.LintResult{Status: lint.Warn} + } + } + // If no bad usage was found, pass + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_cert_eku_extra_values", + Description: "Subscriber Certificate: extKeyUsage values other than id-kp-serverAuth, id-kp-clientAuth, and id-kp-emailProtection SHOULD NOT be present.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subExtKeyUsageLegalUsage{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_missing.go new file mode 100644 index 0000000000..0e76dff786 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_missing.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +BRs: 7.1.2.3 +extKeyUsage (required) +Either the value id-kp-serverAuth [RFC5280] or id-kp-clientAuth [RFC5280] or both values MUST be present. id-kp-emailProtection [RFC5280] MAY be present. Other values SHOULD NOT be present. +*******************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subExtKeyUsage struct{} + +func (l *subExtKeyUsage) Initialize() error { + return nil +} + +func (l *subExtKeyUsage) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *subExtKeyUsage) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.EkuSynOid) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_eku_missing", + Description: "Subscriber certificates MUST have the extended key usage extension present", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subExtKeyUsage{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go new file mode 100644 index 0000000000..5f6b2b7b75 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go @@ -0,0 +1,59 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +BRs: 7.1.2.3 +extKeyUsage (required) +Either the value id-kp-serverAuth [RFC5280] or id-kp-clientAuth [RFC5280] or both values MUST be present. id-kp-emailProtection [RFC5280] MAY be present. Other values SHOULD NOT be present. +*******************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subExtKeyUsageClientOrServer struct{} + +func (l *subExtKeyUsageClientOrServer) Initialize() error { + return nil +} + +func (l *subExtKeyUsageClientOrServer) CheckApplies(c *x509.Certificate) bool { + return c.ExtKeyUsage != nil +} + +func (l *subExtKeyUsageClientOrServer) Execute(c *x509.Certificate) *lint.LintResult { + for _, kp := range c.ExtKeyUsage { + if kp == x509.ExtKeyUsageServerAuth || kp == x509.ExtKeyUsageClientAuth { + // If we find either of ServerAuth or ClientAuth, lint.Pass + return &lint.LintResult{Status: lint.Pass} + } + } + // If neither were found, lint.Error + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_eku_server_auth_client_auth_missing", + Description: "Subscriber certificates MUST have have either id-kp-serverAuth or id-kp-clientAuth or both present in extKeyUsage", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subExtKeyUsageClientOrServer{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_gn_sn_contains_policy.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_gn_sn_contains_policy.go new file mode 100644 index 0000000000..c75abac5f5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_gn_sn_contains_policy.go @@ -0,0 +1,52 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertSubjectGnOrSnContainsPolicy struct{} + +func (l *subCertSubjectGnOrSnContainsPolicy) Initialize() error { + return nil +} + +func (l *subCertSubjectGnOrSnContainsPolicy) CheckApplies(c *x509.Certificate) bool { + //Check if GivenName or Surname fields are filled out + return util.IsSubscriberCert(c) && (len(c.Subject.GivenName) != 0 || len(c.Subject.Surname) != 0) +} + +func (l *subCertSubjectGnOrSnContainsPolicy) Execute(c *x509.Certificate) *lint.LintResult { + for _, policyIds := range c.PolicyIdentifiers { + if policyIds.Equal(util.BRIndividualValidatedOID) { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_given_name_surname_contains_correct_policy", + Description: "Subscriber Certificate: A certificate containing a subject:givenName field or subject:surname field MUST contain the (2.23.140.1.2.3) certPolicy OID.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertSubjectGnOrSnContainsPolicy{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_is_ca.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_is_ca.go new file mode 100644 index 0000000000..535a8cb864 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_is_ca.go @@ -0,0 +1,57 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertNotCA struct{} + +func (l *subCertNotCA) Initialize() error { + return nil +} + +func (l *subCertNotCA) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) && c.KeyUsage&x509.KeyUsageCertSign == 0 && util.IsExtInCert(c, util.BasicConstOID) +} + +func (l *subCertNotCA) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.BasicConstOID) + var constraints basicConstraints + if _, err := asn1.Unmarshal(e.Value, &constraints); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if constraints.IsCA { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_not_is_ca", + Description: "Subscriber Certificate: basicContrainsts cA field MUST NOT be true.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertNotCA{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_cert_sign_bit_set.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_cert_sign_bit_set.go new file mode 100644 index 0000000000..8740b1f9e4 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_cert_sign_bit_set.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************** +BRs: 7.1.2.3 +keyUsage (optional) +If present, bit positions for keyCertSign and cRLSign MUST NOT be set. +***************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertKeyUsageBitSet struct{} + +func (l *subCertKeyUsageBitSet) Initialize() error { + return nil +} + +func (l *subCertKeyUsageBitSet) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) && !util.IsCACert(c) +} + +func (l *subCertKeyUsageBitSet) Execute(c *x509.Certificate) *lint.LintResult { + if (c.KeyUsage & x509.KeyUsageCertSign) == x509.KeyUsageCertSign { + return &lint.LintResult{Status: lint.Error} + } else { //key usage doesn't allow cert signing or isn't present + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_key_usage_cert_sign_bit_set", + Description: "Subscriber Certificate: keyUsage if present, bit positions for keyCertSign and cRLSign MUST NOT be set.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCertKeyUsageBitSet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_crl_sign_bit_set.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_crl_sign_bit_set.go new file mode 100644 index 0000000000..a434ba4b44 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_key_usage_crl_sign_bit_set.go @@ -0,0 +1,56 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************** +BRs: 7.1.2.3 +keyUsage (optional) +If present, bit positions for keyCertSign and cRLSign MUST NOT be set. +***************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCrlSignAllowed struct{} + +func (l *subCrlSignAllowed) Initialize() error { + return nil +} + +func (l *subCrlSignAllowed) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) && !util.IsCACert(c) +} + +func (l *subCrlSignAllowed) Execute(c *x509.Certificate) *lint.LintResult { + if (c.KeyUsage & x509.KeyUsageCRLSign) == x509.KeyUsageCRLSign { + return &lint.LintResult{Status: lint.Error} + } else { //key usage doesn't allow cert signing or isn't present + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_key_usage_crl_sign_bit_set", + Description: "Subscriber Certificate: keyUsage if present, bit positions for keyCertSign and cRLSign MUST NOT be set.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subCrlSignAllowed{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_appear.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_appear.go new file mode 100644 index 0000000000..b2b96e0e75 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_appear.go @@ -0,0 +1,53 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertLocalityNameMustAppear struct{} + +func (l *subCertLocalityNameMustAppear) Initialize() error { + return nil +} + +func (l *subCertLocalityNameMustAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertLocalityNameMustAppear) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.Organization) > 0 || len(c.Subject.GivenName) > 0 || len(c.Subject.Surname) > 0 { + if len(c.Subject.Province) == 0 { + if len(c.Subject.Locality) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_locality_name_must_appear", + Description: "Subscriber Certificate: subject:localityName MUST appear if subject:organizationName, subject:givenName, or subject:surname fields are present but the subject:stateOrProvinceName field is absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertLocalityNameMustAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_not_appear.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_not_appear.go new file mode 100644 index 0000000000..ebe4d65049 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_locality_name_must_not_appear.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertLocalityNameMustNotAppear struct{} + +func (l *subCertLocalityNameMustNotAppear) Initialize() error { + return nil +} + +func (l *subCertLocalityNameMustNotAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertLocalityNameMustNotAppear) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.Organization) == 0 && len(c.Subject.GivenName) == 0 && len(c.Subject.Surname) == 0 { + if len(c.Subject.Locality) > 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_locality_name_must_not_appear", + Description: "Subscriber Certificate: subject:localityName MUST NOT appear if subject:organizationName, subject:givenName, and subject:surname fields are absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertLocalityNameMustNotAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_or_sub_ca_using_sha1.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_or_sub_ca_using_sha1.go new file mode 100644 index 0000000000..dcd961ef5c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_or_sub_ca_using_sha1.go @@ -0,0 +1,54 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************** +BRs: 7.1.3 +SHA‐1 MAY be used with RSA keys in accordance with the criteria defined in Section 7.1.3. +**************************************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type sigAlgTestsSHA1 struct{} + +func (l *sigAlgTestsSHA1) Initialize() error { + return nil +} + +func (l *sigAlgTestsSHA1) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *sigAlgTestsSHA1) Execute(c *x509.Certificate) *lint.LintResult { + if c.SignatureAlgorithm == x509.SHA1WithRSA || c.SignatureAlgorithm == x509.DSAWithSHA1 || c.SignatureAlgorithm == x509.ECDSAWithSHA1 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_or_sub_ca_using_sha1", + Description: "CAs MUST NOT issue any new Subscriber certificates or Subordinate CA certificates using SHA-1 after 1 January 2016", + Citation: "BRs: 7.1.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.NO_SHA1, + Lint: &sigAlgTestsSHA1{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_postal_code_prohibited.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_postal_code_prohibited.go new file mode 100644 index 0000000000..ed43e1a06b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_postal_code_prohibited.go @@ -0,0 +1,52 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertPostalCodeMustNotAppear struct{} + +func (l *subCertPostalCodeMustNotAppear) Initialize() error { + return nil +} + +func (l *subCertPostalCodeMustNotAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertPostalCodeMustNotAppear) Execute(c *x509.Certificate) *lint.LintResult { + // BR 7.1.4.2.2 uses "or" and "and" interchangeably when they mean "and". + if len(c.Subject.Organization) == 0 && len(c.Subject.GivenName) == 0 && len(c.Subject.Surname) == 0 { + if len(c.Subject.PostalCode) > 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_postal_code_must_not_appear", + Description: "Subscriber Certificate: subject:postalCode MUST NOT appear if the subject:organizationName field, subject:givenName field, or subject:surname fields are absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertPostalCodeMustNotAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_appear.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_appear.go new file mode 100644 index 0000000000..21493e805e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_appear.go @@ -0,0 +1,53 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertProvinceMustAppear struct{} + +func (l *subCertProvinceMustAppear) Initialize() error { + return nil +} + +func (l *subCertProvinceMustAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertProvinceMustAppear) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.Organization) > 0 || len(c.Subject.GivenName) > 0 || len(c.Subject.Surname) > 0 { + if len(c.Subject.Locality) == 0 { + if len(c.Subject.Province) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_province_must_appear", + Description: "Subscriber Certificate: subject:stateOrProvinceName MUST appear if the subject:organizationName, subject:givenName, or subject:surname fields are present and subject:localityName is absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertProvinceMustAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_not_appear.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_not_appear.go new file mode 100644 index 0000000000..4dddc7c115 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_province_must_not_appear.go @@ -0,0 +1,51 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertProvinceMustNotAppear struct{} + +func (l *subCertProvinceMustNotAppear) Initialize() error { + return nil +} + +func (l *subCertProvinceMustNotAppear) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertProvinceMustNotAppear) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.Organization) == 0 && len(c.Subject.GivenName) == 0 && len(c.Subject.Surname) == 0 { + if len(c.Subject.Province) > 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_province_must_not_appear", + Description: "Subscriber Certificate: subject:stateOrProvinceName MUST NOT appear if the subject:organizationName, subject:givenName, and subject:surname fields are absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertProvinceMustNotAppear{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_sha1_expiration_too_long.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_sha1_expiration_too_long.go new file mode 100644 index 0000000000..123607fc16 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_sha1_expiration_too_long.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*************************************************************************************************************** +Effective 16 January 2015, CAs SHOULD NOT issue Subscriber Certificates utilizing the SHA‐1 algorithm with +an Expiry Date greater than 1 January 2017 because Application Software Providers are in the process of +deprecating and/or removing the SHA‐1 algorithm from their software, and they have communicated that +CAs and Subscribers using such certificates do so at their own risk. +****************************************************************************************************************/ + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type sha1ExpireLong struct{} + +func (l *sha1ExpireLong) Initialize() error { + return nil +} + +func (l *sha1ExpireLong) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) && (c.SignatureAlgorithm == x509.SHA1WithRSA || + c.SignatureAlgorithm == x509.DSAWithSHA1 || + c.SignatureAlgorithm == x509.ECDSAWithSHA1) +} + +func (l *sha1ExpireLong) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotAfter.After(time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC)) { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_sub_cert_sha1_expiration_too_long", + Description: "Subscriber certificates using the SHA-1 algorithm SHOULD NOT have an expiration date later than 1 Jan 2017", + Citation: "BRs: 7.1.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: time.Date(2015, time.January, 16, 0, 0, 0, 0, time.UTC), + Lint: &sha1ExpireLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_street_address_should_not_exist.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_street_address_should_not_exist.go new file mode 100644 index 0000000000..a2ea09d11e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_street_address_should_not_exist.go @@ -0,0 +1,52 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertStreetAddressShouldNotExist struct{} + +func (l *subCertStreetAddressShouldNotExist) Initialize() error { + return nil +} + +func (l *subCertStreetAddressShouldNotExist) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertStreetAddressShouldNotExist) Execute(c *x509.Certificate) *lint.LintResult { + //If all fields are absent + if len(c.Subject.Organization) == 0 && len(c.Subject.GivenName) == 0 && len(c.Subject.Surname) == 0 { + if len(c.Subject.StreetAddress) > 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_street_address_should_not_exist", + Description: "Subscriber Certificate: subject:streetAddress MUST NOT appear if subject:organizationName, subject:givenName, and subject:surname fields are absent.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABGivenNameDate, + Lint: &subCertStreetAddressShouldNotExist{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_39_months.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_39_months.go new file mode 100644 index 0000000000..3c2a1d4cec --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_39_months.go @@ -0,0 +1,49 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertValidTimeLongerThan39Months struct{} + +func (l *subCertValidTimeLongerThan39Months) Initialize() error { + return nil +} + +func (l *subCertValidTimeLongerThan39Months) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertValidTimeLongerThan39Months) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotBefore.AddDate(0, 39, 0).Before(c.NotAfter) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_valid_time_longer_than_39_months", + Description: "Subscriber Certificates issued after 1 July 2016 but prior to 1 March 2018 MUST have a Validity Period no greater than 39 months.", + Citation: "BRs: 6.3.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SubCert39Month, + Lint: &subCertValidTimeLongerThan39Months{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_825_days.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_825_days.go new file mode 100644 index 0000000000..6cdd5618ed --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_sub_cert_valid_time_longer_than_825_days.go @@ -0,0 +1,49 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subCertValidTimeLongerThan825Days struct{} + +func (l *subCertValidTimeLongerThan825Days) Initialize() error { + return nil +} + +func (l *subCertValidTimeLongerThan825Days) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *subCertValidTimeLongerThan825Days) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotBefore.AddDate(0, 0, 825).Before(c.NotAfter) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_sub_cert_valid_time_longer_than_825_days", + Description: "Subscriber Certificates issued after 1 March 2018 MUST have a Validity Period no greater than 825 days.", + Citation: "BRs: 6.3.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SubCert825Days, + Lint: &subCertValidTimeLongerThan825Days{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_included.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_included.go new file mode 100644 index 0000000000..cd05e5d2d9 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_included.go @@ -0,0 +1,55 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*************************************************************** +BRs: 7.1.4.2.2 +Required/Optional: Deprecated (Discouraged, but not prohibited) +***************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type commonNames struct{} + +func (l *commonNames) Initialize() error { + return nil +} + +func (l *commonNames) CheckApplies(c *x509.Certificate) bool { + return !util.IsCACert(c) +} + +func (l *commonNames) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName == "" { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Notice} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_subject_common_name_included", + Description: "Subscriber Certificate: commonName is deprecated.", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &commonNames{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_not_from_san.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_not_from_san.go new file mode 100644 index 0000000000..bb66370828 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_common_name_not_from_san.go @@ -0,0 +1,69 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.4.2.2 +If present, this field MUST contain a single IP address +or Fully‐Qualified Domain Name that is one of the values +contained in the Certificate’s subjectAltName extension (see Section 7.1.4.2.1). +************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectCommonNameNotFromSAN struct{} + +func (l *subjectCommonNameNotFromSAN) Initialize() error { + return nil +} + +func (l *subjectCommonNameNotFromSAN) CheckApplies(c *x509.Certificate) bool { + return c.Subject.CommonName != "" && !util.IsCACert(c) +} + +func (l *subjectCommonNameNotFromSAN) Execute(c *x509.Certificate) *lint.LintResult { + cn := c.Subject.CommonName + + for _, dn := range c.DNSNames { + if strings.EqualFold(cn, dn) { + return &lint.LintResult{Status: lint.Pass} + } + } + + for _, ip := range c.IPAddresses { + if cn == ip.String() { + return &lint.LintResult{Status: lint.Pass} + } + } + + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_common_name_not_from_san", + Description: "The common name field in subscriber certificates must include only names from the SAN extension", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subjectCommonNameNotFromSAN{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_malformed_arpa_ip.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_malformed_arpa_ip.go new file mode 100644 index 0000000000..496e69f657 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_malformed_arpa_ip.go @@ -0,0 +1,150 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_br + +import ( + "fmt" + "net" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +// arpaMalformedIP is a linter that warns for malformed names under the +// .in-addr.arpa or .ip6.arpa zones. +// See also: lint_subject_contains_reserved_arpa_ip.go for a lint that ensures +// well formed rDNS names in these zones do not specify an address in a IANA +// reserved network. +type arpaMalformedIP struct{} + +// Initialize for an arpaMalformedIP linter is a NOP to statisfy linting +// interfaces. +func (l *arpaMalformedIP) Initialize() error { + return nil +} + +// CheckApplies returns true if the certificate contains any names that end in +// one of the two designated zones for reverse DNS: in-addr.arpa or ip6.arpa. +func (l *arpaMalformedIP) CheckApplies(c *x509.Certificate) bool { + names := append([]string{c.Subject.CommonName}, c.DNSNames...) + for _, name := range names { + name = strings.ToLower(name) + if strings.HasSuffix(name, rdnsIPv4Suffix) || + strings.HasSuffix(name, rdnsIPv6Suffix) { + return true + } + } + return false +} + +// Execute will check the given certificate to ensure that all of the DNS +// subject alternate names that specify a reverse DNS name under the respective +// IPv4 or IPv6 arpa zones are well formed. A lint.Warn lint.LintResult is returned if +// the name is in a reverse DNS zone but has the wrong number of labels. +func (l *arpaMalformedIP) Execute(c *x509.Certificate) *lint.LintResult { + for _, name := range c.DNSNames { + name = strings.ToLower(name) + var err error + if strings.HasSuffix(name, rdnsIPv4Suffix) { + // If the name has the in-addr.arpa suffix then it should be an IPv4 reverse + // DNS name. + err = lintReversedIPAddressLabels(name, false) + } else if strings.HasSuffix(name, rdnsIPv6Suffix) { + // If the name has the ip6.arpa suffix then it should be an IPv6 reverse + // DNS name. + err = lintReversedIPAddressLabels(name, true) + } + // Return the first error as a negative lint result + if err != nil { + return &lint.LintResult{ + Status: lint.Warn, + Details: err.Error(), + } + } + } + + return &lint.LintResult{ + Status: lint.Pass, + } +} + +// lintReversedIPAddressLabels lints the given name as either a reversed IPv4 or +// IPv6 address under the respective ARPA zone based on the address class. An +// error is returned if there aren't enough labels in the name after removing +// the relevant arpa suffix. +func lintReversedIPAddressLabels(name string, ipv6 bool) error { + numRequiredLabels := rdnsIPv4Labels + zoneSuffix := rdnsIPv4Suffix + + if ipv6 { + numRequiredLabels = rdnsIPv6Labels + zoneSuffix = rdnsIPv6Suffix + } + + // Strip off the zone suffix to get only the reversed IP address + ipName := strings.TrimSuffix(name, zoneSuffix) + + // A well encoded IPv4 or IPv6 reverse DNS name will have the correct number + // of labels to express the address + ipLabels := strings.Split(ipName, ".") + if len(ipLabels) != numRequiredLabels { + return fmt.Errorf( + "name %q has too few leading labels (%d vs %d) to be a reverse DNS entry "+ + "in the %q zone.", + name, len(ipLabels), numRequiredLabels, zoneSuffix) + } + + // Reverse the IP labels and try to parse an IP address + var ip net.IP + if ipv6 { + ip = reversedLabelsToIPv6(ipLabels) + } else { + ip = reversedLabelsToIPv4(ipLabels) + } + + // If the result isn't an IP then a warning should be generated + if ip == nil { + return fmt.Errorf( + "the first %d labels of name %q did not parse as a reversed IP address", + numRequiredLabels, name) + } + + // Otherwise return no error - checking the actual value of the IP is left to + // `lint_subject_contains_reserved_arpa_ip.go`. + return nil +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_subject_contains_malformed_arpa_ip", + Description: "Checks no subject domain name contains a rDNS entry in the " + + "registry-controlled .arpa zone with the wrong number of labels, or " + + "an invalid IP address (RFC 3596, BCP49)", + // NOTE(@cpu): 3.2.2.6 is particular to wildcard domain validation for names + // in a registry controlled zone (like .arpa), which would be an appropriate + // citation for when this lint finds a rDNS entry with the wrong + // number of labels/invalid IP because of the presence of a wildcard + // character. There is a larger on-going discussion[0] on the BRs stance on + // the .arpa zone entries that may produce a better citation to use here. + // + // [0]: https://github.com/cabforum/documents/issues/153 + Citation: "BRs: 3.2.2.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &arpaMalformedIP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_noninformational_value.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_noninformational_value.go new file mode 100644 index 0000000000..52ec2c5dc2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_noninformational_value.go @@ -0,0 +1,80 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************************************************************** +BRs: 7.1.4.2.2 +Other Subject Attributes +With the exception of the subject:organizationalUnitName (OU) attribute, optional attributes, when present within +the subject field, MUST contain information that has been verified by the CA. Metadata such as ‘.’, ‘-‘, and ‘ ‘ (i.e. +space) characters, and/or any other indication that the value is absent, incomplete, or not applicable, SHALL NOT +be used. +**********************************************************************************************************************/ + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type illegalChar struct{} + +func (l *illegalChar) Initialize() error { + return nil +} + +func (l *illegalChar) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *illegalChar) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Names { + value, ok := j.Value.(string) + if !ok { + continue + } + + if !checkAlphaNumericOrUTF8Present(value) { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("found only metadata %s in subjectDN attribute %s", value, j.Type.String())} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_contains_noninformational_value", + Description: "Subject name fields must not contain '.','-',' ' or any other indication that the field has been omitted", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &illegalChar{}, + }) +} + +// checkAlphaNumericOrUTF8Present checks if input string contains at least one occurrence of [a-Z0-9] or +// a UTF8 rune outside of ascii table +func checkAlphaNumericOrUTF8Present(input string) bool { + for _, r := range input { + if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r > 127 { + return true + } + } + + return false +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_arpa_ip.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_arpa_ip.go new file mode 100644 index 0000000000..34b2292bfb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_arpa_ip.go @@ -0,0 +1,233 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_br + +import ( + "fmt" + "net" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +const ( + // arpaTLD holds a string constant for the .arpa TLD + arpaTLD = ".arpa" + + // rdnsIPv4Suffix is the expected suffix for IPv4 reverse DNS names as + // specified in https://tools.ietf.org/html/rfc1035#section-3.5 + rdnsIPv4Suffix = ".in-addr" + arpaTLD + // rndsIPv4Labels is the expected number of labels for an IPv4 reverse DNS + // name (not counting the rdnsIPv4Suffix labels). IPv4 addresses are four + // bytes. RFC 1035 uses one byte per label meaning there are 4 expected labels + // under the rdnsIPv4Suffix. + rdnsIPv4Labels = 4 + + // rdnsIPv6Suffix is the expected suffix for IPv6 reverse DNS names as + // specified in https://tools.ietf.org/html/rfc3596#section-2.5 + rdnsIPv6Suffix = ".ip6" + arpaTLD + // rndsIPv6Labels is the expected number of labels for an IPv6 reverse DNS + // name (not counting the rdnsIPv6Suffix labels). IPv6 addresses are 16 bytes. + // RFC 3596 Sec 2.5 uses one *nibble* per label meaning there are 16*2 + // expected labels under the rdnsIPv6Suffix. + rdnsIPv6Labels = 32 +) + +// arpaReservedIP is a linter that errors for any well formed rDNS names in the +// .in-addr.arpa or .ip6.arpa zones that specify an address in an IANA reserved +// network. +// See also: lint_subject_contains_malformed_arpa_ip.go for a lint that warns +// about malformed rDNS names in these zones. +type arpaReservedIP struct{} + +// Initialize for an arpaReservedIP linter is a NOP to statisfy linting +// interfaces. +func (l *arpaReservedIP) Initialize() error { + return nil +} + +// CheckApplies returns true if the certificate contains any names that end in +// one of the two designated zones for reverse DNS: in-addr.arpa or ip6.arpa. +func (l *arpaReservedIP) CheckApplies(c *x509.Certificate) bool { + names := append([]string{c.Subject.CommonName}, c.DNSNames...) + for _, name := range names { + name = strings.ToLower(name) + if strings.HasSuffix(name, rdnsIPv4Suffix) || + strings.HasSuffix(name, rdnsIPv6Suffix) { + return true + } + } + return false +} + +// Execute will check the given certificate to ensure that all of the DNS +// subject alternate names that specify a well formed reverse DNS name under the +// respective IPv4 or IPv6 arpa zones do not specify an IP in an IANA +// reserved IP space. An lint.Error lint.LintResult is returned if the name specifies an +// IP address of the wrong class, or specifies an IP address in an IANA reserved +// network. +func (l *arpaReservedIP) Execute(c *x509.Certificate) *lint.LintResult { + for _, name := range c.DNSNames { + name = strings.ToLower(name) + var err error + if strings.HasSuffix(name, rdnsIPv4Suffix) { + // If the name has the in-addr.arpa suffix then it should be an IPv4 reverse + // DNS name. + err = lintReversedIPAddress(name, false) + } else if strings.HasSuffix(name, rdnsIPv6Suffix) { + // If the name has the ip6.arpa suffix then it should be an IPv6 reverse + // DNS name. + err = lintReversedIPAddress(name, true) + } + // Return the first error as a negative lint result + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: err.Error(), + } + } + } + + return &lint.LintResult{ + Status: lint.Pass, + } +} + +// reversedLabelsToIPv4 reverses the provided labels (assumed to be 4 labels, +// one per byte of the IPv6 address) and constructs an IPv4 address, returning +// the result of calling net.ParseIP for the constructed address. +func reversedLabelsToIPv4(labels []string) net.IP { + var buf strings.Builder + + // If there aren't the right number of labels, it isn't an IPv4 address. + if len(labels) != rdnsIPv4Labels { + return nil + } + + // An IPv4 address is represented as four groups of bytes separated by '.' + for i := len(labels) - 1; i >= 0; i-- { + buf.WriteString(labels[i]) + if i != 0 { + buf.WriteString(".") + } + } + return net.ParseIP(buf.String()) +} + +// reversedLabelsToIPv6 reverses the provided labels (assumed to be 32 labels, +// one per nibble of an IPv6 address) and constructs an IPv6 address, returning +// the result of calling net.ParseIP for the constructed address. +func reversedLabelsToIPv6(labels []string) net.IP { + var buf strings.Builder + + // If there aren't the right number of labels, it isn't an IPv6 address. + if len(labels) != rdnsIPv6Labels { + return nil + } + + // An IPv6 address is represented as eight groups of two bytes separated + // by `:` in hex form. Since each label in the rDNS form is one nibble we need + // four label components per IPv6 address component group. + for i := len(labels) - 1; i >= 0; i -= 4 { + buf.WriteString(labels[i]) + buf.WriteString(labels[i-1]) + buf.WriteString(labels[i-2]) + buf.WriteString(labels[i-3]) + if i > 4 { + buf.WriteString(":") + } + } + return net.ParseIP(buf.String()) +} + +// lintReversedIPAddress lints the given name as either a reversed IPv4 or IPv6 +// address under the respective ARPA zone based on the address class. An error +// is returned if: +// +// 1. The IP address labels parse as an IP of the wrong address class for the +// arpa suffix the name is using. +// 2. The IP address is within an IANA reserved range. +func lintReversedIPAddress(name string, ipv6 bool) error { + numRequiredLabels := rdnsIPv4Labels + zoneSuffix := rdnsIPv4Suffix + + if ipv6 { + numRequiredLabels = rdnsIPv6Labels + zoneSuffix = rdnsIPv6Suffix + } + + // Strip off the zone suffix to get only the reversed IP address + ipName := strings.TrimSuffix(name, zoneSuffix) + + // A well encoded IPv4 or IPv6 reverse DNS name will have the correct number + // of labels to express the address. If there isn't the right number of labels + // a separate `lint_subject_contains_malformed_arpa_ip.go` linter will flag it + // as a warning. This linter is specifically concerned with well formed rDNS + // that specifies a reserved IP. + ipLabels := strings.Split(ipName, ".") + if len(ipLabels) != numRequiredLabels { + return nil + } + + // Reverse the IP labels and try to parse an IP address + var ip net.IP + if ipv6 { + ip = reversedLabelsToIPv6(ipLabels) + } else { + ip = reversedLabelsToIPv4(ipLabels) + } + // If the result isn't an IP at all assume there is no problem - leave + // `lint_subject_contains_malformed_arpa_ip` to flag it as a warning. + if ip == nil { + return nil + } + + if !ipv6 && ip.To4() == nil { + // If we weren't expecting IPv6 and got it, that's a problem + return fmt.Errorf( + "the first %d labels of name %q parsed as a reversed IPv6 address but is "+ + "in the %q IPv4 reverse DNS zone.", + numRequiredLabels, name, rdnsIPv4Suffix) + } else if ipv6 && ip.To4() != nil { + // If we were expecting IPv6 and got an IPv4 address, that's a problem + return fmt.Errorf( + "the first %d labels of name %q parsed as a reversed IPv4 address but is "+ + "in the %q IPv4 reverse DNS zone.", + numRequiredLabels, name, rdnsIPv6Suffix) + } + + // If the IP address is in an IANA reserved space, that's a problem. + if util.IsIANAReserved(ip) { + return fmt.Errorf( + "the first %d labels of name %q parsed as a reversed IP address in "+ + "an IANA reserved IP space.", + numRequiredLabels, name) + } + + return nil +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_contains_reserved_arpa_ip", + Description: "Checks no subject domain name contains a rDNS entry in an .arpa zone specifying a reserved IP address", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &arpaReservedIP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_ip.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_ip.go new file mode 100644 index 0000000000..71f48c5e69 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_contains_reserved_ip.go @@ -0,0 +1,60 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +BRs: 7.1.4.2.1 +Also as of the Effective Date, the CA SHALL NOT +issue a certificate with an Expiry Date later than +1 November 2015 with a subjectAlternativeName extension +or Subject commonName field containing a Reserved IP +Address or Internal Name. +************************************************/ + +import ( + "net" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectReservedIP struct{} + +func (l *subjectReservedIP) Initialize() error { + return nil +} + +func (l *subjectReservedIP) CheckApplies(c *x509.Certificate) bool { + return c.NotAfter.After(util.NoReservedIP) +} + +func (l *subjectReservedIP) Execute(c *x509.Certificate) *lint.LintResult { + if ip := net.ParseIP(c.Subject.CommonName); ip != nil && util.IsIANAReserved(ip) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_contains_reserved_ip", + Description: "Certificates expiring later than 11 Jan 2015 MUST NOT contain a reserved IP address in the common name field", + Citation: "BRs: 7.1.4.2.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &subjectReservedIP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_country_not_iso.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_country_not_iso.go new file mode 100644 index 0000000000..fa6468c87a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_br/lint_subject_country_not_iso.go @@ -0,0 +1,61 @@ +package cabf_br + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************************************************** +BRs: 7.1.4.2.2 +Certificate Field: issuer:countryName (OID 2.5.4.6) +Required/Optional: Required +Contents: This field MUST contain the two-letter ISO 3166-1 country code for the country in which the issuer’s +place of business is located. +**************************************************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type countryNotIso struct{} + +func (l *countryNotIso) Initialize() error { + return nil +} + +func (l *countryNotIso) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *countryNotIso) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Country { + if !util.IsISOCountryCode(strings.ToUpper(j)) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_country_not_iso", + Description: "The country name field MUST contain the two-letter ISO code for the country or XX", + Citation: "BRs: 7.1.4.2.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + Lint: &countryNotIso{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_business_category_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_business_category_missing.go new file mode 100644 index 0000000000..e35d2e70c4 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_business_category_missing.go @@ -0,0 +1,50 @@ +package cabf_ev + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type evNoBiz struct{} + +func (l *evNoBiz) Initialize() error { + return nil +} + +func (l *evNoBiz) CheckApplies(c *x509.Certificate) bool { + return util.IsEV(c.PolicyIdentifiers) && util.IsSubscriberCert(c) +} + +func (l *evNoBiz) Execute(c *x509.Certificate) *lint.LintResult { + if util.TypeInName(&c.Subject, util.BusinessOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ev_business_category_missing", + Description: "EV certificates must include businessCategory in subject", + Citation: "EVGs: 9.2.3", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + Lint: &evNoBiz{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_country_name_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_country_name_missing.go new file mode 100644 index 0000000000..2d8998bb76 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_country_name_missing.go @@ -0,0 +1,50 @@ +package cabf_ev + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type evCountryMissing struct{} + +func (l *evCountryMissing) Initialize() error { + return nil +} + +func (l *evCountryMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsEV(c.PolicyIdentifiers) && util.IsSubscriberCert(c) +} + +func (l *evCountryMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.TypeInName(&c.Subject, util.CountryNameOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ev_country_name_missing", + Description: "EV certificates must include countryName in subject", + Citation: "EVGs: 9.2.4", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + Lint: &evCountryMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_organization_name_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_organization_name_missing.go new file mode 100644 index 0000000000..88ca41ff94 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_organization_name_missing.go @@ -0,0 +1,50 @@ +package cabf_ev + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type evOrgMissing struct{} + +func (l *evOrgMissing) Initialize() error { + return nil +} + +func (l *evOrgMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsEV(c.PolicyIdentifiers) && util.IsSubscriberCert(c) +} + +func (l *evOrgMissing) Execute(c *x509.Certificate) *lint.LintResult { + if util.TypeInName(&c.Subject, util.OrganizationNameOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ev_organization_name_missing", + Description: "EV certificates must include organizationName in subject", + Citation: "EVGs: 9.2.1", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + Lint: &evOrgMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_serial_number_missing.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_serial_number_missing.go new file mode 100644 index 0000000000..ff95e2927c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_serial_number_missing.go @@ -0,0 +1,49 @@ +package cabf_ev + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type evSNMissing struct{} + +func (l *evSNMissing) Initialize() error { + return nil +} + +func (l *evSNMissing) CheckApplies(c *x509.Certificate) bool { + return util.IsEV(c.PolicyIdentifiers) && util.IsSubscriberCert(c) +} + +func (l *evSNMissing) Execute(c *x509.Certificate) *lint.LintResult { + if len(c.Subject.SerialNumber) == 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ev_serial_number_missing", + Description: "EV certificates must include serialNumber in subject", + Citation: "EVGs: 9.2.6", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + Lint: &evSNMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_valid_time_too_long.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_valid_time_too_long.go new file mode 100644 index 0000000000..a0ec4d76c3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_ev_valid_time_too_long.go @@ -0,0 +1,54 @@ +package cabf_ev + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type evValidTooLong struct{} + +func (l *evValidTooLong) Initialize() error { + return nil +} + +func (l *evValidTooLong) CheckApplies(c *x509.Certificate) bool { + // CA/Browser Forum Ballot 193 changed the maximum validity period to be + // 825 days, which is more permissive than 27-month certificates, as that + // is 823 days. + return c.NotBefore.Before(util.SubCert825Days) && + util.IsSubscriberCert(c) && + util.IsEV(c.PolicyIdentifiers) +} + +func (l *evValidTooLong) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotBefore.AddDate(0, 27, 0).Before(c.NotAfter) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ev_valid_time_too_long", + Description: "EV certificates must be 27 months in validity or less", + Citation: "EVGs 1.0: 8(a), EVGs 1.6.1: 9.4", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + Lint: &evValidTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_onion_subject_validity_time_too_large.go b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_onion_subject_validity_time_too_large.go new file mode 100644 index 0000000000..cfe792aa91 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/cabf_ev/lint_onion_subject_validity_time_too_large.go @@ -0,0 +1,69 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package cabf_ev + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +const ( + // Ballot 144 specified: + // CAs MUST NOT issue a Certificate that includes a Domain Name where .onion + // is in the right-most label of the Domain Name with a validity period longer + // than 15 months + maxOnionValidityMonths = 15 +) + +type torValidityTooLarge struct{} + +// Initialize for a torValidityTooLarge linter is a NOP. +func (l *torValidityTooLarge) Initialize() error { + return nil +} + +// CheckApplies returns true if the certificate is a subscriber certificate that +// contains a subject name ending in `.onion`. +func (l *torValidityTooLarge) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.CertificateSubjInTLD(c, util.OnionTLD) +} + +// Execute will return an lint.Error lint.LintResult if the provided certificate has +// a validity period longer than the maximum allowed validity for a certificate +// with a .onion subject. +func (l *torValidityTooLarge) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotBefore.AddDate(0, maxOnionValidityMonths, 0).Before(c.NotAfter) { + return &lint.LintResult{ + Status: lint.Error, + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_onion_subject_validity_time_too_large", + Description: fmt.Sprintf( + "certificates with .onion names can not be valid for more than %d months", + maxOnionValidityMonths), + Citation: "EVGs: Appendix F", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.OnionOnlyEVDate, + Lint: &torValidityTooLarge{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_bare_wildcard.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_bare_wildcard.go new file mode 100644 index 0000000000..a7750c7b95 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_bare_wildcard.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type brIANBareWildcard struct{} + +func (l *brIANBareWildcard) Initialize() error { + return nil +} + +func (l *brIANBareWildcard) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *brIANBareWildcard) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + if strings.HasSuffix(dns, "*") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ian_bare_wildcard", + Description: "A wildcard MUST be accompanied by other data to its right (Only checks IANDNSNames)", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &brIANBareWildcard{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_includes_null_char.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_includes_null_char.go new file mode 100644 index 0000000000..8e49a5877d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_includes_null_char.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANDNSNull struct{} + +func (l *IANDNSNull) Initialize() error { + return nil +} + +func (l *IANDNSNull) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANDNSNull) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + for i := 0; i < len(dns); i++ { + if dns[i] == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ian_dns_name_includes_null_char", + Description: "DNSName MUST NOT include a null character", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IANDNSNull{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_starts_with_period.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_starts_with_period.go new file mode 100644 index 0000000000..ecfb398101 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_dns_name_starts_with_period.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANDNSPeriod struct{} + +func (l *IANDNSPeriod) Initialize() error { + return nil +} + +func (l *IANDNSPeriod) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANDNSPeriod) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + if strings.HasPrefix(dns, ".") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ian_dns_name_starts_with_period", + Description: "DNSName MUST NOT start with a period", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IANDNSPeriod{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_iana_pub_suffix_empty.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_iana_pub_suffix_empty.go new file mode 100644 index 0000000000..692eeea85b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_iana_pub_suffix_empty.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANPubSuffix struct{} + +func (l *IANPubSuffix) Initialize() error { + return nil +} + +func (l *IANPubSuffix) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANPubSuffix) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + if len(strings.Split(dns, ".")) < 3 { + return &lint.LintResult{Status: lint.Warn} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ian_iana_pub_suffix_empty", + Description: "Domain SHOULD NOT have a bare public suffix", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IANPubSuffix{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_wildcard_not_first.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_wildcard_not_first.go new file mode 100644 index 0000000000..1ca41b05b5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_ian_wildcard_not_first.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type brIANWildcardFirst struct{} + +func (l *brIANWildcardFirst) Initialize() error { + return nil +} + +func (l *brIANWildcardFirst) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *brIANWildcardFirst) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + for i := 1; i < len(dns); i++ { + if dns[i] == '*' { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ian_wildcard_not_first", + Description: "A wildcard MUST be in the first label of FQDN (ie not: www.*.com) (Only checks IANDNSNames)", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &brIANWildcardFirst{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_is_redacted_cert.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_is_redacted_cert.go new file mode 100644 index 0000000000..db5ce60676 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_is_redacted_cert.go @@ -0,0 +1,63 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type DNSNameRedacted struct{} + +func (l *DNSNameRedacted) Initialize() error { + return nil +} + +func (l *DNSNameRedacted) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func isRedactedCertificate(domain string) bool { + domain = util.RemovePrependedWildcard(domain) + return strings.HasPrefix(domain, "?.") +} + +func (l *DNSNameRedacted) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.CommonName != "" { + if isRedactedCertificate(c.Subject.CommonName) { + return &lint.LintResult{Status: lint.Notice} + } + } + for _, domain := range c.DNSNames { + if isRedactedCertificate(domain) { + return &lint.LintResult{Status: lint.Notice} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_contains_redacted_dnsname", + Description: "Some precerts are redacted and of the form ?.?.a.com or *.?.a.com", + Source: lint.ZLint, + Citation: "IETF Draft: https://tools.ietf.org/id/draft-strad-trans-redaction-00.html", + EffectiveDate: util.ZeroDate, + Lint: &DNSNameRedacted{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_leading_whitespace.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_leading_whitespace.go new file mode 100644 index 0000000000..f8b9b59880 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_leading_whitespace.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IssuerDNLeadingSpace struct{} + +func (l *IssuerDNLeadingSpace) Initialize() error { + return nil +} + +func (l *IssuerDNLeadingSpace) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *IssuerDNLeadingSpace) Execute(c *x509.Certificate) *lint.LintResult { + leading, _, err := util.CheckRDNSequenceWhiteSpace(c.RawIssuer) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if leading { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_issuer_dn_leading_whitespace", + Description: "AttributeValue in issuer RelativeDistinguishedName sequence SHOULD NOT have leading whitespace", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IssuerDNLeadingSpace{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_trailing_whitespace.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_trailing_whitespace.go new file mode 100644 index 0000000000..106f873f90 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_dn_trailing_whitespace.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IssuerDNTrailingSpace struct{} + +func (l *IssuerDNTrailingSpace) Initialize() error { + return nil +} + +func (l *IssuerDNTrailingSpace) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *IssuerDNTrailingSpace) Execute(c *x509.Certificate) *lint.LintResult { + _, trailing, err := util.CheckRDNSequenceWhiteSpace(c.RawIssuer) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if trailing { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_issuer_dn_trailing_whitespace", + Description: "AttributeValue in issuer RelativeDistinguishedName sequence SHOULD NOT have trailing whitespace", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IssuerDNTrailingSpace{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_multiple_rdn.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_multiple_rdn.go new file mode 100644 index 0000000000..9e3d225f67 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_issuer_multiple_rdn.go @@ -0,0 +1,59 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IssuerRDNHasMultipleAttribute struct{} + +func (l *IssuerRDNHasMultipleAttribute) Initialize() error { + return nil +} + +func (l *IssuerRDNHasMultipleAttribute) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *IssuerRDNHasMultipleAttribute) Execute(c *x509.Certificate) *lint.LintResult { + var issuer pkix.RDNSequence + _, err := asn1.Unmarshal(c.RawIssuer, &issuer) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, rdn := range issuer { + if len(rdn) > 1 { + return &lint.LintResult{Status: lint.Warn} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_multiple_issuer_rdn", + Description: "Certificates should not have multiple attributes in a single RDN (issuer)", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &IssuerRDNHasMultipleAttribute{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_exp_negative.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_exp_negative.go new file mode 100644 index 0000000000..874f5b3e4e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_exp_negative.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaExpNegative struct{} + +func (l *rsaExpNegative) Initialize() error { + return nil +} + +func (l *rsaExpNegative) CheckApplies(c *x509.Certificate) bool { + _, ok := c.PublicKey.(*rsa.PublicKey) + return ok && c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaExpNegative) Execute(c *x509.Certificate) *lint.LintResult { + key := c.PublicKey.(*rsa.PublicKey) + if key.E < 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_rsa_exp_negative", + Description: "RSA public key exponent MUST be positive", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &rsaExpNegative{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_no_public_key.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_no_public_key.go new file mode 100644 index 0000000000..847e1b97d7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_rsa_no_public_key.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaParsedPubKeyExist struct{} + +func (l *rsaParsedPubKeyExist) Initialize() error { + return nil +} + +func (l *rsaParsedPubKeyExist) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.RSA +} + +func (l *rsaParsedPubKeyExist) Execute(c *x509.Certificate) *lint.LintResult { + _, ok := c.PublicKey.(*rsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_rsa_no_public_key", + Description: "The RSA public key should be present", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &rsaParsedPubKeyExist{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_bare_wildcard.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_bare_wildcard.go new file mode 100644 index 0000000000..d6dfa592fd --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_bare_wildcard.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type brSANBareWildcard struct{} + +func (l *brSANBareWildcard) Initialize() error { + return nil +} + +func (l *brSANBareWildcard) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *brSANBareWildcard) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + if strings.HasSuffix(dns, "*") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_bare_wildcard", + Description: "A wildcard MUST be accompanied by other data to its right (Only checks DNSName)", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &brSANBareWildcard{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_duplicate.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_duplicate.go new file mode 100644 index 0000000000..c03b7b10e6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_duplicate.go @@ -0,0 +1,58 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package community + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDNSDuplicate struct{} + +func (l *SANDNSDuplicate) Initialize() error { + return nil +} + +func (l *SANDNSDuplicate) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDNSDuplicate) Execute(c *x509.Certificate) *lint.LintResult { + checkedDNSNames := map[string]struct{}{} + for _, dns := range c.DNSNames { + normalizedDNSName := strings.ToLower(dns) + if _, isPresent := checkedDNSNames[normalizedDNSName]; isPresent { + return &lint.LintResult{Status: lint.Notice} + } + + checkedDNSNames[normalizedDNSName] = struct{}{} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_san_dns_name_duplicate", + Description: "SAN DNSName contains duplicate values", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SANDNSDuplicate{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_includes_null_char.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_includes_null_char.go new file mode 100644 index 0000000000..7a7ae4451f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_includes_null_char.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDNSNull struct{} + +func (l *SANDNSNull) Initialize() error { + return nil +} + +func (l *SANDNSNull) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDNSNull) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + for i := 0; i < len(dns); i++ { + if dns[i] == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_dns_name_includes_null_char", + Description: "DNSName MUST NOT include a null character", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SANDNSNull{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_starts_with_period.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_starts_with_period.go new file mode 100644 index 0000000000..92520c28ba --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_dns_name_starts_with_period.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDNSPeriod struct{} + +func (l *SANDNSPeriod) Initialize() error { + return nil +} + +func (l *SANDNSPeriod) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDNSPeriod) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + if strings.HasPrefix(dns, ".") { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_dns_name_starts_with_period", + Description: "DNSName MUST NOT start with a period", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SANDNSPeriod{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_iana_pub_suffix_empty.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_iana_pub_suffix_empty.go new file mode 100644 index 0000000000..07d8c3cbca --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_iana_pub_suffix_empty.go @@ -0,0 +1,58 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type pubSuffix struct{} + +func (l *pubSuffix) Initialize() error { + return nil +} + +func (l *pubSuffix) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *pubSuffix) Execute(c *x509.Certificate) *lint.LintResult { + parsedSANDNSNames := c.GetParsedDNSNames(false) + for i := range c.GetParsedDNSNames(false) { + if parsedSANDNSNames[i].ParseError != nil { + if strings.HasSuffix(parsedSANDNSNames[i].ParseError.Error(), "is a suffix") { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.NA} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_san_iana_pub_suffix_empty", + Description: "The domain SHOULD NOT have a bare public suffix", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &pubSuffix{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_wildcard_not_first.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_wildcard_not_first.go new file mode 100644 index 0000000000..085a85f12c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_san_wildcard_not_first.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANWildCardFirst struct{} + +func (l *SANWildCardFirst) Initialize() error { + return nil +} + +func (l *SANWildCardFirst) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANWildCardFirst) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + for i := 1; i < len(dns); i++ { + if dns[i] == '*' { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_san_wildcard_not_first", + Description: "A wildcard MUST be in the first label of FQDN (ie not: www.*.com) (Only checks DNSName)", + Citation: "awslabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SANWildCardFirst{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_leading_whitespace.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_leading_whitespace.go new file mode 100644 index 0000000000..7f3b35ef89 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_leading_whitespace.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectDNLeadingSpace struct{} + +func (l *SubjectDNLeadingSpace) Initialize() error { + return nil +} + +func (l *SubjectDNLeadingSpace) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *SubjectDNLeadingSpace) Execute(c *x509.Certificate) *lint.LintResult { + leading, _, err := util.CheckRDNSequenceWhiteSpace(c.RawSubject) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if leading { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_subject_dn_leading_whitespace", + Description: "AttributeValue in subject RelativeDistinguishedName sequence SHOULD NOT have leading whitespace", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SubjectDNLeadingSpace{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_trailing_whitespace.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_trailing_whitespace.go new file mode 100644 index 0000000000..35bc791d8c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_dn_trailing_whitespace.go @@ -0,0 +1,53 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectDNTrailingSpace struct{} + +func (l *SubjectDNTrailingSpace) Initialize() error { + return nil +} + +func (l *SubjectDNTrailingSpace) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *SubjectDNTrailingSpace) Execute(c *x509.Certificate) *lint.LintResult { + _, trailing, err := util.CheckRDNSequenceWhiteSpace(c.RawSubject) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if trailing { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_subject_dn_trailing_whitespace", + Description: "AttributeValue in subject RelativeDistinguishedName sequence SHOULD NOT have trailing whitespace", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SubjectDNTrailingSpace{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_multiple_rdn.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_multiple_rdn.go new file mode 100644 index 0000000000..0cdf1f7943 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_subject_multiple_rdn.go @@ -0,0 +1,58 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectRDNHasMultipleAttribute struct{} + +func (l *SubjectRDNHasMultipleAttribute) Initialize() error { + return nil +} + +func (l *SubjectRDNHasMultipleAttribute) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *SubjectRDNHasMultipleAttribute) Execute(c *x509.Certificate) *lint.LintResult { + var subject pkix.RDNSequence + if _, err := asn1.Unmarshal(c.RawSubject, &subject); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, rdn := range subject { + if len(rdn) > 1 { + return &lint.LintResult{Status: lint.Notice} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_multiple_subject_rdn", + Description: "Certificates typically do not have have multiple attributes in a single RDN (subject). This may be an error.", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SubjectRDNHasMultipleAttribute{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/community/lint_validity_time_not_positive.go b/vendor/github.com/zmap/zlint/v2/lints/community/lint_validity_time_not_positive.go new file mode 100644 index 0000000000..63a4901e52 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/community/lint_validity_time_not_positive.go @@ -0,0 +1,49 @@ +package community + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type validityNegative struct{} + +func (l *validityNegative) Initialize() error { + return nil +} + +func (l *validityNegative) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *validityNegative) Execute(c *x509.Certificate) *lint.LintResult { + if c.NotBefore.After(c.NotAfter) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_validity_time_not_positive", + Description: "Certificates MUST have a positive time for which they are valid", + Citation: "lint.AWSLabs certlint", + Source: lint.AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &validityNegative{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_present_qcs_critical.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_present_qcs_critical.go new file mode 100644 index 0000000000..2560300bbb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_present_qcs_critical.go @@ -0,0 +1,62 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcEtsiPresentQcsCritical struct{} + +func (l *qcStatemQcEtsiPresentQcsCritical) Initialize() error { + return nil +} + +func (l *qcStatemQcEtsiPresentQcsCritical) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.IsAnyEtsiQcStatementPresent(util.GetExtFromCert(c, util.QcStateOid).Value) { + return true + } + return false +} + +func (l *qcStatemQcEtsiPresentQcsCritical) Execute(c *x509.Certificate) *lint.LintResult { + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + if ext.Critical { + errString = "ETSI QC Statement is present and QC Statements extension is marked critical" + } + + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_etsi_present_qcs_critical", + Description: "Checks that a QC Statement which contains any of the id-etsi-qcs-... QC Statements is not marked critical", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.1", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcEtsiPresentQcsCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_type_as_statem.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_type_as_statem.go new file mode 100644 index 0000000000..3f769e8d39 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_etsi_type_as_statem.go @@ -0,0 +1,69 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemEtsiTypeAsStatem struct{} + +func (l *qcStatemEtsiTypeAsStatem) Initialize() error { + return nil +} + +func (l *qcStatemEtsiTypeAsStatem) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.QcStateOid) +} + +func (l *qcStatemEtsiTypeAsStatem) Execute(c *x509.Certificate) *lint.LintResult { + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + + oidList := make([]*asn1.ObjectIdentifier, 3) + oidList[0] = &util.IdEtsiQcsQctEsign + oidList[1] = &util.IdEtsiQcsQctEseal + oidList[2] = &util.IdEtsiQcsQctWeb + + for _, oid := range oidList { + r := util.ParseQcStatem(ext.Value, *oid) + util.AppendToStringSemicolonDelim(&errString, r.GetErrorInfo()) + if r.IsPresent() { + util.AppendToStringSemicolonDelim(&errString, fmt.Sprintf("ETSI QC Type OID %v used as QC statement", oid)) + } + } + + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_etsi_type_as_statem", + Description: "Checks for erroneous QC Statement OID that actually are represented by ETSI ESI QC type OID.", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.2.3", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemEtsiTypeAsStatem{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_mandatory_etsi_statems.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_mandatory_etsi_statems.go new file mode 100644 index 0000000000..6737cf368c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_mandatory_etsi_statems.go @@ -0,0 +1,72 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcmandatoryEtsiStatems struct{} + +func (l *qcStatemQcmandatoryEtsiStatems) Initialize() error { + return nil +} + +func (l *qcStatemQcmandatoryEtsiStatems) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.IsAnyEtsiQcStatementPresent(util.GetExtFromCert(c, util.QcStateOid).Value) { + return true + } + return false +} + +func (l *qcStatemQcmandatoryEtsiStatems) Execute(c *x509.Certificate) *lint.LintResult { + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + + oidList := make([]*asn1.ObjectIdentifier, 1) + oidList[0] = &util.IdEtsiQcsQcCompliance + + for _, oid := range oidList { + r := util.ParseQcStatem(ext.Value, *oid) + util.AppendToStringSemicolonDelim(&errString, r.GetErrorInfo()) + if !r.IsPresent() { + util.AppendToStringSemicolonDelim(&errString, "missing mandatory ETSI QC statement") + } + } + + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_mandatory_etsi_statems", + Description: "Checks that a QC Statement that contains at least one of the ETSI ESI statements, also features the set of mandatory ETSI ESI QC statements.", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 5", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcmandatoryEtsiStatems{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qccompliance_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qccompliance_valid.go new file mode 100644 index 0000000000..14f648a39d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qccompliance_valid.go @@ -0,0 +1,67 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcComplianceValid struct{} + +func (this *qcStatemQcComplianceValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcCompliance +} + +func (l *qcStatemQcComplianceValid) Initialize() error { + return nil +} + +func (l *qcStatemQcComplianceValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func (l *qcStatemQcComplianceValid) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qccompliance_valid", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcCompliance has the correct form", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.2.1", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcComplianceValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qclimitvalue_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qclimitvalue_valid.go new file mode 100644 index 0000000000..9d519701a5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qclimitvalue_valid.go @@ -0,0 +1,100 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "unicode" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcLimitValueValid struct{} + +func (this *qcStatemQcLimitValueValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcLimitValue +} + +func (l *qcStatemQcLimitValueValid) Initialize() error { + return nil +} + +func (l *qcStatemQcLimitValueValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func isOnlyLetters(s string) bool { + for _, r := range s { + if !unicode.IsLetter(r) { + return false + } + } + return true +} + +func (l *qcStatemQcLimitValueValid) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + qcLv, ok := s.(util.EtsiQcLimitValue) + if !ok { + return &lint.LintResult{Status: lint.Error, Details: "parsed QcStatem is not a EtsiQcLimitValue"} + } + if qcLv.Amount < 0 { + util.AppendToStringSemicolonDelim(&errString, "amount is negative") + } + if qcLv.IsNum { + if qcLv.CurrencyNum < 1 || qcLv.CurrencyNum > 999 { + util.AppendToStringSemicolonDelim(&errString, "numeric currency code is out of range") + } + } else { + if len(qcLv.CurrencyAlph) != 3 { + util.AppendToStringSemicolonDelim(&errString, "invalid string length of currency code") + } + if !isOnlyLetters(qcLv.CurrencyAlph) { + util.AppendToStringSemicolonDelim(&errString, "currency code string contains not only letters") + } + + } + + } + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qclimitvalue_valid", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcLimitValue has the correct form", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.3.2", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcLimitValueValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_lang_case.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_lang_case.go new file mode 100644 index 0000000000..130da2c9cb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_lang_case.go @@ -0,0 +1,91 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "fmt" + "unicode" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcPdsLangCase struct{} + +func (this *qcStatemQcPdsLangCase) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcEuPDS +} + +func (l *qcStatemQcPdsLangCase) Initialize() error { + return nil +} + +func (l *qcStatemQcPdsLangCase) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func isOnlyLowerCaseLetters(s string) bool { + for _, c := range s { + if !unicode.IsLower(c) { + return false + } + } + return true +} + +func (l *qcStatemQcPdsLangCase) Execute(c *x509.Certificate) *lint.LintResult { + errString := "" + wrnString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + pds := s.(util.EtsiQcPds) + for i, loc := range pds.PdsLocations { + if !isOnlyLowerCaseLetters(loc.Language) { + util.AppendToStringSemicolonDelim(&wrnString, fmt.Sprintf("PDS location %d has a language code containing invalid letters", i)) + } + + } + } + if len(errString) == 0 { + if len(wrnString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn, Details: wrnString} + } + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_qcstatem_qcpds_lang_case", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcPDS features a language code comprised of only lower case letters", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.3.4", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcPdsLangCase{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_valid.go new file mode 100644 index 0000000000..d066e3dfed --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcpds_valid.go @@ -0,0 +1,101 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "fmt" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcPdsValid struct{} + +func (this *qcStatemQcPdsValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcEuPDS +} + +func (l *qcStatemQcPdsValid) Initialize() error { + return nil +} + +func (l *qcStatemQcPdsValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func isInList(s string, list []string) bool { + for _, i := range list { + if strings.Compare(i, s) == 0 { + return true + } + } + return false +} + +func (l *qcStatemQcPdsValid) Execute(c *x509.Certificate) *lint.LintResult { + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + codeList := make([]string, 0) + foundEn := false + pds := s.(util.EtsiQcPds) + if len(pds.PdsLocations) == 0 { + util.AppendToStringSemicolonDelim(&errString, "PDS list is empty") + } + for i, loc := range pds.PdsLocations { + if len(loc.Language) != 2 { + util.AppendToStringSemicolonDelim(&errString, fmt.Sprintf("PDS location %d has a language code with an invalid length", i)) + } + if strings.Compare(strings.ToLower(loc.Language), "en") == 0 { + foundEn = true + } + if isInList(strings.ToLower(loc.Language), codeList) { + util.AppendToStringSemicolonDelim(&errString, "country code '"+loc.Language+"' appears multiple times") + } + codeList = append(codeList, loc.Language) + + } + if !foundEn { + util.AppendToStringSemicolonDelim(&errString, "no english PDS present") + } + } + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qcpds_valid", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcPDS has the correct form", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.3.4", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcPdsValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcretentionperiod_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcretentionperiod_valid.go new file mode 100644 index 0000000000..dbf5c06e5f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcretentionperiod_valid.go @@ -0,0 +1,74 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcRetentionPeriodValid struct{} + +func (this *qcStatemQcRetentionPeriodValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcRetentionPeriod +} + +func (l *qcStatemQcRetentionPeriodValid) Initialize() error { + return nil +} + +func (l *qcStatemQcRetentionPeriodValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func (l *qcStatemQcRetentionPeriodValid) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + + rp := s.(util.EtsiQcRetentionPeriod) + if rp.Period < 0 { + util.AppendToStringSemicolonDelim(&errString, "retention period is negative") + } + } + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qcretentionperiod_valid", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcRetentionPeriod has the correct form", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11)/ Section 4.3.3", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcRetentionPeriodValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcsscd_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcsscd_valid.go new file mode 100644 index 0000000000..b52e444636 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qcsscd_valid.go @@ -0,0 +1,68 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQcSscdValid struct{} + +func (this *qcStatemQcSscdValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcSSCD +} + +func (l *qcStatemQcSscdValid) Initialize() error { + return nil +} + +func (l *qcStatemQcSscdValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func (l *qcStatemQcSscdValid) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qcsscd_valid", + Description: "Checks that a QC Statement of the type id-etsi-qcs-QcSSCD has the correct form", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.2.2", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQcSscdValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_valid.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_valid.go new file mode 100644 index 0000000000..da575c528c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_valid.go @@ -0,0 +1,84 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQctypeValid struct{} + +func (this *qcStatemQctypeValid) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcType +} + +func (l *qcStatemQctypeValid) Initialize() error { + return nil +} + +func (l *qcStatemQctypeValid) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func (l *qcStatemQctypeValid) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + qcType := s.(util.Etsi423QcType) + if len(qcType.TypeOids) == 0 { + errString += "no QcType present, sequence of OIDs is empty" + } + for _, t := range qcType.TypeOids { + + if !t.Equal(util.IdEtsiQcsQctEsign) && !t.Equal(util.IdEtsiQcsQctEseal) && !t.Equal(util.IdEtsiQcsQctWeb) { + if len(errString) > 0 { + errString += "; " + } + errString += fmt.Sprintf("encountered invalid ETSI QcType OID: %v", t) + } + } + } + + if len(errString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_qcstatem_qctype_valid", + Description: "Checks that a QC Statement of the type Id-etsi-qcs-QcType features a non-empty list of only the allowed QcType OIDs", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.2.3", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQctypeValid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_web.go b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_web.go new file mode 100644 index 0000000000..8f2b7abe7b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/etsi/lint_qcstatem_qctype_web.go @@ -0,0 +1,90 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package etsi + +import ( + "encoding/asn1" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type qcStatemQctypeWeb struct{} + +func (this *qcStatemQctypeWeb) getStatementOid() *asn1.ObjectIdentifier { + return &util.IdEtsiQcsQcType +} + +func (l *qcStatemQctypeWeb) Initialize() error { + return nil +} + +func (l *qcStatemQctypeWeb) CheckApplies(c *x509.Certificate) bool { + if !util.IsExtInCert(c, util.QcStateOid) { + return false + } + if util.ParseQcStatem(util.GetExtFromCert(c, util.QcStateOid).Value, *l.getStatementOid()).IsPresent() { + return true + } + return false +} + +func (l *qcStatemQctypeWeb) Execute(c *x509.Certificate) *lint.LintResult { + + errString := "" + wrnString := "" + ext := util.GetExtFromCert(c, util.QcStateOid) + s := util.ParseQcStatem(ext.Value, *l.getStatementOid()) + errString += s.GetErrorInfo() + if len(errString) == 0 { + qcType := s.(util.Etsi423QcType) + if len(qcType.TypeOids) == 0 { + errString += "no QcType present, sequence of OIDs is empty" + } + found := false + for _, t := range qcType.TypeOids { + + if t.Equal(util.IdEtsiQcsQctWeb) { + found = true + } + } + if !found { + wrnString += fmt.Sprintf("etsi Type does not indicate certificate as a 'web' certificate") + } + } + + if len(errString) == 0 { + if len(wrnString) == 0 { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn, Details: wrnString} + } + } else { + return &lint.LintResult{Status: lint.Error, Details: errString} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_qcstatem_qctype_web", + Description: "Checks that a QC Statement of the type Id-etsi-qcs-QcType features features at least the type IdEtsiQcsQctWeb", + Citation: "ETSI EN 319 412 - 5 V2.2.1 (2017 - 11) / Section 4.2.3", + Source: lint.EtsiEsi, + EffectiveDate: util.EtsiEn319_412_5_V2_2_1_Date, + Lint: &qcStatemQctypeWeb{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_allowed_eku.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_allowed_eku.go new file mode 100644 index 0000000000..b276ca041f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_allowed_eku.go @@ -0,0 +1,76 @@ +/* + * ZLint Copyright 2019 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +Section 5.3 - Intermediate Certificates +Intermediate certificates created after January 1, 2019, with the exception +of cross-certificates that share a private key with a corresponding root +certificate: MUST contain an EKU extension; and, MUST NOT include the +anyExtendedKeyUsage KeyPurposeId; and, * MUST NOT include both the +id-kp-serverAuth and id-kp-emailProtection KeyPurposeIds in the same +certificate. +Note that the lint cannot distinguish cross-certificates from other +intermediates. +********************************************************************/ + +package mozilla + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type allowedEKU struct{} + +func (l *allowedEKU) Initialize() error { + return nil +} + +func (l *allowedEKU) CheckApplies(c *x509.Certificate) bool { + // TODO(@cpu): This lint should be limited to SubCAs that do not share + // a private key with a corresponding root certificate in the Mozilla root + // store. See https://github.com/zmap/zlint/issues/352 + return util.IsSubCA(c) +} + +func (l *allowedEKU) Execute(c *x509.Certificate) *lint.LintResult { + noEKU := len(c.ExtKeyUsage) == 0 + anyEKU := util.HasEKU(c, x509.ExtKeyUsageAny) + emailAndServerAuthEKU := + util.HasEKU(c, x509.ExtKeyUsageEmailProtection) && + util.HasEKU(c, x509.ExtKeyUsageServerAuth) + + if noEKU || anyEKU || emailAndServerAuthEKU { + // NOTE(@cpu): When this lint's scope is improved (see CheckApplies TODO) + // this should be a lint.Error result instead of lint.Notice. See + // https://github.com/zmap/zlint/issues/352 + return &lint.LintResult{Status: lint.Notice} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_mp_allowed_eku", + Description: "A SubCA certificate must not have key usage that allows for both server auth and email protection, and must not use anyKeyUsage", + Citation: "Mozilla Root Store Policy / Section 5.3", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC), + Lint: &allowedEKU{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_authority_key_identifier_correct.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_authority_key_identifier_correct.go new file mode 100644 index 0000000000..301f736724 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_authority_key_identifier_correct.go @@ -0,0 +1,78 @@ +/* + * ZLint Copyright 2019 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +Section 5.2 - Forbidden and Required Practices +CAs MUST NOT issue certificates that have: +- incorrect extensions (e.g., SSL certificates that exclude SSL usage, or authority key IDs + that include both the key ID and the issuer’s issuer name and serial number); +********************************************************************/ + +package mozilla + +import ( + "encoding/asn1" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type keyIdentifier struct { + KeyIdentifier asn1.RawValue `asn1:"optional,tag:0"` + AuthorityCertIssuer asn1.RawValue `asn1:"optional,tag:1"` + AuthorityCertSerialNumber asn1.RawValue `asn1:"optional,tag:2"` +} + +type authorityKeyIdentifierCorrect struct{} + +func (l *authorityKeyIdentifierCorrect) Initialize() error { + return nil +} + +func (l *authorityKeyIdentifierCorrect) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.AuthkeyOID) +} + +func (l *authorityKeyIdentifierCorrect) Execute(c *x509.Certificate) *lint.LintResult { + var keyID keyIdentifier + + // ext is assumed not-nil based on CheckApplies. + ext := util.GetExtFromCert(c, util.AuthkeyOID) + if _, err := asn1.Unmarshal(ext.Value, &keyID); err != nil { + return &lint.LintResult{ + Status: lint.Fatal, + Details: fmt.Sprintf("error unmarshalling authority key identifier extension: %v", err), + } + } + + hasKeyID := len(keyID.KeyIdentifier.Bytes) > 0 + hasCertIssuer := len(keyID.AuthorityCertIssuer.Bytes) > 0 + if hasKeyID && hasCertIssuer { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_authority_key_identifier_correct", + Description: "CAs MUST NOT issue certificates that have authority key IDs that include both the key ID and the issuer's issuer name and serial number", + Citation: "Mozilla Root Store Policy / Section 5.2", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy22Date, + Lint: &authorityKeyIdentifierCorrect{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_pub_key_encoding_correct.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_pub_key_encoding_correct.go new file mode 100644 index 0000000000..077a76cfb1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_pub_key_encoding_correct.go @@ -0,0 +1,88 @@ +package mozilla + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ + +When ECDSA keys are encoded in a SubjectPublicKeyInfo structure, the algorithm field MUST be one of the following, as +specified by RFC 5480, Section 2.1.1: + +The encoded AlgorithmIdentifier for a P-256 key MUST match the following hex-encoded +bytes: > 301306072a8648ce3d020106082a8648ce3d030107. + +The encoded AlgorithmIdentifier for a P-384 key MUST match the following hex-encoded +bytes: > 301006072a8648ce3d020106052b81040022. + +The above encodings consist of an ecPublicKey OID (1.2.840.10045.2.1) with a named curve parameter of the corresponding +curve OID. Certificates MUST NOT use the implicit or specified curve forms. + +************************************************/ + +import ( + "bytes" + "encoding/hex" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ecdsaPubKeyAidEncoding struct{} + +var acceptedAlgIDEncodingsDER = [2][]byte{ + // encoded AlgorithmIdentifier for a P-256 key + {0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}, + // encoded AlgorithmIdentifier for a P-384 key + {0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22}, +} + +func (l *ecdsaPubKeyAidEncoding) Initialize() error { + return nil +} + +func (l *ecdsaPubKeyAidEncoding) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.ECDSA +} + +func (l *ecdsaPubKeyAidEncoding) Execute(c *x509.Certificate) *lint.LintResult { + encodedPublicKeyAid, err := util.GetPublicKeyAidEncoded(c) + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("error reading public key algorithm identifier: %v", err), + } + } + + for _, encoding := range acceptedAlgIDEncodingsDER { + if bytes.Equal(encodedPublicKeyAid, encoding) { + return &lint.LintResult{Status: lint.Pass} + } + } + + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Wrong encoding of ECC public key. Got the unsupported %s", hex.EncodeToString(encodedPublicKeyAid))} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_ecdsa_pub_key_encoding_correct", + Description: "The encoded algorithm identifiers for ECDSA public keys MUST match specific bytes", + Citation: "Mozilla Root Store Policy / Section 5.1.2", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy27Date, + Lint: &ecdsaPubKeyAidEncoding{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_signature_encoding_correct.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_signature_encoding_correct.go new file mode 100644 index 0000000000..3ffcc7ba8c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_ecdsa_signature_encoding_correct.go @@ -0,0 +1,121 @@ +package mozilla + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ + +When a root or intermediate certificate's ECDSA key is used to produce a signature, only the following algorithms may +be used, and with the following encoding requirements: + +If the signing key is P-256, the signature MUST use ECDSA with SHA-256. The encoded AlgorithmIdentifier MUST match the +following hex-encoded bytes: 300a06082a8648ce3d040302. + +If the signing key is P-384, the signature MUST use ECDSA with SHA-384. The encoded AlgorithmIdentifier MUST match the +following hex-encoded bytes: 300a06082a8648ce3d040303. + +The above encodings consist of the corresponding OID with the parameters field omitted, as specified by RFC 5758, +Section 3.2. Certificates MUST NOT include a NULL parameter. Note this differs from RSASSA-PKCS1-v1_5, which includes +an explicit NULL. + +************************************************/ + +import ( + "bytes" + "encoding/hex" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ecdsaSignatureAidEncoding struct{} + +func (l *ecdsaSignatureAidEncoding) Initialize() error { + return nil +} + +func (l *ecdsaSignatureAidEncoding) CheckApplies(c *x509.Certificate) bool { + // check for all ECDSA signature algorithms to avoid missing this lint if an unsupported algorithm is used in the first place + // 1.2.840.10045.4.3.1 is SHA224withECDSA + return c.SignatureAlgorithm == x509.ECDSAWithSHA1 || + c.SignatureAlgorithm == x509.ECDSAWithSHA256 || + c.SignatureAlgorithm == x509.ECDSAWithSHA384 || + c.SignatureAlgorithm == x509.ECDSAWithSHA512 || + c.SignatureAlgorithmOID.Equal(util.OidSignatureSHA224withECDSA) +} + +func (l *ecdsaSignatureAidEncoding) Execute(c *x509.Certificate) *lint.LintResult { + // We must check consistency of the issuer public key to the signature algorithm + // (see for example: If the signing key is P-256, the signature MUST use ECDSA with SHA-256. + // The encoded AlgorithmIdentifier MUST match the following hex-encoded bytes: 300a06082a8648ce3d040302.) + // Thus we need the issuer public key which it is not available so easy. + // At this stage all certificates (also of sub-CAs and root-CAs, provided they are linted) are either + // P-256 or P-384 (see lint e_mp_ecdsa_pub_key_encoding_correct). + // Therefore we check the length of the signature in the certificate. If it is 0 ... 72 bytes then it is + // assumed done by a P-256 key and if it is 73 ... 104 bytes it is assumed done by a P-384 key. + + signature := c.Signature + signatureSize := len(signature) + encoded, err := util.GetSignatureAlgorithmInTBSEncoded(c) + if err != nil { + return &lint.LintResult{Status: lint.Error, Details: err.Error()} + } + + // Signatures made with P-256 are not going to be greater than 72 bytes long + // Seq Tag+Length = 2, r Tag+length = 2, s Tag+length = 2, r max 32+1 (unsigned representation), same for s + // len <= 2+2+2+33+33 (= 72) + const maxP256SigByteLen = 72 + // len <= 2+2+2+49+49 (= 104) + const maxP384SigByteLen = 104 + + if signatureSize <= maxP256SigByteLen { + expectedEncoding := []byte{0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02} + + if bytes.Equal(encoded, expectedEncoding) { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("Encoding of signature algorithm does not match signing key on P-256 curve. Got the unsupported %s", hex.EncodeToString(encoded)), + } + } else if signatureSize <= maxP384SigByteLen { + expectedEncoding := []byte{0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03} + + if bytes.Equal(encoded, expectedEncoding) { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("Encoding of signature algorithm does not match signing key on P-384 curve. Got the unsupported %s", hex.EncodeToString(encoded)), + } + } + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("Encoding of signature algorithm does not match signing key. Got signature length %v", signatureSize), + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_ecdsa_signature_encoding_correct", + Description: "The encoded algorithm identifiers for ECDSA signatures MUST match specific hex-encoded bytes", + Citation: "Mozilla Root Store Policy / Section 5.1.2", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy27Date, + Lint: &ecdsaSignatureAidEncoding{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_exponent_cannot_be_one.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_exponent_cannot_be_one.go new file mode 100644 index 0000000000..fe53fa9d28 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_exponent_cannot_be_one.go @@ -0,0 +1,66 @@ +/* + * ZLint Copyright 2019 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +Section 5.2 - Forbidden and Required Practices +CAs MUST NOT issue certificates that have: +- invalid public keys (e.g., RSA certificates with public exponent equal to 1); +********************************************************************/ + +package mozilla + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type exponentCannotBeOne struct{} + +func (l *exponentCannotBeOne) Initialize() error { + return nil +} + +func (l *exponentCannotBeOne) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.RSA +} + +func (l *exponentCannotBeOne) Execute(c *x509.Certificate) *lint.LintResult { + pubKey, ok := c.PublicKey.(*rsa.PublicKey) + if !ok { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "certificate public key was not an RSA public key", + } + } + + if pubKey.E == 1 { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_exponent_cannot_be_one", + Description: "CAs MUST NOT issue certificates that have invalid public keys (e.g., RSA certificates with public exponent equal to 1)", + Citation: "Mozilla Root Store Policy / Section 5.2", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy24Date, + Lint: &exponentCannotBeOne{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_2048_bits_or_more.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_2048_bits_or_more.go new file mode 100644 index 0000000000..d4e59f8564 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_2048_bits_or_more.go @@ -0,0 +1,65 @@ +/* + * ZLint Copyright 2019 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +Section 5.1 - Algorithms +RSA keys whose modulus size in bits is divisible by 8, and is at least 2048. +********************************************************************/ + +package mozilla + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type modulus2048OrMore struct{} + +func (l *modulus2048OrMore) Initialize() error { + return nil +} + +func (l *modulus2048OrMore) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.RSA +} + +func (l *modulus2048OrMore) Execute(c *x509.Certificate) *lint.LintResult { + pubKey, ok := c.PublicKey.(*rsa.PublicKey) + if !ok { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "certificate public key was not an RSA public key", + } + } + + if bitLen := pubKey.N.BitLen(); bitLen < 2048 { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_modulus_must_be_2048_bits_or_more", + Description: "RSA keys must have modulus size of at least 2048 bits", + Citation: "Mozilla Root Store Policy / Section 5.1", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy24Date, + Lint: &modulus2048OrMore{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_divisible_by_8.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_divisible_by_8.go new file mode 100644 index 0000000000..2e454ef085 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_modulus_must_be_divisible_by_8.go @@ -0,0 +1,65 @@ +/* + * ZLint Copyright 2019 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +Section 5.1 - Algorithms +RSA keys whose modulus size in bits is divisible by 8, and is at least 2048. +********************************************************************/ + +package mozilla + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type modulusDivisibleBy8 struct{} + +func (l *modulusDivisibleBy8) Initialize() error { + return nil +} + +func (l *modulusDivisibleBy8) CheckApplies(c *x509.Certificate) bool { + return c.PublicKeyAlgorithm == x509.RSA +} + +func (l *modulusDivisibleBy8) Execute(c *x509.Certificate) *lint.LintResult { + pubKey, ok := c.PublicKey.(*rsa.PublicKey) + if !ok { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "certificate public key was not an RSA public key", + } + } + + if bitLen := pubKey.N.BitLen(); (bitLen % 8) != 0 { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_modulus_must_be_divisible_by_8", + Description: "RSA keys must have a modulus size divisible by 8", + Citation: "Mozilla Root Store Policy / Section 5.1", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy24Date, + Lint: &modulusDivisibleBy8{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_pss_parameters_encoding_correct.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_pss_parameters_encoding_correct.go new file mode 100644 index 0000000000..b7b7998004 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_pss_parameters_encoding_correct.go @@ -0,0 +1,101 @@ +package mozilla + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ + +https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ + +Section 5.1.1 RSA + +RSASSA-PSS with SHA-256, MGF-1 with SHA-256, and a salt length of 32 bytes. + +The encoded AlgorithmIdentifier MUST match the following hex-encoded bytes: + +304106092a864886f70d01010a3034a00f300d0609608648016503040201 +0500a11c301a06092a864886f70d010108300d0609608648016503040201 +0500a203020120 + +RSASSA-PSS with SHA-384, MGF-1 with SHA-384, and a salt length of 48 bytes. + +The encoded AlgorithmIdentifier MUST match the following hex-encoded bytes: + +304106092a864886f70d01010a3034a00f300d0609608648016503040202 +0500a11c301a06092a864886f70d010108300d0609608648016503040202 +0500a203020130 + +RSASSA-PSS with SHA-512, MGF-1 with SHA-512, and a salt length of 64 bytes. + +The encoded AlgorithmIdentifier MUST match the following hex-encoded bytes: + +304106092a864886f70d01010a3034a00f300d0609608648016503040203 +0500a11c301a06092a864886f70d010108300d0609608648016503040203 +0500a203020140 +************************************************/ + +import ( + "bytes" + "encoding/hex" + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaPssAidEncoding struct{} + +var RSASSAPSSAlgorithmIDToDER = [3][]byte{ + // RSASSA-PSS with SHA-256, MGF-1 with SHA-256, salt length 32 bytes + {0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20}, + // RSASSA-PSS with SHA-384, MGF-1 with SHA-384, salt length 48 bytes + {0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x30}, + // RSASSA-PSS with SHA-512, MGF-1 with SHA-512, salt length 64 bytes + {0x30, 0x41, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa1, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x40}, +} + +func (l *rsaPssAidEncoding) Initialize() error { + return nil +} + +func (l *rsaPssAidEncoding) CheckApplies(c *x509.Certificate) bool { + return c.SignatureAlgorithmOID.Equal(util.OidRSASSAPSS) +} + +func (l *rsaPssAidEncoding) Execute(c *x509.Certificate) *lint.LintResult { + signatureAlgoID, err := util.GetSignatureAlgorithmInTBSEncoded(c) + if err != nil { + return &lint.LintResult{Status: lint.Error, Details: err.Error()} + } + + for _, encoding := range RSASSAPSSAlgorithmIDToDER { + if bytes.Equal(signatureAlgoID, encoding) { + return &lint.LintResult{Status: lint.Pass} + } + } + + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("RSASSA-PSS parameters are not properly encoded. %v presentations are allowed but got the unsupported %s", len(RSASSAPSSAlgorithmIDToDER), hex.EncodeToString(signatureAlgoID))} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_rsassa-pss_parameters_encoding_in_signature_algorithm_correct", + Description: "The encoded AlgorithmIdentifier for RSASSA-PSS in the signature algorithm MUST match specific bytes", + Citation: "Mozilla Root Store Policy / Section 5.1.1", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy27Date, + Lint: &rsaPssAidEncoding{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_rsassa-pss_in_spki.go b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_rsassa-pss_in_spki.go new file mode 100644 index 0000000000..0752fe99d8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/mozilla/lint_mp_rsassa-pss_in_spki.go @@ -0,0 +1,66 @@ +package mozilla + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/policy/ + +Section 5.1.1 RSA + +CAs MUST NOT use the id-RSASSA-PSS OID (1.2.840.113549.1.1.10) within a SubjectPublicKeyInfo to represent a RSA key. +************************************************/ + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaPssInSPKI struct{} + +func (l *rsaPssInSPKI) Initialize() error { + return nil +} + +func (l *rsaPssInSPKI) CheckApplies(c *x509.Certificate) bool { + // always check, no certificate is allowed to contain the PSS OID in public key + return true +} + +func (l *rsaPssInSPKI) Execute(c *x509.Certificate) *lint.LintResult { + publicKeyOID, err := util.GetPublicKeyOID(c) + if err != nil { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("error reading OID in certificate SubjectPublicKeyInfo: %v", err)} + } + + if publicKeyOID.Equal(util.OidRSASSAPSS) { + return &lint.LintResult{Status: lint.Error, Details: "id-RSASSA-PSS OID found in certificate SubjectPublicKeyInfo"} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mp_rsassa-pss_in_spki", + Description: "CAs MUST NOT use the id-RSASSA-PSS OID (1.2.840.113549.1.1.10) within a SubjectPublicKeyInfo to represent a RSA key.", + Citation: "Mozilla Root Store Policy / Section 5.1.1", + Source: lint.MozillaRootStorePolicy, + EffectiveDate: util.MozillaPolicy27Date, + Lint: &rsaPssInSPKI{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_basic_constraints_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_basic_constraints_not_critical.go new file mode 100644 index 0000000000..6a112c7b1b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_basic_constraints_not_critical.go @@ -0,0 +1,66 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +/************************************************ +RFC 5280: 4.2.1.9 +Conforming CAs MUST include this extension in all CA certificates that contain +public keys used to validate digital signatures on certificates and MUST mark +the extension as critical in such certificates. This extension MAY appear as a +critical or non- critical extension in CA certificates that contain public keys +used exclusively for purposes other than validating digital signatures on +certificates. Such CA certificates include ones that contain public keys used +exclusively for validating digital signatures on CRLs and ones that contain key +management public keys used with certificate. +************************************************/ + +type basicConstCrit struct{} + +func (l *basicConstCrit) Initialize() error { + return nil +} + +func (l *basicConstCrit) CheckApplies(c *x509.Certificate) bool { + return c.IsCA && util.IsExtInCert(c, util.BasicConstOID) +} + +func (l *basicConstCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.BasicConstOID); e != nil { + if e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } + } else { + return &lint.LintResult{Status: lint.NA} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_basic_constraints_not_critical", + Description: "basicConstraints MUST appear as a critical extension", + Citation: "RFC 5280: 4.2.1.9", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &basicConstCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ca_subject_field_empty.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ca_subject_field_empty.go new file mode 100644 index 0000000000..d7c2152cf2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ca_subject_field_empty.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.1.2.6 +The subject field identifies the entity associated with the public + key stored in the subject public key field. The subject name MAY be + carried in the subject field and/or the subjectAltName extension. If + the subject is a CA (e.g., the basic constraints extension, as + discussed in Section 4.2.1.9, is present and the value of cA is + TRUE), then the subject field MUST be populated with a non-empty + distinguished name matching the contents of the issuer field (Section + 4.1.2.4) in all certificates issued by the subject CA. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type caSubjectEmpty struct{} + +func (l *caSubjectEmpty) Initialize() error { + return nil +} + +func (l *caSubjectEmpty) CheckApplies(c *x509.Certificate) bool { + return c.IsCA +} + +func (l *caSubjectEmpty) Execute(c *x509.Certificate) *lint.LintResult { + if &c.Subject != nil && util.NotAllNameFieldsAreEmpty(&c.Subject) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ca_subject_field_empty", + Description: "CA Certificates subject field MUST not be empty and MUST have a non-empty distinguished name", + Citation: "RFC 5280: 4.1.2.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &caSubjectEmpty{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_contains_unique_identifier.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_contains_unique_identifier.go new file mode 100644 index 0000000000..a790e36541 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_contains_unique_identifier.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ + These fields MUST only appear if the version is 2 or 3 (Section 4.1.2.1). + These fields MUST NOT appear if the version is 1. The subject and issuer + unique identifiers are present in the certificate to handle the possibility + of reuse of subject and/or issuer names over time. This profile RECOMMENDS + that names not be reused for different entities and that Internet certificates + not make use of unique identifiers. CAs conforming to this profile MUST NOT + generate certificates with unique identifiers. Applications conforming to + this profile SHOULD be capable of parsing certificates that include unique + identifiers, but there are no processing requirements associated with the + unique identifiers. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertContainsUniqueIdentifier struct{} + +func (l *CertContainsUniqueIdentifier) Initialize() error { + return nil +} + +func (l *CertContainsUniqueIdentifier) CheckApplies(cert *x509.Certificate) bool { + return true +} + +func (l *CertContainsUniqueIdentifier) Execute(cert *x509.Certificate) *lint.LintResult { + if cert.IssuerUniqueId.Bytes == nil && cert.SubjectUniqueId.Bytes == nil { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.Error} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_contains_unique_identifier", + Description: "CAs MUST NOT generate certificate with unique identifiers", + Source: lint.RFC5280, + Citation: "RFC 5280: 4.1.2.8", + EffectiveDate: util.RFC5280Date, + Lint: &CertContainsUniqueIdentifier{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_extensions_version_not_3.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_extensions_version_not_3.go new file mode 100644 index 0000000000..479816e6ef --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_extensions_version_not_3.go @@ -0,0 +1,68 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +4.1.2.1. Version + This field describes the version of the encoded certificate. When + extensions are used, as expected in this profile, version MUST be 3 + (value is 2). If no extensions are present, but a UniqueIdentifier + is present, the version SHOULD be 2 (value is 1); however, the version + MAY be 3. If only basic fields are present, the version SHOULD be 1 + (the value is omitted from the certificate as the default value); + however, the version MAY be 2 or 3. + + Implementations SHOULD be prepared to accept any version certificate. + At a minimum, conforming implementations MUST recognize version 3 certificates. +4.1.2.9. Extensions + This field MUST only appear if the version is 3 (Section 4.1.2.1). + If present, this field is a SEQUENCE of one or more certificate + extensions. The format and content of certificate extensions in the + Internet PKI are defined in Section 4.2. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type CertExtensionsVersonNot3 struct{} + +func (l *CertExtensionsVersonNot3) Initialize() error { + return nil +} + +func (l *CertExtensionsVersonNot3) CheckApplies(cert *x509.Certificate) bool { + return true +} + +func (l *CertExtensionsVersonNot3) Execute(cert *x509.Certificate) *lint.LintResult { + if cert.Version != 3 && len(cert.Extensions) != 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_extensions_version_not_3", + Description: "The extensions field MUST only appear in version 3 certificates", + Citation: "RFC 5280: 4.1.2.9", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &CertExtensionsVersonNot3{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_unique_identifier_version_not_2_or_3.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_unique_identifier_version_not_2_or_3.go new file mode 100644 index 0000000000..3d6a251706 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_cert_unique_identifier_version_not_2_or_3.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************** +RFC 5280: 4.1.2.8 + These fields MUST only appear if the version is 2 or 3 (Section 4.1.2.1). + These fields MUST NOT appear if the version is 1. The subject and issuer + unique identifiers are present in the certificate to handle the possibility + of reuse of subject and/or issuer names over time. This profile RECOMMENDS + that names not be reused for different entities and that Internet certificates + not make use of unique identifiers. CAs conforming to this profile MUST NOT + generate certificates with unique identifiers. Applications conforming to + this profile SHOULD be capable of parsing certificates that include unique + identifiers, but there are no processing requirements associated with the + unique identifiers. +****************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type certUniqueIdVersion struct{} + +func (l *certUniqueIdVersion) Initialize() error { + return nil +} + +func (l *certUniqueIdVersion) CheckApplies(c *x509.Certificate) bool { + return c.IssuerUniqueId.Bytes != nil || c.SubjectUniqueId.Bytes != nil +} + +func (l *certUniqueIdVersion) Execute(c *x509.Certificate) *lint.LintResult { + if (c.Version) != 2 && (c.Version) != 3 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_unique_identifier_version_not_2_or_3", + Description: "Unique identifiers MUST only appear if the X.509 version is 2 or 3", + Citation: "RFC 5280: 4.1.2.8", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &certUniqueIdVersion{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_incomplete.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_incomplete.go new file mode 100644 index 0000000000..5dd6af3695 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_incomplete.go @@ -0,0 +1,85 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +The cRLDistributionPoints extension is a SEQUENCE of +DistributionPoint. A DistributionPoint consists of three fields, +each of which is optional: distributionPoint, reasons, and cRLIssuer. +While each of these fields is optional, a DistributionPoint MUST NOT +consist of only the reasons field; either distributionPoint or +cRLIssuer MUST be present. If the certificate issuer is not the CRL +issuer, then the cRLIssuer field MUST be present and contain the Name +of the CRL issuer. If the certificate issuer is also the CRL issuer, +then conforming CAs MUST omit the cRLIssuer field and MUST include +the distributionPoint field. +********************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type distributionPoint struct { + DistributionPoint distributionPointName `asn1:"optional,tag:0"` + Reason asn1.BitString `asn1:"optional,tag:1"` + CRLIssuer asn1.RawValue `asn1:"optional,tag:2"` +} + +type distributionPointName struct { + FullName asn1.RawValue `asn1:"optional,tag:0"` + RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` +} + +type dpIncomplete struct{} + +func (l *dpIncomplete) Initialize() error { + return nil +} + +func (l *dpIncomplete) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *dpIncomplete) Execute(c *x509.Certificate) *lint.LintResult { + dp := util.GetExtFromCert(c, util.CrlDistOID) + var cdp []distributionPoint + _, err := asn1.Unmarshal(dp.Value, &cdp) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, dp := range cdp { + if dp.Reason.BitLength != 0 && len(dp.DistributionPoint.FullName.Bytes) == 0 && + dp.DistributionPoint.RelativeName == nil && len(dp.CRLIssuer.Bytes) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_distribution_point_incomplete", + Description: "A DistributionPoint from the CRLDistributionPoints extension MUST NOT consist of only the reasons field; either distributionPoint or CRLIssuer must be present", + Citation: "RFC 5280: 4.2.1.13", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &dpIncomplete{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_missing_ldap_or_uri.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_missing_ldap_or_uri.go new file mode 100644 index 0000000000..7fabe9560c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_distribution_point_missing_ldap_or_uri.go @@ -0,0 +1,58 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.13 +When present, DistributionPointName SHOULD include at least one LDAP or HTTP URI. +************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type distribNoLDAPorURI struct{} + +func (l *distribNoLDAPorURI) Initialize() error { + return nil +} + +func (l *distribNoLDAPorURI) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CrlDistOID) +} + +func (l *distribNoLDAPorURI) Execute(c *x509.Certificate) *lint.LintResult { + for _, point := range c.CRLDistributionPoints { + if point = strings.ToLower(point); strings.HasPrefix(point, "http://") || strings.HasPrefix(point, "ldap://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Warn} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_distribution_point_missing_ldap_or_uri", + Description: "When present in the CRLDistributionPoints extension, DistributionPointName SHOULD include at least one LDAP or HTTP URI", + Citation: "RFC 5280: 4.2.1.13", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &distribNoLDAPorURI{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ecdsa_ee_invalid_ku.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ecdsa_ee_invalid_ku.go new file mode 100644 index 0000000000..a059ce10d6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ecdsa_ee_invalid_ku.go @@ -0,0 +1,99 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package rfc + +import ( + "fmt" + "sort" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ecdsaInvalidKU struct{} + +// Initialize is a no-op for this lint. +func (l *ecdsaInvalidKU) Initialize() error { + return nil +} + +// CheckApplies returns true when the certificate is a subscriber cert using an +// ECDSA public key algorithm. +func (l *ecdsaInvalidKU) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && c.PublicKeyAlgorithm == x509.ECDSA +} + +// Execute returns a Notice level lint.LintResult if the ECDSA end entity certificate +// being linted has Key Usage bits set other than digitalSignature, +// nonRepudiation/contentCommentment, and keyAgreement. +func (l *ecdsaInvalidKU) Execute(c *x509.Certificate) *lint.LintResult { + // RFC 5480, Section 3 "Key Usage Bits" says: + // + // If the keyUsage extension is present in an End Entity (EE) + // certificate that indicates id-ecPublicKey in SubjectPublicKeyInfo, + // then any combination of the following values MAY be present: + // + // digitalSignature; + // nonRepudiation; and + // keyAgreement. + // + // So we set up `allowedKUs` to match. Note that per RFC 5280: recent editions + // of X.509 renamed "nonRepudiation" to "contentCommitment", which is the name + // of the Go x509 constant we use here alongside the digitalSignature and + // keyAgreement constants. + allowedKUs := map[x509.KeyUsage]bool{ + x509.KeyUsageDigitalSignature: true, + x509.KeyUsageContentCommitment: true, + x509.KeyUsageKeyAgreement: true, + } + + var invalidKUs []string + for ku, kuName := range util.KeyUsageToString { + if c.KeyUsage&ku != 0 { + if !allowedKUs[ku] { + invalidKUs = append(invalidKUs, kuName) + } + } + } + + if len(invalidKUs) > 0 { + // Sort the invalid KUs to allow consistent ordering of Details messages for + // unit testing + sort.Strings(invalidKUs) + return &lint.LintResult{ + Status: lint.Notice, + Details: fmt.Sprintf( + "Certificate had unexpected key usage(s): %s", + strings.Join(invalidKUs, ", ")), + } + } + + return &lint.LintResult{ + Status: lint.Pass, + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "n_ecdsa_ee_invalid_ku", + Description: "ECDSA end-entity certificates MAY have key usages: digitalSignature, nonRepudiation and keyAgreement", + Citation: "RFC 5480 Section 3", + Source: lint.RFC5480, + EffectiveDate: util.CABEffectiveDate, + Lint: &ecdsaInvalidKU{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_eku_critical_improperly.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_eku_critical_improperly.go new file mode 100644 index 0000000000..a7f9f6f898 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_eku_critical_improperly.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.12 +If a CA includes extended key usages to satisfy such applications, + but does not wish to restrict usages of the key, the CA can include + the special KeyPurposeId anyExtendedKeyUsage in addition to the + particular key purposes required by the applications. Conforming CAs + SHOULD NOT mark this extension as critical if the anyExtendedKeyUsage + KeyPurposeId is present. Applications that require the presence of a + particular purpose MAY reject certificates that include the + anyExtendedKeyUsage OID but not the particular OID expected for the + application. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ekuBadCritical struct{} + +func (l *ekuBadCritical) Initialize() error { + return nil +} + +func (l *ekuBadCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.EkuSynOid) +} + +func (l *ekuBadCritical) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.EkuSynOid); e.Critical { + for _, single_use := range c.ExtKeyUsage { + if single_use == x509.ExtKeyUsageAny { + return &lint.LintResult{Status: lint.Warn} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_eku_critical_improperly", + Description: "Conforming CAs SHOULD NOT mark extended key usage extension as critical if the anyExtendedKeyUsage KeyPurposedID is present", + Citation: "RFC 5280: 4.2.1.12", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &ekuBadCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_access_location_missing.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_access_location_missing.go new file mode 100644 index 0000000000..ca61f0cfdf --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_access_location_missing.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.2.1 +An authorityInfoAccess extension may include multiple instances of + the id-ad-caIssuers accessMethod. The different instances may + specify different methods for accessing the same information or may + point to different information. When the id-ad-caIssuers + accessMethod is used, at least one instance SHOULD specify an + accessLocation that is an HTTP [RFC2616] or LDAP [RFC4516] URI. + +************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type aiaNoHTTPorLDAP struct{} + +func (l *aiaNoHTTPorLDAP) Initialize() error { + return nil +} + +func (l *aiaNoHTTPorLDAP) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.AiaOID) && c.IssuingCertificateURL != nil +} + +func (l *aiaNoHTTPorLDAP) Execute(c *x509.Certificate) *lint.LintResult { + for _, caIssuer := range c.IssuingCertificateURL { + if caIssuer = strings.ToLower(caIssuer); strings.HasPrefix(caIssuer, "http://") || strings.HasPrefix(caIssuer, "ldap://") { + return &lint.LintResult{Status: lint.Pass} + } + } + return &lint.LintResult{Status: lint.Warn} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_aia_access_location_missing", + Description: "When the id-ad-caIssuers accessMethod is used, at least one instance SHOULD specify an accessLocation that is an HTTP or LDAP URI", + Citation: "RFC 5280: 4.2.2.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &aiaNoHTTPorLDAP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_marked_critical.go new file mode 100644 index 0000000000..f05843185d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_aia_marked_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +Authority Information Access + The authority information access extension indicates how to access information and services for the issuer of the certificate in which the extension appears. Information and services may include on-line validation services and CA policy data. (The location of CRLs is not specified in this extension; that information is provided by the cRLDistributionPoints extension.) This extension may be included in end entity or CA certificates. Conforming CAs MUST mark this extension as non-critical. +************************************************/ +//See also: BRs: 7.1.2.3 & CAB: 7.1.2.2 + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtAiaMarkedCritical struct{} + +func (l *ExtAiaMarkedCritical) Initialize() error { + return nil +} + +func (l *ExtAiaMarkedCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.AiaOID) +} + +func (l *ExtAiaMarkedCritical) Execute(cert *x509.Certificate) *lint.LintResult { + if util.GetExtFromCert(cert, util.AiaOID).Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_aia_marked_critical", + Description: "Conforming CAs must mark the Authority Information Access extension as non-critical", + Citation: "RFC 5280: 4.2.2.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &ExtAiaMarkedCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_critical.go new file mode 100644 index 0000000000..ad034f08e1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************* +RFC 5280: 4.2.1.1 +Conforming CAs MUST mark this extension as non-critical. +**********************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type authorityKeyIdCritical struct{} + +func (l *authorityKeyIdCritical) Initialize() error { + return nil +} + +func (l *authorityKeyIdCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.AuthkeyOID) +} + +func (l *authorityKeyIdCritical) Execute(c *x509.Certificate) *lint.LintResult { + aki := util.GetExtFromCert(c, util.AuthkeyOID) //pointer to the extension + if aki.Critical { + return &lint.LintResult{Status: lint.Error} + } else { //implies !aki.Critical + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_authority_key_identifier_critical", + Description: "The authority key identifier extension must be non-critical", + Citation: "RFC 5280: 4.2.1.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &authorityKeyIdCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_missing.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_missing.go new file mode 100644 index 0000000000..8fd4f64bd7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_missing.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************************************** +RFC 5280: 4.2.1.1 +The keyIdentifier field of the authorityKeyIdentifier extension MUST + be included in all certificates generated by conforming CAs to + facilitate certification path construction. There is one exception; + where a CA distributes its public key in the form of a "self-signed" + certificate, the authority key identifier MAY be omitted. The + signature on a self-signed certificate is generated with the private + key associated with the certificate's subject public key. (This + proves that the issuer possesses both the public and private keys.) + In this case, the subject and authority key identifiers would be + identical, but only the subject key identifier is needed for + certification path building. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type authorityKeyIdMissing struct{} + +func (l *authorityKeyIdMissing) Initialize() error { + return nil +} + +func (l *authorityKeyIdMissing) CheckApplies(c *x509.Certificate) bool { + return !util.IsRootCA(c) +} + +func (l *authorityKeyIdMissing) Execute(c *x509.Certificate) *lint.LintResult { + if !util.IsExtInCert(c, util.AuthkeyOID) && !util.IsSelfSigned(c) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_authority_key_identifier_missing", + Description: "CAs must support key identifiers and include them in all certificates", + Citation: "RFC 5280: 4.2 & 4.2.1.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &authorityKeyIdMissing{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_no_key_identifier.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_no_key_identifier.go new file mode 100644 index 0000000000..9afb572b50 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_authority_key_identifier_no_key_identifier.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************************************** +RFC 5280: 4.2.1.1 +The keyIdentifier field of the authorityKeyIdentifier extension MUST + be included in all certificates generated by conforming CAs to + facilitate certification path construction. There is one exception; + where a CA distributes its public key in the form of a "self-signed" + certificate, the authority key identifier MAY be omitted. The + signature on a self-signed certificate is generated with the private + key associated with the certificate's subject public key. (This + proves that the issuer possesses both the public and private keys.) + In this case, the subject and authority key identifiers would be + identical, but only the subject key identifier is needed for + certification path building. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type authorityKeyIdNoKeyIdField struct{} + +func (l *authorityKeyIdNoKeyIdField) Initialize() error { + return nil +} + +func (l *authorityKeyIdNoKeyIdField) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *authorityKeyIdNoKeyIdField) Execute(c *x509.Certificate) *lint.LintResult { + if c.AuthorityKeyId == nil && !util.IsSelfSigned(c) { //will be nil by default if not found in x509.parseCert + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_authority_key_identifier_no_key_identifier", + Description: "CAs must include keyIdentifer field of AKI in all non-self-issued certificates", + Citation: "RFC 5280: 4.2.1.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &authorityKeyIdNoKeyIdField{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_contains_noticeref.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_contains_noticeref.go new file mode 100644 index 0000000000..09fbd508d2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_contains_noticeref.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +The user notice has two optional fields: the noticeRef field and the +explicitText field. Conforming CAs SHOULD NOT use the noticeRef +option. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type noticeRefPres struct{} + +func (l *noticeRefPres) Initialize() error { + return nil +} + +func (l *noticeRefPres) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CertPolicyOID) +} + +func (l *noticeRefPres) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.NoticeRefNumbers { + for _, number := range firstLvl { + if number != nil { + return &lint.LintResult{Status: lint.Warn} + } + } + } + for _, firstLvl := range c.NoticeRefOrgnization { + for _, org := range firstLvl { + if len(org.Bytes) != 0 { + return &lint.LintResult{Status: lint.Warn} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_cert_policy_contains_noticeref", + Description: "Compliant certificates SHOULD NOT use the noticeRef option", + Citation: "RFC 5280: 4.2.1.4", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: ¬iceRefPres{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_disallowed_any_policy_qualifier.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_disallowed_any_policy_qualifier.go new file mode 100644 index 0000000000..1ec2a69a98 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_disallowed_any_policy_qualifier.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +RFC 5280: 4.2.1.4 +To promote interoperability, this profile RECOMMENDS that policy +information terms consist of only an OID. Where an OID alone is +insufficient, this profile strongly recommends that the use of +qualifiers be limited to those identified in this section. When +qualifiers are used with the special policy anyPolicy, they MUST be +limited to the qualifiers identified in this section. Only those +qualifiers returned as a result of path validation are considered. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type unrecommendedQualifier struct{} + +func (l *unrecommendedQualifier) Initialize() error { + return nil +} + +func (l *unrecommendedQualifier) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CertPolicyOID) +} + +func (l *unrecommendedQualifier) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.QualifierId { + for _, qualifierId := range firstLvl { + if !qualifierId.Equal(util.CpsOID) && !qualifierId.Equal(util.UserNoticeOID) { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_cert_policy_disallowed_any_policy_qualifier", + Description: "When qualifiers are used with the special policy anyPolicy, they must be limited to qualifiers identified in this section: (4.2.1.4)", + Citation: "RFC 5280: 4.2.1.4", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &unrecommendedQualifier{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_duplicate.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_duplicate.go new file mode 100644 index 0000000000..1e43fc6bea --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_duplicate.go @@ -0,0 +1,63 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ + The certificate policies extension contains a sequence of one or more + policy information terms, each of which consists of an object identifier + (OID) and optional qualifiers. Optional qualifiers, which MAY be present, + are not expected to change the definition of the policy. A certificate + policy OID MUST NOT appear more than once in a certificate policies extension. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtCertPolicyDuplicate struct{} + +func (l *ExtCertPolicyDuplicate) Initialize() error { + return nil +} + +func (l *ExtCertPolicyDuplicate) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.CertPolicyOID) +} + +func (l *ExtCertPolicyDuplicate) Execute(cert *x509.Certificate) *lint.LintResult { + // O(n^2) is not terrible here because n is small + for i := 0; i < len(cert.PolicyIdentifiers); i++ { + for j := i + 1; j < len(cert.PolicyIdentifiers); j++ { + if i != j && cert.PolicyIdentifiers[i].Equal(cert.PolicyIdentifiers[j]) { + // Any one duplicate fails the test, so return here + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_cert_policy_duplicate", + Description: "A certificate policy OID must not appear more than once in the extension", + Citation: "RFC 5280: 4.2.1.4", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &ExtCertPolicyDuplicate{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_ia5_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_ia5_string.go new file mode 100644 index 0000000000..fec5421c6b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_ia5_string.go @@ -0,0 +1,72 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** + +An explicitText field includes the textual statement directly in +the certificate. The explicitText field is a string with a +maximum size of 200 characters. Conforming CAs SHOULD use the +UTF8String encoding for explicitText. VisibleString or BMPString +are acceptable but less preferred alternatives. Conforming CAs +MUST NOT encode explicitText as IA5String. The explicitText string +SHOULD NOT include any control characters (e.g., U+0000 to U+001F +and U+007F to U+009F). When the UTF8String or BMPString encoding +is used, all character sequences SHOULD be normalized according +to Unicode normalization form C (NFC) [NFC]. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type explicitTextIA5String struct{} + +func (l *explicitTextIA5String) Initialize() error { + return nil +} + +func (l *explicitTextIA5String) CheckApplies(c *x509.Certificate) bool { + for _, text := range c.ExplicitTexts { + if text != nil { + return true + } + } + return false +} + +func (l *explicitTextIA5String) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.ExplicitTexts { + for _, text := range firstLvl { + if text.Tag == 22 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_cert_policy_explicit_text_ia5_string", + Description: "Compliant certificates must not encode explicitTest as an IA5String", + Citation: "RFC 6818: 3", + Source: lint.RFC5280, + EffectiveDate: util.RFC6818Date, + Lint: &explicitTextIA5String{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_includes_control.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_includes_control.go new file mode 100644 index 0000000000..1f3f3fee99 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_includes_control.go @@ -0,0 +1,90 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************* +An explicitText field includes the textual statement directly in +the certificate. The explicitText field is a string with a +maximum size of 200 characters. Conforming CAs SHOULD use the +UTF8String encoding for explicitText, but MAY use IA5String. +Conforming CAs MUST NOT encode explicitText as VisibleString or +BMPString. The explicitText string SHOULD NOT include any control +characters (e.g., U+0000 to U+001F and U+007F to U+009F). When +the UTF8String encoding is used, all character sequences SHOULD be +normalized according to Unicode normalization form C (NFC) [NFC]. +*********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type controlChar struct{} + +func (l *controlChar) Initialize() error { + return nil +} + +func (l *controlChar) CheckApplies(c *x509.Certificate) bool { + for _, text := range c.ExplicitTexts { + if text != nil { + return true + } + } + return false +} + +func (l *controlChar) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.ExplicitTexts { + for _, text := range firstLvl { + if text.Tag == 12 { + for i := 0; i < len(text.Bytes); i++ { + if text.Bytes[i]&0x80 == 0 { + if text.Bytes[i] < 0x20 || text.Bytes[i] == 0x7f { + return &lint.LintResult{Status: lint.Warn} + } + } else if text.Bytes[i]&0x20 == 0 { + if text.Bytes[i] == 0xc2 && text.Bytes[i+1] >= 0x80 && text.Bytes[i+1] <= 0x9f { + return &lint.LintResult{Status: lint.Warn} + } + i += 1 + } else if text.Bytes[i]&0x10 == 0 { + i += 2 + } else if text.Bytes[i]&0x08 == 0 { + i += 3 + } else if text.Bytes[i]&0x04 == 0 { + i += 4 + } else if text.Bytes[i]&0x02 == 0 { + i += 5 + } + } + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_cert_policy_explicit_text_includes_control", + Description: "Explicit text should not include any control characters", + Citation: "RFC 6818: 3", + Source: lint.RFC5280, + EffectiveDate: util.RFC6818Date, + Lint: &controlChar{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_nfc.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_nfc.go new file mode 100644 index 0000000000..6cf26b2850 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_nfc.go @@ -0,0 +1,66 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ + When the UTF8String encoding is used, all character sequences SHOULD be + normalized according to Unicode normalization form C (NFC) [NFC]. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" + "golang.org/x/text/unicode/norm" +) + +type ExtCertPolicyExplicitTextNotNFC struct{} + +func (l *ExtCertPolicyExplicitTextNotNFC) Initialize() error { + return nil +} + +func (l *ExtCertPolicyExplicitTextNotNFC) CheckApplies(c *x509.Certificate) bool { + for _, text := range c.ExplicitTexts { + if text != nil { + return true + } + } + return false +} + +func (l *ExtCertPolicyExplicitTextNotNFC) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.ExplicitTexts { + for _, text := range firstLvl { + if text.Tag == 12 || text.Tag == 30 { + if !norm.NFC.IsNormal(text.Bytes) { + return &lint.LintResult{Status: lint.Warn} + } + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_cert_policy_explicit_text_not_nfc", + Description: "When utf8string or bmpstring encoding is used for explicitText field in certificate policy, it SHOULD be normalized by NFC format", + Citation: "RFC6181 3", + Source: lint.RFC5280, + EffectiveDate: util.RFC6818Date, + Lint: &ExtCertPolicyExplicitTextNotNFC{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_utf8.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_utf8.go new file mode 100644 index 0000000000..37154281b9 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_not_utf8.go @@ -0,0 +1,73 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +https://tools.ietf.org/html/rfc6818#section-3 + +An explicitText field includes the textual statement directly in +the certificate. The explicitText field is a string with a +maximum size of 200 characters. Conforming CAs SHOULD use the +UTF8String encoding for explicitText. VisibleString or BMPString +are acceptable but less preferred alternatives. Conforming CAs +MUST NOT encode explicitText as IA5String. The explicitText string +SHOULD NOT include any control characters (e.g., U+0000 to U+001F +and U+007F to U+009F). When the UTF8String or BMPString encoding +is used, all character sequences SHOULD be normalized according +to Unicode normalization form C (NFC) [NFC]. +*******************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type explicitTextUtf8 struct{} + +func (l *explicitTextUtf8) Initialize() error { + return nil +} + +func (l *explicitTextUtf8) CheckApplies(c *x509.Certificate) bool { + for _, text := range c.ExplicitTexts { + if text != nil { + return true + } + } + return false +} + +func (l *explicitTextUtf8) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.ExplicitTexts { + for _, text := range firstLvl { + if text.Tag != 12 { + return &lint.LintResult{Status: lint.Warn} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_cert_policy_explicit_text_not_utf8", + Description: "Compliant certificates should use the utf8string encoding for explicitText", + Citation: "RFC 6818: 3", + Source: lint.RFC5280, + EffectiveDate: util.RFC6818Date, + Lint: &explicitTextUtf8{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_too_long.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_too_long.go new file mode 100644 index 0000000000..54febf328a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_cert_policy_explicit_text_too_long.go @@ -0,0 +1,82 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +An explicitText field includes the textual statement directly in +the certificate. The explicitText field is a string with a +maximum size of 200 characters. Conforming CAs SHOULD use the +UTF8String encoding for explicitText. VisibleString or BMPString +are acceptable but less preferred alternatives. Conforming CAs +MUST NOT encode explicitText as IA5String. The explicitText string +SHOULD NOT include any control characters (e.g., U+0000 to U+001F +and U+007F to U+009F). When the UTF8String or BMPString encoding +is used, all character sequences SHOULD be normalized according +to Unicode normalization form C (NFC) [NFC]. +*******************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type explicitTextTooLong struct{} + +const tagBMPString int = 30 + +func (l *explicitTextTooLong) Initialize() error { + return nil +} + +func (l *explicitTextTooLong) CheckApplies(c *x509.Certificate) bool { + for _, text := range c.ExplicitTexts { + if text != nil { + return true + } + } + return false +} + +func (l *explicitTextTooLong) Execute(c *x509.Certificate) *lint.LintResult { + for _, firstLvl := range c.ExplicitTexts { + for _, text := range firstLvl { + var runes string + // If the field is a BMPString, we need to parse the bytes out into + // UTF-16-BE runes in order to check their length accurately + // The `Bytes` attribute here is the raw representation of the userNotice + if text.Tag == tagBMPString { + runes, _ = util.ParseBMPString(text.Bytes) + } else { + runes = string(text.Bytes) + } + if len(runes) > 200 { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_cert_policy_explicit_text_too_long", + Description: "Explicit text has a maximum size of 200 characters", + Citation: "RFC 6818: 3", + Source: lint.RFC5280, + EffectiveDate: util.RFC6818Date, + Lint: &explicitTextTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_crl_distribution_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_crl_distribution_marked_critical.go new file mode 100644 index 0000000000..cf4a22cdf0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_crl_distribution_marked_critical.go @@ -0,0 +1,57 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +The CRL distribution points extension identifies how CRL information is obtained. The extension SHOULD be non-critical, but this profile RECOMMENDS support for this extension by CAs and applications. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtCrlDistributionMarkedCritical struct{} + +func (l *ExtCrlDistributionMarkedCritical) Initialize() error { + return nil +} + +func (l *ExtCrlDistributionMarkedCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.CrlDistOID) +} + +func (l *ExtCrlDistributionMarkedCritical) Execute(cert *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(cert, util.CrlDistOID); e != nil { + if !e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } + } + return &lint.LintResult{Status: lint.NA} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_crl_distribution_marked_critical", + Description: "If included, the CRL Distribution Points extension SHOULD NOT be marked critical", + Citation: "RFC 5280: 4.2.1.13", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &ExtCrlDistributionMarkedCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_duplicate_extension.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_duplicate_extension.go new file mode 100644 index 0000000000..029d2440b5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_duplicate_extension.go @@ -0,0 +1,59 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +"A certificate MUST NOT include more than one instance of a particular extension." +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtDuplicateExtension struct{} + +func (l *ExtDuplicateExtension) Initialize() error { + return nil +} + +func (l *ExtDuplicateExtension) CheckApplies(cert *x509.Certificate) bool { + return cert.Version == 3 +} + +func (l *ExtDuplicateExtension) Execute(cert *x509.Certificate) *lint.LintResult { + // O(n^2) is not terrible here because n is capped around 10 + for i := 0; i < len(cert.Extensions); i++ { + for j := i + 1; j < len(cert.Extensions); j++ { + if i != j && cert.Extensions[i].Id.Equal(cert.Extensions[j].Id) { + return &lint.LintResult{Status: lint.Error} + } + } + } + // Nested loop will return if it finds a duplicate, so safe to assume pass + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_duplicate_extension", + Description: "A certificate MUST NOT include more than one instance of a particular extension", + Citation: "RFC 5280: 4.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &ExtDuplicateExtension{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_freshest_crl_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_freshest_crl_marked_critical.go new file mode 100644 index 0000000000..2e1d6b945a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_freshest_crl_marked_critical.go @@ -0,0 +1,57 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +The freshest CRL extension identifies how delta CRL information is obtained. The extension MUST be marked as non-critical by conforming CAs. Further discussion of CRL management is contained in Section 5. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtFreshestCrlMarkedCritical struct{} + +func (l *ExtFreshestCrlMarkedCritical) Initialize() error { + return nil +} + +func (l *ExtFreshestCrlMarkedCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.FreshCRLOID) +} + +func (l *ExtFreshestCrlMarkedCritical) Execute(cert *x509.Certificate) *lint.LintResult { + var fCRL *pkix.Extension = util.GetExtFromCert(cert, util.FreshCRLOID) + if fCRL != nil && fCRL.Critical { + return &lint.LintResult{Status: lint.Error} + } else if fCRL != nil && !fCRL.Critical { + return &lint.LintResult{Status: lint.Pass} + } + return &lint.LintResult{Status: lint.NA} //shouldn't happen +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_freshest_crl_marked_critical", + Description: "Freshest CRL MUST be marked as non-critical by conforming CAs", + Citation: "RFC 5280: 4.2.1.15", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &ExtFreshestCrlMarkedCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_critical.go new file mode 100644 index 0000000000..9c3fd96850 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +Issuer Alternative Name + As with Section 4.2.1.6, this extension is used to associate Internet style identities with the certificate issuer. Issuer alternative name MUST be encoded as in 4.2.1.6. Issuer alternative names are not processed as part of the certification path validation algorithm in Section 6. (That is, issuer alternative names are not used in name chaining and name constraints are not enforced.) + Where present, conforming CAs SHOULD mark this extension as non-critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type ExtIANCritical struct{} + +func (l *ExtIANCritical) Initialize() error { + return nil +} + +func (l *ExtIANCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.IssuerAlternateNameOID) +} + +func (l *ExtIANCritical) Execute(cert *x509.Certificate) *lint.LintResult { + if util.GetExtFromCert(cert, util.IssuerAlternateNameOID).Critical { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_ian_critical", + Description: "Issuer alternate name should be marked as non-critical", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &ExtIANCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_dns_not_ia5_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_dns_not_ia5_string.go new file mode 100644 index 0000000000..5bbfc9fb5a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_dns_not_ia5_string.go @@ -0,0 +1,74 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +RFC 5280: 4.2.1.7 +When the subjectAltName extension contains a domain name system +label, the domain name MUST be stored in the DNSName (an IA5String). +The name MUST be in the "preferred name syntax", as specified by +Section 3.5 of [RFC1034] and as modified by Section 2.1 of +[RFC1123]. Note that while uppercase and lowercase letters are +allowed in domain names, no significance is attached to the case. In +addition, while the string " " is a legal domain name, subjectAltName +extensions with a DNSName of " " MUST NOT be used. Finally, the use +of the DNS representation for Internet mail addresses +(subscriber.example.com instead of subscriber@example.com) MUST NOT +be used; such identities are to be encoded as rfc822Name. Rules for +encoding internationalized domain names are specified in Section 7.2. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANDNSNotIA5String struct{} + +func (l *IANDNSNotIA5String) Initialize() error { + return nil +} + +func (l *IANDNSNotIA5String) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANDNSNotIA5String) Execute(c *x509.Certificate) *lint.LintResult { + ext := util.GetExtFromCert(c, util.IssuerAlternateNameOID) + if ext == nil { + return &lint.LintResult{Status: lint.Fatal} + } + ok, err := util.AllAlternateNameWithTagAreIA5(ext, util.DNSNameTag) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if ok { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_dns_not_ia5_string", + Description: "DNSNames MUST be IA5 strings", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &IANDNSNotIA5String{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_empty_name.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_empty_name.go new file mode 100644 index 0000000000..67c637080d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_empty_name.go @@ -0,0 +1,81 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/****************************************************************** +RFC 5280: 4.2.1.7 +If the subjectAltName extension is present, the sequence MUST contain +at least one entry. Unlike the subject field, conforming CAs MUST +NOT issue certificates with subjectAltNames containing empty +GeneralName fields. For example, an rfc822Name is represented as an +IA5String. While an empty string is a valid IA5String, such an +rfc822Name is not permitted by this profile. The behavior of clients +that encounter such a certificate when processing a certification +path is not defined by this profile. +******************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANEmptyName struct{} + +func (l *IANEmptyName) Initialize() error { + return nil +} + +func (l *IANEmptyName) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANEmptyName) Execute(c *x509.Certificate) *lint.LintResult { + value := util.GetExtFromCert(c, util.IssuerAlternateNameOID).Value + var seq asn1.RawValue + if _, err := asn1.Unmarshal(value, &seq); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + rest := seq.Bytes + for len(rest) > 0 { + var v asn1.RawValue + var err error + rest, err = asn1.Unmarshal(rest, &v) + if err != nil { + return &lint.LintResult{Status: lint.NA} + } + if len(v.Bytes) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_empty_name", + Description: "General name fields must not be empty in IAN", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &IANEmptyName{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_no_entries.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_no_entries.go new file mode 100644 index 0000000000..da3710157f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_no_entries.go @@ -0,0 +1,63 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************** +RFC 5280: 4.2.1.7 +If the issuerAltName extension is present, the sequence MUST contain + at least one entry. Unlike the subject field, conforming CAs MUST + NOT issue certificates with subjectAltNames containing empty + GeneralName fields. For example, an rfc822Name is represented as an + IA5String. While an empty string is a valid IA5String, such an + rfc822Name is not permitted by this profile. The behavior of clients + that encounter such a certificate when processing a certification + path is not defined by this profile. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANNoEntry struct{} + +func (l *IANNoEntry) Initialize() error { + return nil +} + +func (l *IANNoEntry) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANNoEntry) Execute(c *x509.Certificate) *lint.LintResult { + ian := util.GetExtFromCert(c, util.IssuerAlternateNameOID) + if util.IsEmptyASN1Sequence(ian.Value) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_no_entries", + Description: "If present, the IAN extension must contain at least one entry", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &IANNoEntry{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_rfc822_format_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_rfc822_format_invalid.go new file mode 100644 index 0000000000..096b183178 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_rfc822_format_invalid.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.6 + When the issuerAltName extension contains an Internet mail address, + the address MUST be stored in the rfc822Name. The format of an + rfc822Name is a "Mailbox" as defined in Section 4.1.2 of [RFC2821]. + A Mailbox has the form "Local-part@Domain". Note that a Mailbox has + no phrase (such as a common name) before it, has no comment (text + surrounded in parentheses) after it, and is not surrounded by "<" and + ">". Rules for encoding Internet mail addresses that include + internationalized domain names are specified in Section 7.5. +************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANEmail struct{} + +func (l *IANEmail) Initialize() error { + return nil +} + +func (l *IANEmail) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANEmail) Execute(c *x509.Certificate) *lint.LintResult { + for _, str := range c.IANEmailAddresses { + if str == "" { + continue + } + if strings.Contains(str, " ") { + return &lint.LintResult{Status: lint.Error} + } else if str[0] == '<' || str[len(str)-1] == ')' { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_rfc822_format_invalid", + Description: "Email must not be surrounded with `<>`, and there MUST NOT be trailing comments in `()`", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &IANEmail{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_space_dns_name.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_space_dns_name.go new file mode 100644 index 0000000000..1c2b24598f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_space_dns_name.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************** +RFC 5280: 4.2.1.7 +When the issuerAltName extension contains a domain name system +label, the domain name MUST be stored in the dNSName (an IA5String). +The name MUST be in the "preferred name syntax", as specified by +Section 3.5 of [RFC1034] and as modified by Section 2.1 of +[RFC1123]. Note that while uppercase and lowercase letters are +allowed in domain names, no significance is attached to the case. In +addition, while the string " " is a legal domain name, subjectAltName +extensions with a dNSName of " " MUST NOT be used. Finally, the use +of the DNS representation for Internet mail addresses +(subscriber.example.com instead of subscriber@example.com) MUST NOT +be used; such identities are to be encoded as rfc822Name. Rules for +encoding internationalized domain names are specified in Section 7.2. +**********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANSpace struct{} + +func (l *IANSpace) Initialize() error { + return nil +} + +func (l *IANSpace) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANSpace) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.IANDNSNames { + if dns == " " { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_space_dns_name", + Description: "dNSName ' ' MUST NOT be used", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &IANSpace{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_format_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_format_invalid.go new file mode 100644 index 0000000000..f686188d0f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_format_invalid.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. +************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANURIFormat struct{} + +func (l *IANURIFormat) Initialize() error { + return nil +} + +func (l *IANURIFormat) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANURIFormat) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.IANURIs { + parsed_uri, err := url.Parse(uri) + + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + + //scheme + if parsed_uri.Scheme == "" { + return &lint.LintResult{Status: lint.Error} + } + + //scheme-specific part + if parsed_uri.Host == "" && parsed_uri.User == nil && parsed_uri.Opaque == "" && parsed_uri.Path == "" { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_uri_format_invalid", + Description: "URIs in the subjectAltName extension MUST have a scheme and scheme specific part", + Citation: "RFC5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &IANURIFormat{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_host_not_fqdn_or_ip.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_host_not_fqdn_or_ip.go new file mode 100644 index 0000000000..9bc007d526 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_host_not_fqdn_or_ip.go @@ -0,0 +1,72 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************* +When the issuerAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). The name +MUST NOT be a relative URI, and it MUST follow the URI syntax and +encoding rules specified in [RFC3986]. The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. URIs that +include an authority ([RFC3986], Section 3.2) MUST include a fully +qualified domain name or IP address as the host. Rules for encoding +Internationalized Resource Identifiers (IRIs) are specified in +Section 7.4. +*********************************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANURIFQDNOrIP struct{} + +func (l *IANURIFQDNOrIP) Initialize() error { + return nil +} + +func (l *IANURIFQDNOrIP) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANURIFQDNOrIP) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.IANURIs { + if uri != "" { + parsedUrl, err := url.Parse(uri) + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + host := parsedUrl.Host + if !util.AuthIsFQDNOrIP(host) { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_uri_host_not_fqdn_or_ip", + Description: "URIs that include an authority ([RFC3986], Section 3.2) MUST include a fully qualified domain name or IP address as the host", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &IANURIFQDNOrIP{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_not_ia5.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_not_ia5.go new file mode 100644 index 0000000000..7dc0ce5b62 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_not_ia5.go @@ -0,0 +1,60 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +When the issuerAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). +************************************************/ + +import ( + "unicode" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IANURIIA5String struct{} + +func (l *IANURIIA5String) Initialize() error { + return nil +} + +func (l *IANURIIA5String) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *IANURIIA5String) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.IANURIs { + for _, c := range uri { + if c > unicode.MaxASCII { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_uri_not_ia5", + Description: "When subjectAltName contains a URI, the name MUST be an IA5 string", + Citation: "RFC5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &IANURIIA5String{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_relative.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_relative.go new file mode 100644 index 0000000000..d43cfe8734 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_ian_uri_relative.go @@ -0,0 +1,71 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************* +When the issuerAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). The name +MUST NOT be a relative URI, and it MUST follow the URI syntax and +encoding rules specified in [RFC3986]. The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. URIs that +include an authority ([RFC3986], Section 3.2) MUST include a fully +qualified domain name or IP address as the host. Rules for encoding +Internationalized Resource Identifiers (IRIs) are specified in +Section 7.4. +*************************************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type uriRelative struct{} + +func (l *uriRelative) Initialize() error { + return nil +} + +func (l *uriRelative) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.IssuerAlternateNameOID) +} + +func (l *uriRelative) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.IANURIs { + parsed_uri, err := url.Parse(uri) + + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + + if !parsed_uri.IsAbs() { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_ian_uri_relative", + Description: "When issuerAltName extension is present and the URI is used, the name MUST NOT be a relative URI", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &uriRelative{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_cert_sign_without_ca.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_cert_sign_without_ca.go new file mode 100644 index 0000000000..c3a8ab0c04 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_cert_sign_without_ca.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.9 +The cA boolean indicates whether the certified public key may be used + to verify certificate signatures. If the cA boolean is not asserted, + then the keyCertSign bit in the key usage extension MUST NOT be + asserted. If the basic constraints extension is not present in a + version 3 certificate, or the extension is present but the cA boolean + is not asserted, then the certified public key MUST NOT be used to + verify certificate signatures. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type keyUsageCertSignNoCa struct{} + +func (l *keyUsageCertSignNoCa) Initialize() error { + return nil +} + +func (l *keyUsageCertSignNoCa) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *keyUsageCertSignNoCa) Execute(c *x509.Certificate) *lint.LintResult { + if (c.KeyUsage & x509.KeyUsageCertSign) != 0 { + if c.BasicConstraintsValid && util.IsCACert(c) { //CA certs may assert certificate signing usage + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_key_usage_cert_sign_without_ca", + Description: "if the keyCertSign bit is asserted, then the cA bit in the basic constraints extension MUST also be asserted", + Citation: "RFC 5280: 4.2.1.3 & 4.2.1.9", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &keyUsageCertSignNoCa{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_not_critical.go new file mode 100644 index 0000000000..60492bf6c8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_not_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// "When present, conforming CAs SHOULD mark this extension as critical." + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type checkKeyUsageCritical struct{} + +func (l *checkKeyUsageCritical) Initialize() error { + return nil +} + +func (l *checkKeyUsageCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *checkKeyUsageCritical) Execute(c *x509.Certificate) *lint.LintResult { + keyUsage := util.GetExtFromCert(c, util.KeyUsageOID) + if keyUsage == nil { + return &lint.LintResult{Status: lint.NA} + } + if keyUsage.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_key_usage_not_critical", + Description: "The keyUsage extension SHOULD be critical", + Citation: "RFC 5280: 4.2.1.3", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &checkKeyUsageCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_without_bits.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_without_bits.go new file mode 100644 index 0000000000..e9cd8017a5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_key_usage_without_bits.go @@ -0,0 +1,59 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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 profile does not restrict the combinations of bits that may be + set in an instantiation of the keyUsage extension. However, + appropriate values for keyUsage extensions for particular algorithms + are specified in [RFC3279], [RFC4055], and [RFC4491]. When the + keyUsage extension appears in a certificate, at least one of the bits + MUST be set to 1. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type keyUsageBitsSet struct{} + +func (l *keyUsageBitsSet) Initialize() error { + return nil +} + +func (l *keyUsageBitsSet) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.KeyUsageOID) +} + +func (l *keyUsageBitsSet) Execute(c *x509.Certificate) *lint.LintResult { + if c.KeyUsage == 0 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_key_usage_without_bits", + Description: "When the keyUsage extension is included, at least one bit MUST be set to 1", + Citation: "RFC 5280: 4.2.1.3", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &keyUsageBitsSet{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_critical.go new file mode 100644 index 0000000000..a4833764d5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_critical.go @@ -0,0 +1,63 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +Restrictions are defined in terms of permitted or excluded name + subtrees. Any name matching a restriction in the excludedSubtrees + field is invalid regardless of information appearing in the + permittedSubtrees. Conforming CAs MUST mark this extension as + critical and SHOULD NOT impose name constraints on the x400Address, + ediPartyName, or registeredID name forms. Conforming CAs MUST NOT + issue certificates where name constraints is an empty sequence. That + is, either the permittedSubtrees field or the excludedSubtrees MUST + be present. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintCrit struct{} + +func (l *nameConstraintCrit) Initialize() error { + return nil +} + +func (l *nameConstraintCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +func (l *nameConstraintCrit) Execute(c *x509.Certificate) *lint.LintResult { + e := util.GetExtFromCert(c, util.NameConstOID) + if e.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_name_constraints_not_critical", + Description: "If it is included, conforming CAs MUST mark the name constrains extension as critical", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &nameConstraintCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_in_ca.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_in_ca.go new file mode 100644 index 0000000000..6e4f35d06e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_name_constraints_not_in_ca.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************************************** +RFC 5280: 4.2.1.10 +The name constraints extension, which MUST be used only in a CA + certificate, indicates a name space within which all subject names in + subsequent certificates in a certification path MUST be located. + Restrictions apply to the subject distinguished name and apply to + subject alternative names. Restrictions apply only when the + specified name form is present. If no name of the type is in the + certificate, the certificate is acceptable. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintNotCa struct{} + +func (l *nameConstraintNotCa) Initialize() error { + return nil +} + +func (l *nameConstraintNotCa) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +func (l *nameConstraintNotCa) Execute(c *x509.Certificate) *lint.LintResult { + if !util.IsCACert(c) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_name_constraints_not_in_ca", + Description: "The name constraints extension MUST only be used in CA certificates", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &nameConstraintNotCa{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_empty.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_empty.go new file mode 100644 index 0000000000..7629f31b9d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_empty.go @@ -0,0 +1,76 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************* +RFC 5280: 4.2.1.11 +Conforming CAs MUST NOT issue certificates where policy constraints + is an empty sequence. That is, either the inhibitPolicyMapping field + or the requireExplicitPolicy field MUST be present. The behavior of + clients that encounter an empty policy constraints field is not + addressed in this profile. +*************************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type policyConstraintsContents struct{} + +func (l *policyConstraintsContents) Initialize() error { + return nil +} + +func (l *policyConstraintsContents) CheckApplies(c *x509.Certificate) bool { + if !(util.IsExtInCert(c, util.PolicyConstOID)) { + return false + } + pc := util.GetExtFromCert(c, util.PolicyConstOID) + var seq asn1.RawValue + rest, err := asn1.Unmarshal(pc.Value, &seq) //only one sequence, so rest should be empty + if err != nil || len(rest) != 0 || seq.Tag != 16 || seq.Class != 0 || !seq.IsCompound { + return false + } + return true +} + +func (l *policyConstraintsContents) Execute(c *x509.Certificate) *lint.LintResult { + pc := util.GetExtFromCert(c, util.PolicyConstOID) + var seq asn1.RawValue + _, err := asn1.Unmarshal(pc.Value, &seq) //only one sequence, so rest should be empty + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(seq.Bytes) == 0 { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_policy_constraints_empty", + Description: "Conforming CAs MUST NOT issue certificates where policy constraints is an empty sequence. That is, either the inhibitPolicyMapping field or the requireExplicityPolicy field MUST be present", + Citation: "RFC 5280: 4.2.1.11", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &policyConstraintsContents{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_not_critical.go new file mode 100644 index 0000000000..b8364600fd --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_constraints_not_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.11 +Conforming CAs MUST mark this extension as critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type policyConstraintsCritical struct{} + +func (l *policyConstraintsCritical) Initialize() error { + return nil +} + +func (l *policyConstraintsCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.PolicyConstOID) +} + +func (l *policyConstraintsCritical) Execute(c *x509.Certificate) *lint.LintResult { + pc := util.GetExtFromCert(c, util.PolicyConstOID) + if !pc.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_policy_constraints_not_critical", + Description: "Conforming CAs MUST mark the policy constraints extension as critical", + Citation: "RFC 5280: 4.2.1.11", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &policyConstraintsCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_any_policy.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_any_policy.go new file mode 100644 index 0000000000..8cb9b2b1c5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_any_policy.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +RFC 5280: 4.2.1.5 +Each issuerDomainPolicy named in the policy mappings extension SHOULD + also be asserted in a certificate policies extension in the same + certificate. Policies MUST NOT be mapped either to or from the + special value anyPolicy (Section 4.2.1.4). +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type policyMapAnyPolicy struct{} + +func (l *policyMapAnyPolicy) Initialize() error { + return nil +} + +func (l *policyMapAnyPolicy) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.PolicyMapOID) +} + +func (l *policyMapAnyPolicy) Execute(c *x509.Certificate) *lint.LintResult { + extPolMap := util.GetExtFromCert(c, util.PolicyMapOID) + polMap, err := util.GetMappedPolicies(extPolMap) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, pair := range polMap { + if util.AnyPolicyOID.Equal(pair[0]) || util.AnyPolicyOID.Equal(pair[1]) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_policy_map_any_policy", + Description: "Policies must not be mapped to or from the anyPolicy value", + Citation: "RFC 5280: 4.2.1.5", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &policyMapAnyPolicy{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_critical.go new file mode 100644 index 0000000000..09e502c660 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_critical.go @@ -0,0 +1,57 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************** +RFC 5280: 4.2.1.5. Policy Mappings +This extension MAY be supported by CAs and/or applications. + Conforming CAs SHOULD mark this extension as critical. +**********************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type policyMapCritical struct{} + +func (l *policyMapCritical) Initialize() error { + return nil +} + +func (l *policyMapCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.PolicyMapOID) +} + +func (l *policyMapCritical) Execute(c *x509.Certificate) *lint.LintResult { + polMap := util.GetExtFromCert(c, util.PolicyMapOID) + if polMap.Critical { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_policy_map_not_critical", + Description: "Policy mappings should be marked as critical", + Citation: "RFC 5280: 4.2.1.5", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &policyMapCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_in_cert_policy.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_in_cert_policy.go new file mode 100644 index 0000000000..9382b13a87 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_policy_map_not_in_cert_policy.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************* +RFC 5280: 4.2.1.5 +Each issuerDomainPolicy named in the policy mapping extension SHOULD + also be asserted in a certificate policies extension in the same + certificate. Policies SHOULD NOT be mapped either to or from the + special value anyPolicy (section 4.2.1.5). +*********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type policyMapMatchesCertPolicy struct{} + +func (l *policyMapMatchesCertPolicy) Initialize() error { + return nil +} + +func (l *policyMapMatchesCertPolicy) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.PolicyMapOID) +} + +func (l *policyMapMatchesCertPolicy) Execute(c *x509.Certificate) *lint.LintResult { + extPolMap := util.GetExtFromCert(c, util.PolicyMapOID) + polMap, err := util.GetMappedPolicies(extPolMap) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, pair := range polMap { + if !util.SliceContainsOID(c.PolicyIdentifiers, pair[0]) { + return &lint.LintResult{Status: lint.Warn} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_policy_map_not_in_cert_policy", + Description: "Each issuerDomainPolicy named in the policy mappings extension should also be asserted in a certificate policies extension", + Citation: "RFC 5280: 4.2.1.5", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &policyMapMatchesCertPolicy{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_name_too_long.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_name_too_long.go new file mode 100644 index 0000000000..4942d71eb3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_name_too_long.go @@ -0,0 +1,51 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDNSTooLong struct{} + +func (l *SANDNSTooLong) Initialize() error { + return nil +} + +func (l *SANDNSTooLong) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) && len(c.DNSNames) > 0 +} + +func (l *SANDNSTooLong) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + if len(dns) > 253 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_dns_name_too_long", + Description: "DNSName must be less than or equal to 253 bytes", + Citation: "RFC 5280", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &SANDNSTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_not_ia5_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_not_ia5_string.go new file mode 100644 index 0000000000..98a0f24753 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_dns_not_ia5_string.go @@ -0,0 +1,73 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +RFC 5280: 4.2.1.6 +When the subjectAltName extension contains a domain name system +label, the domain name MUST be stored in the dNSName (an IA5String). +The name MUST be in the "preferred name syntax", as specified by +Section 3.5 of [RFC1034] and as modified by Section 2.1 of +[RFC1123]. Note that while uppercase and lowercase letters are +allowed in domain names, no significance is attached to the case. In +addition, while the string " " is a legal domain name, subjectAltName +extensions with a dNSName of " " MUST NOT be used. Finally, the use +of the DNS representation for Internet mail addresses +(subscriber.example.com instead of subscriber@example.com) MUST NOT +be used; such identities are to be encoded as rfc822Name. Rules for +encoding internationalized domain names are specified in Section 7.2. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANDNSNotIA5String struct{} + +func (l *SANDNSNotIA5String) Initialize() error { + return nil +} + +func (l *SANDNSNotIA5String) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDNSNotIA5String) Execute(c *x509.Certificate) *lint.LintResult { + ext := util.GetExtFromCert(c, util.SubjectAlternateNameOID) + if ext == nil { + return &lint.LintResult{Status: lint.Fatal} + } + ok, err := util.AllAlternateNameWithTagAreIA5(ext, util.DNSNameTag) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if ok { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_dns_not_ia5_string", + Description: "dNSNames MUST be IA5 strings", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &SANDNSNotIA5String{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_empty_name.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_empty_name.go new file mode 100644 index 0000000000..db9a8b39f8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_empty_name.go @@ -0,0 +1,81 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/****************************************************************** +RFC 5280: 4.2.1.6 +If the subjectAltName extension is present, the sequence MUST contain +at least one entry. Unlike the subject field, conforming CAs MUST +NOT issue certificates with subjectAltNames containing empty +GeneralName fields. For example, an rfc822Name is represented as an +IA5String. While an empty string is a valid IA5String, such an +rfc822Name is not permitted by this profile. The behavior of clients +that encounter such a certificate when processing a certification +path is not defined by this profile. +******************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANEmptyName struct{} + +func (l *SANEmptyName) Initialize() error { + return nil +} + +func (l *SANEmptyName) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANEmptyName) Execute(c *x509.Certificate) *lint.LintResult { + value := util.GetExtFromCert(c, util.SubjectAlternateNameOID).Value + var seq asn1.RawValue + if _, err := asn1.Unmarshal(value, &seq); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + rest := seq.Bytes + for len(rest) > 0 { + var v asn1.RawValue + var err error + rest, err = asn1.Unmarshal(rest, &v) + if err != nil { + return &lint.LintResult{Status: lint.NA} + } + if len(v.Bytes) == 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_empty_name", + Description: "General name fields MUST NOT be empty in subjectAlternateNames", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &SANEmptyName{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_no_entries.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_no_entries.go new file mode 100644 index 0000000000..fd9e21bd6e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_no_entries.go @@ -0,0 +1,63 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************** +RFC 5280: 4.2.1.6 +If the subjectAltName extension is present, the sequence MUST contain + at least one entry. Unlike the subject field, conforming CAs MUST + NOT issue certificates with subjectAltNames containing empty + GeneralName fields. For example, an rfc822Name is represented as an + IA5String. While an empty string is a valid IA5String, such an + rfc822Name is not permitted by this profile. The behavior of clients + that encounter such a certificate when processing a certification + path is not defined by this profile. +***********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANNoEntry struct{} + +func (l *SANNoEntry) Initialize() error { + return nil +} + +func (l *SANNoEntry) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANNoEntry) Execute(c *x509.Certificate) *lint.LintResult { + san := util.GetExtFromCert(c, util.SubjectAlternateNameOID) + if util.IsEmptyASN1Sequence(san.Value) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_no_entries", + Description: "If present, the SAN extension MUST contain at least one entry", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &SANNoEntry{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_not_critical_without_subject.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_not_critical_without_subject.go new file mode 100644 index 0000000000..317f18286f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_not_critical_without_subject.go @@ -0,0 +1,63 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.6 +Further, if the only subject identity included in the certificate is + an alternative name form (e.g., an electronic mail address), then the + subject distinguished name MUST be empty (an empty sequence), and the + subjectAltName extension MUST be present. If the subject field + contains an empty sequence, then the issuing CA MUST include a + subjectAltName extension that is marked as critical. When including + the subjectAltName extension in a certificate that has a non-empty + subject distinguished name, conforming CAs SHOULD mark the + subjectAltName extension as non-critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type extSANNotCritNoSubject struct{} + +func (l *extSANNotCritNoSubject) Initialize() error { + return nil +} + +func (l *extSANNotCritNoSubject) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *extSANNotCritNoSubject) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.SubjectAlternateNameOID); !util.NotAllNameFieldsAreEmpty(&c.Subject) && !e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_not_critical_without_subject", + Description: "If there is an empty subject field, then the SAN extension MUST be critical", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &extSANNotCritNoSubject{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_rfc822_format_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_rfc822_format_invalid.go new file mode 100644 index 0000000000..4df76c5ac8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_rfc822_format_invalid.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.6 + When the subjectAltName extension contains an Internet mail address, + the address MUST be stored in the rfc822Name. The format of an + rfc822Name is a "Mailbox" as defined in Section 4.1.2 of [RFC2821]. + A Mailbox has the form "Local-part@Domain". Note that a Mailbox has + no phrase (such as a common name) before it, has no comment (text + surrounded in parentheses) after it, and is not surrounded by "<" and + ">". Rules for encoding Internet mail addresses that include + internationalized domain names are specified in Section 7.5. +************************************************************************/ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type invalidEmail struct{} + +func (l *invalidEmail) Initialize() error { + return nil +} + +func (l *invalidEmail) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *invalidEmail) Execute(c *x509.Certificate) *lint.LintResult { + for _, str := range c.EmailAddresses { + if str == "" { + continue + } + if strings.Contains(str, " ") { + return &lint.LintResult{Status: lint.Error} + } else if str[0] == '<' || str[len(str)-1] == ')' { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_rfc822_format_invalid", + Description: "Email MUST NOT be surrounded with `<>`, and there must be no trailing comments in `()`", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &invalidEmail{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_space_dns_name.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_space_dns_name.go new file mode 100644 index 0000000000..fbc0b3c19d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_space_dns_name.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.6 +When the subjectAltName extension contains a domain name system + label, the domain name MUST be stored in the dNSName (an IA5String). + The name MUST be in the "preferred name syntax", as specified by + Section 3.5 of [RFC1034] and as modified by Section 2.1 of + [RFC1123]. Note that while uppercase and lowercase letters are + allowed in domain names, no significance is attached to the case. In + addition, while the string " " is a legal domain name, subjectAltName + extensions with a dNSName of " " MUST NOT be used. Finally, the use + of the DNS representation for Internet mail addresses + (subscriber.example.com instead of subscriber@example.com) MUST NOT + be used; such identities are to be encoded as rfc822Name. Rules for + encoding internationalized domain names are specified in Section 7.2. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANIsSpaceDNS struct{} + +func (l *SANIsSpaceDNS) Initialize() error { + return nil +} + +func (l *SANIsSpaceDNS) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANIsSpaceDNS) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + if dns == " " { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_space_dns_name", + Description: "The dNSName ` ` MUST NOT be used", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &SANIsSpaceDNS{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_format_invalid.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_format_invalid.go new file mode 100644 index 0000000000..9433317742 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_format_invalid.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. +************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type extSANURIFormatInvalid struct{} + +func (l *extSANURIFormatInvalid) Initialize() error { + return nil +} + +func (l *extSANURIFormatInvalid) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *extSANURIFormatInvalid) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.URIs { + parsed_uri, err := url.Parse(uri) + + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + + //scheme + if parsed_uri.Scheme == "" { + return &lint.LintResult{Status: lint.Error} + } + + //scheme-specific part + if parsed_uri.Host == "" && parsed_uri.User == nil && parsed_uri.Opaque == "" && parsed_uri.Path == "" { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_uri_format_invalid", + Description: "URIs in SAN extension must have a scheme and scheme specific part", + Citation: "RFC5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &extSANURIFormatInvalid{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_host_not_fqdn_or_ip.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_host_not_fqdn_or_ip.go new file mode 100644 index 0000000000..42fac1f37e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_host_not_fqdn_or_ip.go @@ -0,0 +1,78 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************* +When the subjectAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). The name +MUST NOT be a relative URI, and it MUST follow the URI syntax and +encoding rules specified in [RFC3986]. The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. URIs that +include an authority ([RFC3986], Section 3.2) MUST include a fully +qualified domain name or IP address as the host. Rules for encoding +Internationalized Resource Identifiers (IRIs) are specified in +Section 7.4. +*********************************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SANURIHost struct{} + +func (l *SANURIHost) Initialize() error { + return nil +} + +func (l *SANURIHost) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANURIHost) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.URIs { + if uri != "" { + parsed, err := url.Parse(uri) + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + if parsed.Opaque == "" { + // if Opaque is not empty, that means there is no authority, which means that the URI is vacuously OK + if parsed.Host == "" { + return &lint.LintResult{Status: lint.Error} + } + if !util.IsFQDNOrIP(parsed.Host) { + return &lint.LintResult{Status: lint.Error} + } + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_uri_host_not_fqdn_or_ip", + Description: "URIs that include an authority ([RFC3986], Section 3.2) MUST include a fully qualified domain name or IP address as the host", + Citation: "RFC 5280: 4.2.1.7", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &SANURIHost{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_not_ia5.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_not_ia5.go new file mode 100644 index 0000000000..872c7309ab --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_not_ia5.go @@ -0,0 +1,60 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +When the subjectAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). +************************************************/ + +import ( + "unicode" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type extSANURINotIA5 struct{} + +func (l *extSANURINotIA5) Initialize() error { + return nil +} + +func (l *extSANURINotIA5) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *extSANURINotIA5) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.URIs { + for _, c := range uri { + if c > unicode.MaxASCII { + return &lint.LintResult{Status: lint.Error} + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_uri_not_ia5", + Description: "When subjectAlternateName contains a URI, the name MUST be an IA5 string", + Citation: "RFC5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &extSANURINotIA5{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_relative.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_relative.go new file mode 100644 index 0000000000..2066f255b5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_san_uri_relative.go @@ -0,0 +1,71 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************* +When the subjectAltName extension contains a URI, the name MUST be +stored in the uniformResourceIdentifier (an IA5String). The name +MUST NOT be a relative URI, and it MUST follow the URI syntax and +encoding rules specified in [RFC3986]. The name MUST include both a +scheme (e.g., "http" or "ftp") and a scheme-specific-part. URIs that +include an authority ([RFC3986], Section 3.2) MUST include a fully +qualified domain name or IP address as the host. Rules for encoding +Internationalized Resource Identifiers (IRIs) are specified in +Section 7.4. +*************************************************************************/ + +import ( + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type extSANURIRelative struct{} + +func (l *extSANURIRelative) Initialize() error { + return nil +} + +func (l *extSANURIRelative) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *extSANURIRelative) Execute(c *x509.Certificate) *lint.LintResult { + for _, uri := range c.URIs { + parsed_uri, err := url.Parse(uri) + + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + + if !parsed_uri.IsAbs() { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_san_uri_relative", + Description: "When the subjectAlternateName extension is present and a URI is used, the name MUST NOT be a relative URI", + Citation: "RFC 5280: 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &extSANURIRelative{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_directory_attr_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_directory_attr_critical.go new file mode 100644 index 0000000000..acf50e93e2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_directory_attr_critical.go @@ -0,0 +1,58 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.2.1.8 +The subject directory attributes extension is used to convey + identification attributes (e.g., nationality) of the subject. The + extension is defined as a sequence of one or more attributes. + Conforming CAs MUST mark this extension as non-critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subDirAttrCrit struct{} + +func (l *subDirAttrCrit) Initialize() error { + return nil +} + +func (l *subDirAttrCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectDirAttrOID) +} + +func (l *subDirAttrCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.SubjectDirAttrOID); e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_subject_directory_attr_critical", + Description: "Conforming CAs MUST mark the Subject Directory Attributes extension as not critical", + Citation: "RFC 5280: 4.2.1.8", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subDirAttrCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_critical.go new file mode 100644 index 0000000000..749e22e2fb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_critical.go @@ -0,0 +1,56 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************** +RFC 5280: 4.2.1.2 + Conforming CAs MUST mark this extension as non-critical. +**********************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectKeyIdCritical struct{} + +func (l *subjectKeyIdCritical) Initialize() error { + return nil +} + +func (l *subjectKeyIdCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectKeyIdentityOID) +} + +func (l *subjectKeyIdCritical) Execute(c *x509.Certificate) *lint.LintResult { + ski := util.GetExtFromCert(c, util.SubjectKeyIdentityOID) //pointer to the extension + if ski.Critical { + return &lint.LintResult{Status: lint.Error} + } else { //implies !ski.Critical + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_subject_key_identifier_critical", + Description: "The subject key identifier extension MUST be non-critical", + Citation: "RFC 5280: 4.2.1.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectKeyIdCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_ca.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_ca.go new file mode 100644 index 0000000000..2f1f280292 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_ca.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ + To facilitate certification path construction, this extension MUST + appear in all conforming CA certificates, that is, all certificates + including the basic constraints extension (Section 4.2.1.9) where the + value of cA is TRUE. In conforming CA certificates, the value of the + subject key identifier MUST be the value placed in the key identifier + field of the authority key identifier extension (Section 4.2.1.1) of + certificates issued by the subject of this certificate. Applications + are not required to verify that key identifiers match when performing + certification path validation. + ... + For end entity certificates, the subject key identifier extension provides + a means for identifying certificates containing the particular public key + used in an application. Where an end entity has obtained multiple certificates, + especially from multiple CAs, the subject key identifier provides a means to + quickly identify the set of certificates containing a particular public key. + To assist applications in identifying the appropriate end entity certificate, + this extension SHOULD be included in all end entity certificates. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectKeyIdMissingCA struct{} + +func (l *subjectKeyIdMissingCA) Initialize() error { + return nil +} + +func (l *subjectKeyIdMissingCA) CheckApplies(cert *x509.Certificate) bool { + return util.IsCACert(cert) +} + +func (l *subjectKeyIdMissingCA) Execute(cert *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(cert, util.SubjectKeyIdentityOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_ext_subject_key_identifier_missing_ca", + Description: "CAs MUST include a Subject Key Identifier in all CA certificates", + Citation: "RFC 5280: 4.2 & 4.2.1.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectKeyIdMissingCA{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_sub_cert.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_sub_cert.go new file mode 100644 index 0000000000..9d71d05345 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_ext_subject_key_identifier_missing_sub_cert.go @@ -0,0 +1,70 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************** + To facilitate certification path construction, this extension MUST + appear in all conforming CA certificates, that is, all certificates + including the basic constraints extension (Section 4.2.1.9) where the + value of cA is TRUE. In conforming CA certificates, the value of the + subject key identifier MUST be the value placed in the key identifier + field of the authority key identifier extension (Section 4.2.1.1) of + certificates issued by the subject of this certificate. Applications + are not required to verify that key identifiers match when performing + certification path validation. + ... + For end entity certificates, the subject key identifier extension provides + a means for identifying certificates containing the particular public key + used in an application. Where an end entity has obtained multiple certificates, + especially from multiple CAs, the subject key identifier provides a means to + quickly identify the set of certificates containing a particular public key. + To assist applications in identifying the appropriate end entity certificate, + this extension SHOULD be included in all end entity certificates. +**********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectKeyIdMissingSubscriber struct{} + +func (l *subjectKeyIdMissingSubscriber) Initialize() error { + return nil +} + +func (l *subjectKeyIdMissingSubscriber) CheckApplies(cert *x509.Certificate) bool { + return !util.IsCACert(cert) +} + +func (l *subjectKeyIdMissingSubscriber) Execute(cert *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(cert, util.SubjectKeyIdentityOID) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Warn} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_ext_subject_key_identifier_missing_sub_cert", + Description: "Sub certificates SHOULD include Subject Key Identifier in end entity certs", + Citation: "RFC 5280: 4.2 & 4.2.1.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectKeyIdMissingSubscriber{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_does_not_include_seconds.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_does_not_include_seconds.go new file mode 100644 index 0000000000..e049a62aae --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_does_not_include_seconds.go @@ -0,0 +1,97 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +4.1.2.5.2. GeneralizedTime +The generalized time type, GeneralizedTime, is a standard ASN.1 type +for variable precision representation of time. Optionally, the +GeneralizedTime field can include a representation of the time +differential between local and Greenwich Mean Time. + +For the purposes of this profile, GeneralizedTime values MUST be +expressed in Greenwich Mean Time (Zulu) and MUST include seconds +(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds +is zero. GeneralizedTime values MUST NOT include fractional seconds. +********************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type generalizedNoSeconds struct { +} + +func (l *generalizedNoSeconds) Initialize() error { + return nil +} + +func (l *generalizedNoSeconds) CheckApplies(c *x509.Certificate) bool { + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + return date1Gen || date2Gen +} + +func (l *generalizedNoSeconds) Execute(c *x509.Certificate) *lint.LintResult { + r := lint.Pass + date1, date2 := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(date1, date2) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + if date1Gen { + // UTC Tests on notBefore + checkSeconds(&r, date1) + if r == lint.Error { + return &lint.LintResult{Status: r} + } + } + if date2Gen { + checkSeconds(&r, date2) + } + return &lint.LintResult{Status: r} +} + +func checkSeconds(r *lint.LintStatus, t asn1.RawValue) { + if t.Bytes[len(t.Bytes)-1] == 'Z' { + if len(t.Bytes) < 15 { + *r = lint.Error + } + } else if t.Bytes[len(t.Bytes)-5] == '-' || t.Bytes[len(t.Bytes)-1] == '+' { + if len(t.Bytes) < 19 { + *r = lint.Error + } + } else { + if len(t.Bytes) < 14 { + *r = lint.Error + } + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_generalized_time_does_not_include_seconds", + Description: "Generalized time values MUST include seconds", + Citation: "RFC 5280: 4.1.2.5.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &generalizedNoSeconds{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_includes_fraction_seconds.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_includes_fraction_seconds.go new file mode 100644 index 0000000000..1022df4669 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_includes_fraction_seconds.go @@ -0,0 +1,97 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +4.1.2.5.2. GeneralizedTime +The generalized time type, GeneralizedTime, is a standard ASN.1 type +for variable precision representation of time. Optionally, the +GeneralizedTime field can include a representation of the time +differential between local and Greenwich Mean Time. + +For the purposes of this profile, GeneralizedTime values MUST be +expressed in Greenwich Mean Time (Zulu) and MUST include seconds +(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds +is zero. GeneralizedTime values MUST NOT include fractional seconds. +********************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type generalizedTimeFraction struct { +} + +func (l *generalizedTimeFraction) Initialize() error { + return nil +} + +func (l *generalizedTimeFraction) CheckApplies(c *x509.Certificate) bool { + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + return date1Gen || date2Gen +} + +func (l *generalizedTimeFraction) Execute(c *x509.Certificate) *lint.LintResult { + r := lint.Pass + date1, date2 := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(date1, date2) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + if date1Gen { + // UTC Tests on notBefore + checkFraction(&r, date1) + if r == lint.Error { + return &lint.LintResult{Status: r} + } + } + if date2Gen { + checkFraction(&r, date2) + } + return &lint.LintResult{Status: r} +} + +func checkFraction(r *lint.LintStatus, t asn1.RawValue) { + if t.Bytes[len(t.Bytes)-1] == 'Z' { + if len(t.Bytes) > 15 { + *r = lint.Error + } + } else if t.Bytes[len(t.Bytes)-5] == '-' || t.Bytes[len(t.Bytes)-1] == '+' { + if len(t.Bytes) > 19 { + *r = lint.Error + } + } else { + if len(t.Bytes) > 14 { + *r = lint.Error + } + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_generalized_time_includes_fraction_seconds", + Description: "Generalized time values MUST NOT include fractional seconds", + Citation: "RFC 5280: 4.1.2.5.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &generalizedTimeFraction{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_not_in_zulu.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_not_in_zulu.go new file mode 100644 index 0000000000..6d3e392c98 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_generalized_time_not_in_zulu.go @@ -0,0 +1,78 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +4.1.2.5.2. GeneralizedTime +The generalized time type, GeneralizedTime, is a standard ASN.1 type +for variable precision representation of time. Optionally, the +GeneralizedTime field can include a representation of the time +differential between local and Greenwich Mean Time. + +For the purposes of this profile, GeneralizedTime values MUST be +expressed in Greenwich Mean Time (Zulu) and MUST include seconds +(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds +is zero. GeneralizedTime values MUST NOT include fractional seconds. +********************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type generalizedNotZulu struct { +} + +func (l *generalizedNotZulu) Initialize() error { + return nil +} + +func (l *generalizedNotZulu) CheckApplies(c *x509.Certificate) bool { + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + return date1Gen || date2Gen +} + +func (l *generalizedNotZulu) Execute(c *x509.Certificate) *lint.LintResult { + date1, date2 := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(date1, date2) + date1Gen := beforeTag == 24 + date2Gen := afterTag == 24 + if date1Gen { + if date1.Bytes[len(date1.Bytes)-1] != 'Z' { + return &lint.LintResult{Status: lint.Error} + } + } + if date2Gen { + if date2.Bytes[len(date2.Bytes)-1] != 'Z' { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_generalized_time_not_in_zulu", + Description: "Generalized time values MUST be expressed in Greenwich Mean Time (Zulu)", + Citation: "RFC 5280: 4.1.2.5.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &generalizedNotZulu{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_malformed_unicode.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_malformed_unicode.go new file mode 100644 index 0000000000..29e2ee215e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_malformed_unicode.go @@ -0,0 +1,60 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" + "golang.org/x/net/idna" +) + +type IDNMalformedUnicode struct{} + +func (l *IDNMalformedUnicode) Initialize() error { + return nil +} + +func (l *IDNMalformedUnicode) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *IDNMalformedUnicode) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + labels := strings.Split(dns, ".") + for _, label := range labels { + if strings.HasPrefix(label, "xn--") { + _, err := idna.ToUnicode(label) + if err != nil { + return &lint.LintResult{Status: lint.Error} + } + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_international_dns_name_not_unicode", + Description: "Internationalized DNSNames punycode not valid unicode", + Citation: "RFC 3490", + EffectiveDate: util.RFC3490Date, + Source: lint.RFC5280, + Lint: &IDNMalformedUnicode{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_must_be_nfc.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_must_be_nfc.go new file mode 100644 index 0000000000..6f6b399a62 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_idn_dnsname_must_be_nfc.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" + "golang.org/x/net/idna" + "golang.org/x/text/unicode/norm" +) + +type IDNNotNFC struct{} + +func (l *IDNNotNFC) Initialize() error { + return nil +} + +func (l *IDNNotNFC) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *IDNNotNFC) Execute(c *x509.Certificate) *lint.LintResult { + for _, dns := range c.DNSNames { + labels := strings.Split(dns, ".") + for _, label := range labels { + if strings.HasPrefix(label, "xn--") { + unicodeLabel, err := idna.ToUnicode(label) + if err != nil { + return &lint.LintResult{Status: lint.NA} + } + if !norm.NFC.IsNormalString(unicodeLabel) { + return &lint.LintResult{Status: lint.Error} + } + } + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_international_dns_name_not_nfc", + Description: "Internationalized DNSNames must be normalized by unicode normalization form C", + Citation: "RFC 8399", + Source: lint.RFC5891, + EffectiveDate: util.RFC8399Date, + Lint: &IDNNotNFC{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_inhibit_any_policy_not_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_inhibit_any_policy_not_critical.go new file mode 100644 index 0000000000..0e60f3f9bd --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_inhibit_any_policy_not_critical.go @@ -0,0 +1,64 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +4.2.1.14. Inhibit anyPolicy + The inhibit anyPolicy extension can be used in certificates issued to CAs. + The inhibit anyPolicy extension indicates that the special anyPolicy OID, + with the value { 2 5 29 32 0 }, is not considered an explicit match for other + certificate policies except when it appears in an intermediate self-issued + CA certificate. The value indicates the number of additional non-self-issued + certificates that may appear in the path before anyPolicy is no longer permitted. + For example, a value of one indicates that anyPolicy may be processed in + certificates issued by the subject of this certificate, but not in additional + certificates in the path. + + Conforming CAs MUST mark this extension as critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type InhibitAnyPolicyNotCritical struct{} + +func (l *InhibitAnyPolicyNotCritical) Initialize() error { + return nil +} + +func (l *InhibitAnyPolicyNotCritical) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.InhibitAnyPolicyOID) +} + +func (l *InhibitAnyPolicyNotCritical) Execute(cert *x509.Certificate) *lint.LintResult { + if anyPol := util.GetExtFromCert(cert, util.InhibitAnyPolicyOID); !anyPol.Critical { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_inhibit_any_policy_not_critical", + Description: "CAs MUST mark the inhibitAnyPolicy extension as critical", + Citation: "RFC 5280: 4.2.1.14", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &InhibitAnyPolicyNotCritical{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_dn_country_not_printable_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_dn_country_not_printable_string.go new file mode 100644 index 0000000000..7b5c720a9b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_dn_country_not_printable_string.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type IssuerDNCountryNotPrintableString struct{} + +func (l *IssuerDNCountryNotPrintableString) Initialize() error { + return nil +} + +func (l *IssuerDNCountryNotPrintableString) CheckApplies(c *x509.Certificate) bool { + return len(c.Issuer.Country) > 0 +} + +func (l *IssuerDNCountryNotPrintableString) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawIssuer, &rdnSequence) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(rest) > 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + if attrTypeAndValue.Type.Equal(util.CountryNameOID) && attrTypeAndValue.Value.Tag != asn1.TagPrintableString { + return &lint.LintResult{Status: lint.Error} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_issuer_dn_country_not_printable_string", + Description: "X520 Distinguished Name Country MUST BE encoded as PrintableString", + Citation: "RFC 5280: Appendix A", + Source: lint.RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &IssuerDNCountryNotPrintableString{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_field_empty.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_field_empty.go new file mode 100644 index 0000000000..c35346a27c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_issuer_field_empty.go @@ -0,0 +1,58 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.1.2.4 +The issuer field identifies the entity that has signed and issued the + certificate. The issuer field MUST contain a non-empty distinguished + name (DN). The issuer field is defined as the X.501 type Name + [X.501]. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type issuerFieldEmpty struct{} + +func (l *issuerFieldEmpty) Initialize() error { + return nil +} + +func (l *issuerFieldEmpty) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *issuerFieldEmpty) Execute(c *x509.Certificate) *lint.LintResult { + if &c.Issuer != nil && util.NotAllNameFieldsAreEmpty(&c.Issuer) { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_issuer_field_empty", + Description: "Certificate issuer field MUST NOT be empty and must have a non-empty distinguished name", + Citation: "RFC 5280: 4.1.2.4", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &issuerFieldEmpty{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_empty.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_empty.go new file mode 100644 index 0000000000..670c529ac5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_empty.go @@ -0,0 +1,79 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************************************** + Restrictions are defined in terms of permitted or excluded name + subtrees. Any name matching a restriction in the excludedSubtrees + field is invalid regardless of information appearing in the + permittedSubtrees. Conforming CAs MUST mark this extension as + critical and SHOULD NOT impose name constraints on the x400Address, + ediPartyName, or registeredID name forms. Conforming CAs MUST NOT + issue certificates where name constraints is an empty sequence. That + is, either the permittedSubtrees field or the excludedSubtrees MUST + be present. +************************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintEmpty struct{} + +func (l *nameConstraintEmpty) Initialize() error { + return nil +} + +func (l *nameConstraintEmpty) CheckApplies(c *x509.Certificate) bool { + if !(util.IsExtInCert(c, util.NameConstOID)) { + return false + } + nc := util.GetExtFromCert(c, util.NameConstOID) + var seq asn1.RawValue + rest, err := asn1.Unmarshal(nc.Value, &seq) //only one sequence, so rest should be empty + if err != nil || len(rest) != 0 || seq.Tag != 16 || seq.Class != 0 || !seq.IsCompound { + return false + } + return true +} + +func (l *nameConstraintEmpty) Execute(c *x509.Certificate) *lint.LintResult { + nc := util.GetExtFromCert(c, util.NameConstOID) + var seq asn1.RawValue + _, err := asn1.Unmarshal(nc.Value, &seq) //only one sequence, so rest should be empty + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(seq.Bytes) == 0 { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_name_constraint_empty", + Description: "Conforming CAs MUST NOT issue certificates where name constraints is an empty sequence. That is, either the permittedSubtree or excludedSubtree fields must be present", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &nameConstraintEmpty{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_maximum_not_absent.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_maximum_not_absent.go new file mode 100644 index 0000000000..f67aecd5dd --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_maximum_not_absent.go @@ -0,0 +1,128 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.10 +Within this profile, the minimum and maximum fields are not used with +any name forms, thus, the minimum MUST be zero, and maximum MUST be +absent. However, if an application encounters a critical name +constraints extension that specifies other values for minimum or +maximum for a name form that appears in a subsequent certificate, the +application MUST either process these fields or reject the +certificate. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintMax struct{} + +func (l *nameConstraintMax) Initialize() error { + return nil +} + +func (l *nameConstraintMax) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +//nolint:gocyclo +func (l *nameConstraintMax) Execute(c *x509.Certificate) *lint.LintResult { + for _, i := range c.PermittedDNSNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedDNSNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedDNSNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedEmailAddresses { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedIPAddresses { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedIPAddresses { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedDirectoryNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedDirectoryNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedEdiPartyNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedEdiPartyNames { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedRegisteredIDs { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedRegisteredIDs { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedX400Addresses { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedX400Addresses { + if i.Max != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_name_constraint_maximum_not_absent", + Description: "Within the name constraints name form, the maximum field is not used and therefore MUST be absent", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &nameConstraintMax{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_minimum_non_zero.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_minimum_non_zero.go new file mode 100644 index 0000000000..c3e64af52a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_minimum_non_zero.go @@ -0,0 +1,128 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +RFC 5280: 4.2.1.10 +Within this profile, the minimum and maximum fields are not used with +any name forms, thus, the minimum MUST be zero, and maximum MUST be +absent. However, if an application encounters a critical name +constraints extension that specifies other values for minimum or +maximum for a name form that appears in a subsequent certificate, the +application MUST either process these fields or reject the +certificate. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstMin struct{} + +func (l *nameConstMin) Initialize() error { + return nil +} + +func (l *nameConstMin) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +//nolint:gocyclo +func (l *nameConstMin) Execute(c *x509.Certificate) *lint.LintResult { + for _, i := range c.PermittedDNSNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedDNSNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedEmailAddresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedEmailAddresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedIPAddresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedIPAddresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedDirectoryNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedDirectoryNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedEdiPartyNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedEdiPartyNames { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedRegisteredIDs { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedRegisteredIDs { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.PermittedX400Addresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + for _, i := range c.ExcludedX400Addresses { + if i.Min != 0 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_name_constraint_minimum_non_zero", + Description: "Within the name constraints name forms, the minimum field is not used and therefore MUST be zero", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &nameConstMin{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_edi_party_name.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_edi_party_name.go new file mode 100644 index 0000000000..c5bbff2a27 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_edi_party_name.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +RFC 5280: 4.2.1.10 +Restrictions are defined in terms of permitted or excluded name +subtrees. Any name matching a restriction in the excludedSubtrees +field is invalid regardless of information appearing in the +permittedSubtrees. Conforming CAs MUST mark this extension as +critical and SHOULD NOT impose name constraints on the x400Address, +ediPartyName, or registeredID name forms. Conforming CAs MUST NOT +issue certificates where name constraints is an empty sequence. That +is, either the permittedSubtrees field or the excludedSubtrees MUST +be present. +*******************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintOnEDI struct{} + +func (l *nameConstraintOnEDI) Initialize() error { + return nil +} + +func (l *nameConstraintOnEDI) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +func (l *nameConstraintOnEDI) Execute(c *x509.Certificate) *lint.LintResult { + if c.PermittedEdiPartyNames != nil || c.ExcludedEdiPartyNames != nil { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_name_constraint_on_edi_party_name", + Description: "The name constraints extension SHOULD NOT impose constraints on the ediPartyName name form", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &nameConstraintOnEDI{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_registered_id.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_registered_id.go new file mode 100644 index 0000000000..889cdaadbf --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_registered_id.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +RFC 5280: 4.2.1.10 +Restrictions are defined in terms of permitted or excluded name +subtrees. Any name matching a restriction in the excludedSubtrees +field is invalid regardless of information appearing in the +permittedSubtrees. Conforming CAs MUST mark this extension as +critical and SHOULD NOT impose name constraints on the x400Address, +ediPartyName, or registeredID name forms. Conforming CAs MUST NOT +issue certificates where name constraints is an empty sequence. That +is, either the permittedSubtrees field or the excludedSubtrees MUST +be present. +*******************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintOnRegisteredId struct{} + +func (l *nameConstraintOnRegisteredId) Initialize() error { + return nil +} + +func (l *nameConstraintOnRegisteredId) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +func (l *nameConstraintOnRegisteredId) Execute(c *x509.Certificate) *lint.LintResult { + if c.PermittedRegisteredIDs != nil || c.ExcludedRegisteredIDs != nil { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_name_constraint_on_registered_id", + Description: "The name constraints extension SHOULD NOT impose constraints on the registeredID name form", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &nameConstraintOnRegisteredId{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_x400.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_x400.go new file mode 100644 index 0000000000..15d68671b6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_name_constraint_on_x400.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +RFC 5280: 4.2.1.10 +Restrictions are defined in terms of permitted or excluded name +subtrees. Any name matching a restriction in the excludedSubtrees +field is invalid regardless of information appearing in the +permittedSubtrees. Conforming CAs MUST mark this extension as +critical and SHOULD NOT impose name constraints on the x400Address, +ediPartyName, or registeredID name forms. Conforming CAs MUST NOT +issue certificates where name constraints is an empty sequence. That +is, either the permittedSubtrees field or the excludedSubtrees MUST +be present. +*******************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type nameConstraintOnX400 struct{} + +func (l *nameConstraintOnX400) Initialize() error { + return nil +} + +func (l *nameConstraintOnX400) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.NameConstOID) +} + +func (l *nameConstraintOnX400) Execute(c *x509.Certificate) *lint.LintResult { + if c.PermittedX400Addresses != nil || c.ExcludedX400Addresses != nil { + return &lint.LintResult{Status: lint.Warn} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "w_name_constraint_on_x400", + Description: "The name constraints extension SHOULD NOT impose constraints on the x400Address name form", + Citation: "RFC 5280: 4.2.1.10", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &nameConstraintOnX400{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_improperly_included.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_improperly_included.go new file mode 100644 index 0000000000..24d7bdeea5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_improperly_included.go @@ -0,0 +1,73 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/****************************************************************** +RFC 5280: 4.2.1.9 +CAs MUST NOT include the pathLenConstraint field unless the cA +boolean is asserted and the key usage extension asserts the +keyCertSign bit. +******************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type pathLenIncluded struct{} + +func (l *pathLenIncluded) Initialize() error { + return nil +} + +func (l *pathLenIncluded) CheckApplies(cert *x509.Certificate) bool { + return util.IsExtInCert(cert, util.BasicConstOID) +} + +func (l *pathLenIncluded) Execute(cert *x509.Certificate) *lint.LintResult { + bc := util.GetExtFromCert(cert, util.BasicConstOID) + var seq asn1.RawValue + var isCa bool + _, err := asn1.Unmarshal(bc.Value, &seq) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(seq.Bytes) == 0 { + return &lint.LintResult{Status: lint.Pass} + } + rest, err := asn1.UnmarshalWithParams(seq.Bytes, &isCa, "optional") + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + keyUsageValue := util.IsExtInCert(cert, util.KeyUsageOID) + if len(rest) > 0 && (!cert.IsCA || !keyUsageValue || (keyUsageValue && cert.KeyUsage&x509.KeyUsageCertSign == 0)) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_path_len_constraint_improperly_included", + Description: "CAs MUST NOT include the pathLenConstraint field unless the CA boolean is asserted and the keyCertSign bit is set", + Citation: "RFC 5280: 4.2.1.9", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &pathLenIncluded{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_zero_or_less.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_zero_or_less.go new file mode 100644 index 0000000000..ae84cca2b9 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_path_len_constraint_zero_or_less.go @@ -0,0 +1,79 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************** +The pathLenConstraint field is meaningful only if the cA boolean is +asserted and the key usage extension, if present, asserts the +keyCertSign bit (Section 4.2.1.3). In this case, it gives the +maximum number of non-self-issued intermediate certificates that may +follow this certificate in a valid certification path. (Note: The +last certificate in the certification path is not an intermediate +certificate, and is not included in this limit. Usually, the last +certificate is an end entity certificate, but it can be a CA +certificate.) A pathLenConstraint of zero indicates that no non- +self-issued intermediate CA certificates may follow in a valid +certification path. Where it appears, the pathLenConstraint field +MUST be greater than or equal to zero. Where pathLenConstraint does +not appear, no limit is imposed. +********************************************************************/ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type basicConst struct { + CA bool `asn1:"optional"` + PathLenConstraint int `asn1:"optional"` +} + +type pathLenNonPositive struct { +} + +func (l *pathLenNonPositive) Initialize() error { + return nil +} + +func (l *pathLenNonPositive) CheckApplies(cert *x509.Certificate) bool { + return cert.BasicConstraintsValid +} + +func (l *pathLenNonPositive) Execute(cert *x509.Certificate) *lint.LintResult { + var bc basicConst + + ext := util.GetExtFromCert(cert, util.BasicConstOID) + if _, err := asn1.Unmarshal(ext.Value, &bc); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if bc.PathLenConstraint < 0 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_path_len_constraint_zero_or_less", + Description: "Where it appears, the pathLenConstraint field MUST be greater than or equal to zero", + Citation: "RFC 5280: 4.2.1.9", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &pathLenNonPositive{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_longer_than_20_octets.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_longer_than_20_octets.go new file mode 100644 index 0000000000..29affc48ad --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_longer_than_20_octets.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: 4.1.2.2. Serial Number + The serial number MUST be a positive integer assigned by the CA to each + certificate. It MUST be unique for each certificate issued by a given CA + (i.e., the issuer name and serial number identify a unique certificate). + CAs MUST force the serialNumber to be a non-negative integer. + + Given the uniqueness requirements above, serial numbers can be expected to + contain long integers. Certificate users MUST be able to handle serialNumber + values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer + than 20 octets. + + Note: Non-conforming CAs may issue certificates with serial numbers that are + negative or zero. Certificate users SHOULD be prepared togracefully handle + such certificates. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type serialNumberTooLong struct{} + +func (l *serialNumberTooLong) Initialize() error { + return nil +} + +func (l *serialNumberTooLong) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *serialNumberTooLong) Execute(c *x509.Certificate) *lint.LintResult { + if c.SerialNumber.BitLen() > 160 { // 20 octets + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_serial_number_longer_than_20_octets", + Description: "Certificates must not have a serial number longer than 20 octets", + Citation: "RFC 5280: 4.1.2.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &serialNumberTooLong{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_not_positive.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_not_positive.go new file mode 100644 index 0000000000..de4ca1b5af --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_serial_number_not_positive.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +4.1.2.2. Serial Number + The serial number MUST be a positive integer assigned by the CA to each + certificate. It MUST be unique for each certificate issued by a given CA + (i.e., the issuer name and serial number identify a unique certificate). + CAs MUST force the serialNumber to be a non-negative integer. + + Given the uniqueness requirements above, serial numbers can be expected to + contain long integers. Certificate users MUST be able to handle serialNumber + values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer + than 20 octets. + + Note: Non-conforming CAs may issue certificates with serial numbers that are + negative or zero. Certificate users SHOULD be prepared togracefully handle + such certificates. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SerialNumberNotPositive struct{} + +func (l *SerialNumberNotPositive) Initialize() error { + return nil +} + +func (l *SerialNumberNotPositive) CheckApplies(cert *x509.Certificate) bool { + return true +} + +func (l *SerialNumberNotPositive) Execute(cert *x509.Certificate) *lint.LintResult { + if cert.SerialNumber.Sign() == -1 { // -1 Means negative when using big.Sign() + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_serial_number_not_positive", + Description: "Certificates must have a positive serial number", + Citation: "RFC 5280: 4.1.2.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &SerialNumberNotPositive{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_spki_rsa_encryption_parameter_not_null.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_spki_rsa_encryption_parameter_not_null.go new file mode 100644 index 0000000000..2688ef0af5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_spki_rsa_encryption_parameter_not_null.go @@ -0,0 +1,66 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"RFC5280: RFC 4055, Section 1.2" +RSA: Encoded algorithm identifier MUST have NULL parameters. +*******************************************************************************************************/ + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type rsaSPKIEncryptionParamNotNULL struct{} + +func (l *rsaSPKIEncryptionParamNotNULL) Initialize() error { + return nil +} + +func (l *rsaSPKIEncryptionParamNotNULL) CheckApplies(c *x509.Certificate) bool { + // explicitly check for util.OidRSAEncryption, as RSA-PSS or RSA-OAEP certificates might be classified with c.PublicKeyAlgorithm = RSA + return c.PublicKeyAlgorithmOID.Equal(util.OidRSAEncryption) +} + +func (l *rsaSPKIEncryptionParamNotNULL) Execute(c *x509.Certificate) *lint.LintResult { + encodedPublicKeyAid, err := util.GetPublicKeyAidEncoded(c) + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("error reading public key algorithm identifier: %v", err), + } + } + + if err := util.CheckAlgorithmIDParamNotNULL(encodedPublicKeyAid, util.OidRSAEncryption); err != nil { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("certificate pkixPublicKey %s", err.Error())} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_spki_rsa_encryption_parameter_not_null", + Description: "RSA: Encoded public key algorithm identifier MUST have NULL parameters", + Citation: "RFC 4055, Section 1.2", + Source: lint.RFC5280, // RFC4055 is referenced in lint.RFC5280, Section 1 + EffectiveDate: util.RFC5280Date, + Lint: &rsaSPKIEncryptionParamNotNULL{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_common_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_common_name_max_length.go new file mode 100644 index 0000000000..7e652b52f5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_common_name_max_length.go @@ -0,0 +1,59 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-common-name INTEGER ::= 64 +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectCommonNameMaxLength struct{} + +func (l *subjectCommonNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectCommonNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectCommonNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + if utf8.RuneCountInString(c.Subject.CommonName) > 64 { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_common_name_max_length", + Description: "The commonName field of the subject MUST be less than 65 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectCommonNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_country_not_printable_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_country_not_printable_string.go new file mode 100644 index 0000000000..be6ef2ec37 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_country_not_printable_string.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectDNCountryNotPrintableString struct{} + +func (l *SubjectDNCountryNotPrintableString) Initialize() error { + return nil +} + +func (l *SubjectDNCountryNotPrintableString) CheckApplies(c *x509.Certificate) bool { + return len(c.Subject.Country) > 0 +} + +func (l *SubjectDNCountryNotPrintableString) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(rest) > 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + if attrTypeAndValue.Type.Equal(util.CountryNameOID) && attrTypeAndValue.Value.Tag != asn1.TagPrintableString { + return &lint.LintResult{Status: lint.Error} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_dn_country_not_printable_string", + Description: "X520 Distinguished Name Country MUST be encoded as PrintableString", + Citation: "RFC 5280: Appendix A", + Source: lint.RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &SubjectDNCountryNotPrintableString{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_not_printable_characters.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_not_printable_characters.go new file mode 100644 index 0000000000..5cda59b484 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_not_printable_characters.go @@ -0,0 +1,74 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package rfc + +import ( + "encoding/asn1" + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectDNNotPrintableCharacters struct{} + +func (l *subjectDNNotPrintableCharacters) Initialize() error { + return nil +} + +func (l *subjectDNNotPrintableCharacters) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectDNNotPrintableCharacters) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(rest) > 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + bytes := attrTypeAndValue.Value.Bytes + for len(bytes) > 0 { + r, size := utf8.DecodeRune(bytes) + if r < 0x20 { + return &lint.LintResult{Status: lint.Error} + } + if r >= 0x7F && r <= 0x9F { + return &lint.LintResult{Status: lint.Error} + } + bytes = bytes[size:] + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_dn_not_printable_characters", + Description: "X520 Subject fields MUST only contain printable control characters", + Citation: "RFC 5280: Appendix A", + Source: lint.RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &subjectDNNotPrintableCharacters{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_max_length.go new file mode 100644 index 0000000000..e58e9149c1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_max_length.go @@ -0,0 +1,51 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectDNSerialNumberMaxLength struct{} + +func (l *SubjectDNSerialNumberMaxLength) Initialize() error { + return nil +} + +func (l *SubjectDNSerialNumberMaxLength) CheckApplies(c *x509.Certificate) bool { + return len(c.Subject.SerialNumber) > 0 +} + +func (l *SubjectDNSerialNumberMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + if utf8.RuneCountInString(c.Subject.SerialNumber) > 64 { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_dn_serial_number_max_length", + Description: "The 'Serial Number' field of the subject MUST be less than 65 characters", + Citation: "RFC 5280: Appendix A", + Source: lint.RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &SubjectDNSerialNumberMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_not_printable_string.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_not_printable_string.go new file mode 100644 index 0000000000..9a2279c1ca --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_dn_serial_number_not_printable_string.go @@ -0,0 +1,65 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type SubjectDNSerialNumberNotPrintableString struct{} + +func (l *SubjectDNSerialNumberNotPrintableString) Initialize() error { + return nil +} + +func (l *SubjectDNSerialNumberNotPrintableString) CheckApplies(c *x509.Certificate) bool { + return len(c.Subject.SerialNumber) > 0 +} + +func (l *SubjectDNSerialNumberNotPrintableString) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if len(rest) > 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + if attrTypeAndValue.Type.Equal(util.SerialOID) && attrTypeAndValue.Value.Tag != asn1.TagPrintableString { + return &lint.LintResult{Status: lint.Error} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_dn_serial_number_not_printable_string", + Description: "X520 Distinguished Name SerialNumber MUST be encoded as PrintableString", + Citation: "RFC 5280: Appendix A", + Source: lint.RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &SubjectDNSerialNumberNotPrintableString{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_email_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_email_max_length.go new file mode 100644 index 0000000000..7eb69589ec --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_email_max_length.go @@ -0,0 +1,68 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-emailaddress-length INTEGER ::= 128 + +The ASN.1 modules in Appendix A are unchanged from RFC 3280, except +that ub-emailaddress-length was changed from 128 to 255 in order to +align with PKCS #9 [RFC2985]. + +ub-emailaddress-length INTEGER ::= 255 + +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectEmailMaxLength struct{} + +func (l *subjectEmailMaxLength) Initialize() error { + return nil +} + +func (l *subjectEmailMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectEmailMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.EmailAddress { + if utf8.RuneCountInString(j) > 255 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_email_max_length", + Description: "The 'Email' field of the subject MUST be less than 256 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectEmailMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_empty_without_san.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_empty_without_san.go new file mode 100644 index 0000000000..7cb963707b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_empty_without_san.go @@ -0,0 +1,67 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************* +RFC 5280: 4.2 & 4.2.1.6 +Further, if the only subject identity included in the certificate is +an alternative name form (e.g., an electronic mail address), then the +subject distinguished name MUST be empty (an empty sequence), and the +subjectAltName extension MUST be present. If the subject field +contains an empty sequence, then the issuing CA MUST include a +subjectAltName extension that is marked as critical. When including +the subjectAltName extension in a certificate that has a non-empty +subject distinguished name, conforming CAs SHOULD mark the +subjectAltName extension as non-critical. +*************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type emptyWithoutSAN struct{} + +func (l *emptyWithoutSAN) Initialize() error { + return nil +} + +func (l *emptyWithoutSAN) CheckApplies(cert *x509.Certificate) bool { + return true +} + +func (l *emptyWithoutSAN) Execute(cert *x509.Certificate) *lint.LintResult { + if subjectIsEmpty(cert) && !util.IsExtInCert(cert, util.SubjectAlternateNameOID) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} + +func subjectIsEmpty(cert *x509.Certificate) bool { + return len(cert.Subject.Names) == 0 +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_empty_without_san", + Description: "CAs MUST support subject alternative name if the subject field is an empty sequence", + Citation: "RFC 5280: 4.2 & 4.2.1.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &emptyWithoutSAN{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_given_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_given_name_max_length.go new file mode 100644 index 0000000000..48d5bc2c9f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_given_name_max_length.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-given-name-length INTEGER ::= 16 + +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectGivenNameMaxLength struct{} + +func (l *subjectGivenNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectGivenNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectGivenNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.GivenName { + if utf8.RuneCountInString(j) > 16 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_given_name_max_length", + Description: "The 'GivenName' field of the subject MUST be less than 17 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectGivenNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_info_access_marked_critical.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_info_access_marked_critical.go new file mode 100644 index 0000000000..66ddc33e51 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_info_access_marked_critical.go @@ -0,0 +1,54 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +The subject information access extension indicates how to access information and services for the subject of the certificate in which the extension appears. When the subject is a CA, information and services may include certificate validation services and CA policy data. When the subject is an end entity, the information describes the type of services offered and how to access them. In this case, the contents of this extension are defined in the protocol specifications for the supported services. This extension may be included in end entity or CA certificates. Conforming CAs MUST mark this extension as non-critical. +************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type siaCrit struct{} + +func (l *siaCrit) Initialize() error { + return nil +} + +func (l *siaCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectInfoAccessOID) +} + +func (l *siaCrit) Execute(c *x509.Certificate) *lint.LintResult { + sia := util.GetExtFromCert(c, util.SubjectInfoAccessOID) + if sia.Critical { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_info_access_marked_critical", + Description: "Conforming CAs MUST mark the Subject Info Access extension as non-critical", + Citation: "RFC 5280: 4.2.2.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC3280Date, + Lint: &siaCrit{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_locality_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_locality_name_max_length.go new file mode 100644 index 0000000000..897e254a3a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_locality_name_max_length.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-locality-name INTEGER ::= 128 +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectLocalityNameMaxLength struct{} + +func (l *subjectLocalityNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectLocalityNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectLocalityNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Locality { + if utf8.RuneCountInString(j) > 128 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_locality_name_max_length", + Description: "The 'Locality Name' field of the subject MUST be less than 129 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectLocalityNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_not_dn.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_not_dn.go new file mode 100644 index 0000000000..670d01e4d2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_not_dn.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************* + RFC 5280: 4.1.2.6 + Where it is non-empty, the subject field MUST contain an X.500 + distinguished name (DN). The DN MUST be unique for each subject + entity certified by the one CA as defined by the issuer name field. A + CA may issue more than one certificate with the same DN to the same + subject entity. +*************************************************************************/ + +import ( + "reflect" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectDN struct{} + +func (l *subjectDN) Initialize() error { + return nil +} + +func (l *subjectDN) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectDN) Execute(c *x509.Certificate) *lint.LintResult { + if reflect.TypeOf(c.Subject) != reflect.TypeOf(*(new(pkix.Name))) { + return &lint.LintResult{Status: lint.Error} + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_not_dn", + Description: "When not empty, the subject field MUST be a distinguished name", + Citation: "RFC 5280: 4.1.2.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectDN{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organization_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organization_name_max_length.go new file mode 100644 index 0000000000..618587e5bb --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organization_name_max_length.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-organization-name INTEGER ::= 64 +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectOrganizationNameMaxLength struct{} + +func (l *subjectOrganizationNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectOrganizationNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectOrganizationNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Organization { + if utf8.RuneCountInString(j) > 64 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_organization_name_max_length", + Description: "The 'Organization Name' field of the subject MUST be less than 65 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectOrganizationNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organizational_unit_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organizational_unit_name_max_length.go new file mode 100644 index 0000000000..e2bf5009d7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_organizational_unit_name_max_length.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-organizational-unit-name INTEGER ::= 64 +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectOrganizationalUnitNameMaxLength struct{} + +func (l *subjectOrganizationalUnitNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectOrganizationalUnitNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectOrganizationalUnitNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.OrganizationalUnit { + if utf8.RuneCountInString(j) > 64 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_organizational_unit_name_max_length", + Description: "The 'Organizational Unit Name' field of the subject MUST be less than 65 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectOrganizationalUnitNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_postal_code_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_postal_code_max_length.go new file mode 100644 index 0000000000..c75f19e630 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_postal_code_max_length.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-postal-code-length INTEGER ::= 16 + +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectPostalCodeMaxLength struct{} + +func (l *subjectPostalCodeMaxLength) Initialize() error { + return nil +} + +func (l *subjectPostalCodeMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectPostalCodeMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.PostalCode { + if utf8.RuneCountInString(j) > 16 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_postal_code_max_length", + Description: "The 'PostalCode' field of the subject MUST be less than 17 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectPostalCodeMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_printable_string_badalpha.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_printable_string_badalpha.go new file mode 100644 index 0000000000..63810a712a --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_printable_string_badalpha.go @@ -0,0 +1,109 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package rfc + +import ( + "encoding/asn1" + "errors" + "fmt" + "regexp" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +var ( + // Per RFC 5280, Appendix B. ASN.1 Notes: + // The character string type PrintableString supports a very basic Latin + // character set: the lowercase letters 'a' through 'z', uppercase + // letters 'A' through 'Z', the digits '0' through '9', eleven special + // characters ' = ( ) + , - . / : ? and space. + printableStringRegex = regexp.MustCompile(`^[a-zA-Z0-9\=\(\)\+,\-.\/:\? ']+$`) +) + +// validatePrintableString returns an error if the provided encoded printable +// string doesn't adhere to the character set defined in RFC 5280. +func validatePrintableString(rawPS []byte) error { + if !printableStringRegex.Match(rawPS) { + return errors.New("encoded PrintableString contained illegal characters") + } + return nil +} + +type subjectPrintableStringBadAlpha struct { +} + +func (l *subjectPrintableStringBadAlpha) Initialize() error { + return nil +} + +// CheckApplies returns true for any certificate with a non-empty RawSubject. +func (l *subjectPrintableStringBadAlpha) CheckApplies(c *x509.Certificate) bool { + return len(c.RawSubject) > 0 +} + +// Execute checks the certificate's RawSubject to ensure that any +// PrintableString attribute/value pairs in the Subject match the character set +// defined for this type in RFC 5280. An lint.Error level lint.LintResult is returned if any +// of the PrintableString attributes do not match a regular expression for the +// allowed character set. +func (l *subjectPrintableStringBadAlpha) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence) + if err != nil { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Failed to Unmarshal RawSubject into RawRDNSequence", + } + } + if len(rest) > 0 { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Trailing data after RawSubject RawRDNSequence", + } + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + // If the attribute type is a PrintableString the bytes of the attribute + // value must match the printable string alphabet. + if attrTypeAndValue.Value.Tag == asn1.TagPrintableString { + if err := validatePrintableString(attrTypeAndValue.Value.Bytes); err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("RawSubject attr oid %s %s", + attrTypeAndValue.Type, err.Error()), + } + } + } + } + } + + return &lint.LintResult{ + Status: lint.Pass, + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_printable_string_badalpha", + Description: "PrintableString type's alphabet only includes a-z, A-Z, 0-9, and 11 special characters", + Citation: "RFC 5280: Appendix B. ASN.1 Notes", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectPrintableStringBadAlpha{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_state_name_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_state_name_max_length.go new file mode 100644 index 0000000000..ce7dacf413 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_state_name_max_length.go @@ -0,0 +1,61 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-state-name INTEGER ::= 128 +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectStateNameMaxLength struct{} + +func (l *subjectStateNameMaxLength) Initialize() error { + return nil +} + +func (l *subjectStateNameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectStateNameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Province { + if utf8.RuneCountInString(j) > 128 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_state_name_max_length", + Description: "The 'State Name' field of the subject MUST be less than 129 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectStateNameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_street_address_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_street_address_max_length.go new file mode 100644 index 0000000000..8ca92605d6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_street_address_max_length.go @@ -0,0 +1,60 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +ITU-T X.520 (02/2001) UpperBounds +ub-street-address INTEGER ::= 128 + +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectStreetAddressMaxLength struct{} + +func (l *subjectStreetAddressMaxLength) Initialize() error { + return nil +} + +func (l *subjectStreetAddressMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectStreetAddressMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.StreetAddress { + if utf8.RuneCountInString(j) > 128 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_street_address_max_length", + Description: "The 'StreetAddress' field of the subject MUST be less than 129 characters", + Citation: "ITU-T X.520 (02/2001) UpperBounds", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectStreetAddressMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_surname_max_length.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_surname_max_length.go new file mode 100644 index 0000000000..58f1c0f75c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_subject_surname_max_length.go @@ -0,0 +1,62 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************ +RFC 5280: A.1 + * In this Appendix, there is a list of upperbounds + for fields in a x509 Certificate. * + ub-surname-length INTEGER ::= 40 + +************************************************/ + +import ( + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type subjectSurnameMaxLength struct{} + +func (l *subjectSurnameMaxLength) Initialize() error { + return nil +} + +func (l *subjectSurnameMaxLength) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectSurnameMaxLength) Execute(c *x509.Certificate) *lint.LintResult { + for _, j := range c.Subject.Surname { + if utf8.RuneCountInString(j) > 40 { + return &lint.LintResult{Status: lint.Error} + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_subject_surname_max_length", + Description: "The 'Surname' field of the subject MUST be less than 41 characters", + Citation: "RFC 5280: A.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &subjectSurnameMaxLength{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_alg_matches_cert_signature_alg.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_alg_matches_cert_signature_alg.go new file mode 100644 index 0000000000..a8fd8c6660 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_alg_matches_cert_signature_alg.go @@ -0,0 +1,88 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************* +RFC 5280: 4.1.1.2 +[the Certificate signatureAlgorithm] field MUST contain the same +algorithm identifier as the signature field in the sequence +tbsCertificate +********************************************************************/ + +package rfc + +import ( + "bytes" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" +) + +type mismatchingSigAlg struct{} + +func (l *mismatchingSigAlg) Initialize() error { + return nil +} + +func (l *mismatchingSigAlg) CheckApplies(_ *x509.Certificate) bool { + return true +} + +func (l *mismatchingSigAlg) Execute(c *x509.Certificate) *lint.LintResult { + // parse out certificate signatureAlgorithm + input := cryptobyte.String(c.Raw) + var cert cryptobyte.String + if !input.ReadASN1(&cert, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate"} + } + var tbsCert cryptobyte.String + if !cert.ReadASN1(&tbsCert, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate.tbsCertificate"} + } + var certSigAlg cryptobyte.String + if !cert.ReadASN1(&certSigAlg, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading certificate.signatureAlgorithm"} + } + + // parse out tbsCertificate signature + if !tbsCert.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.version"} + } + if !tbsCert.SkipASN1(cryptobyte_asn1.INTEGER) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.serialNumber"} + } + var tbsSigAlg cryptobyte.String + if !tbsCert.ReadASN1(&tbsSigAlg, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.signature"} + } + + if !bytes.Equal(certSigAlg, tbsSigAlg) { + return &lint.LintResult{Status: lint.Error} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_cert_sig_alg_not_match_tbs_sig_alg", + Description: "Certificate signature field must match TBSCertificate signature field", + Citation: "RFC 5280, Section 4.1.1.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + Lint: &mismatchingSigAlg{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_rsa_encryption_parameter_not_null.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_rsa_encryption_parameter_not_null.go new file mode 100644 index 0000000000..4b62b5619d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_tbs_signature_rsa_encryption_parameter_not_null.go @@ -0,0 +1,82 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/******************************************************************************************************* +"RFC5280: RFC 4055, Section 5" +RSA: Encoded algorithm identifier MUST have NULL parameters. +*******************************************************************************************************/ + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" +) + +type rsaTBSSignatureEncryptionParamNotNULL struct{} + +func (l *rsaTBSSignatureEncryptionParamNotNULL) Initialize() error { + return nil +} + +func (l *rsaTBSSignatureEncryptionParamNotNULL) CheckApplies(c *x509.Certificate) bool { + _, ok := util.RSAAlgorithmIDToDER[c.SignatureAlgorithmOID.String()] + return ok +} + +func (l *rsaTBSSignatureEncryptionParamNotNULL) Execute(c *x509.Certificate) *lint.LintResult { + input := cryptobyte.String(c.RawTBSCertificate) + + var tbsCert cryptobyte.String + if !input.ReadASN1(&tbsCert, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate"} + } + + if !tbsCert.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.version"} + } + + if !tbsCert.SkipASN1(cryptobyte_asn1.INTEGER) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.serialNumber"} + } + + var signatureAlgoID cryptobyte.String + var tag cryptobyte_asn1.Tag + // use ReadAnyElement to preserve tag and length octets + if !tbsCert.ReadAnyASN1Element(&signatureAlgoID, &tag) { + return &lint.LintResult{Status: lint.Fatal, Details: "error reading tbsCertificate.signature"} + } + + if err := util.CheckAlgorithmIDParamNotNULL(signatureAlgoID, c.SignatureAlgorithmOID); err != nil { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("certificate tbsCertificate.signature %s", err.Error())} + } + + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_tbs_signature_rsa_encryption_parameter_not_null", + Description: "RSA: Encoded signature algorithm identifier MUST have NULL parameters", + Citation: "RFC 4055, Section 5", + Source: lint.RFC5280, // RFC4055 is referenced in RFC5280, Section 1 + EffectiveDate: util.RFC5280Date, + Lint: &rsaTBSSignatureEncryptionParamNotNULL{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_does_not_include_seconds.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_does_not_include_seconds.go new file mode 100644 index 0000000000..83aa0ee92b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_does_not_include_seconds.go @@ -0,0 +1,83 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/************************************************************************ +4.1.2.5.1. UTCTime +The universal time type, UTCTime, is a standard ASN.1 type intended +for representation of dates and time. UTCTime specifies the year +through the two low-order digits and time is specified to the +precision of one minute or one second. UTCTime includes either Z +(for Zulu, or Greenwich Mean Time) or a time differential. +For the purposes of this profile, UTCTime values MUST be expressed in +Greenwich Mean Time (Zulu) and MUST include seconds (i.e., times are +YYMMDDHHMMSSZ), even where the number of seconds is zero. Conforming +systems MUST interpret the year field (YY) as follows: + + Where YY is greater than or equal to 50, the year SHALL be + interpreted as 19YY; and + + Where YY is less than 50, the year SHALL be interpreted as 20YY. +************************************************************************/ + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type utcNoSecond struct { +} + +func (l *utcNoSecond) Initialize() error { + return nil +} + +func (l *utcNoSecond) CheckApplies(c *x509.Certificate) bool { + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Utc := beforeTag == 23 + date2Utc := afterTag == 23 + return date1Utc || date2Utc +} + +func (l *utcNoSecond) Execute(c *x509.Certificate) *lint.LintResult { + date1, date2 := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(date1, date2) + date1Utc := beforeTag == 23 + date2Utc := afterTag == 23 + if date1Utc { + if len(date1.Bytes) != 13 && len(date1.Bytes) != 17 { + return &lint.LintResult{Status: lint.Error} + } + } + if date2Utc { + if len(date2.Bytes) != 13 && len(date2.Bytes) != 17 { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_utc_time_does_not_include_seconds", + Description: "UTCTime values MUST include seconds", + Citation: "RFC 5280: 4.1.2.5.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &utcNoSecond{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_not_in_zulu.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_not_in_zulu.go new file mode 100644 index 0000000000..6a7e735729 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_utc_time_not_in_zulu.go @@ -0,0 +1,98 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/*********************************************************************** +4.1.2.5.1. UTCTime + The universal time type, UTCTime, is a standard ASN.1 type intended + for representation of dates and time. UTCTime specifies the year + through the two low-order digits and time is specified to the + precision of one minute or one second. UTCTime includes either Z + (for Zulu, or Greenwich Mean Time) or a time differential. + + For the purposes of this profile, UTCTime values MUST be expressed in + Greenwich Mean Time (Zulu) and MUST include seconds (i.e., times are + YYMMDDHHMMSSZ), even where the number of seconds is zero. Conforming + systems MUST interpret the year field (YY) as follows: + + Where YY is greater than or equal to 50, the year SHALL be + interpreted as 19YY; and + + Where YY is less than 50, the year SHALL be interpreted as 20YY. +***********************************************************************/ + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type utcTimeGMT struct { +} + +func (l *utcTimeGMT) Initialize() error { + return nil +} + +func (l *utcTimeGMT) CheckApplies(c *x509.Certificate) bool { + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Utc := beforeTag == 23 + date2Utc := afterTag == 23 + return date1Utc || date2Utc +} + +func (l *utcTimeGMT) Execute(c *x509.Certificate) *lint.LintResult { + var r lint.LintStatus + firstDate, secondDate := util.GetTimes(c) + beforeTag, afterTag := util.FindTimeType(firstDate, secondDate) + date1Utc := beforeTag == 23 + date2Utc := afterTag == 23 + if date1Utc { + // UTC Tests on notBefore + utcNotGmt(c.NotBefore, &r) + } + if date2Utc { + // UTC Tests on NotAfter + utcNotGmt(c.NotAfter, &r) + } + return &lint.LintResult{Status: r} +} + +func utcNotGmt(t time.Time, r *lint.LintStatus) { + // If we already ran this test and it resulted in error, don't want to discard that + // And now we use the afterBool to make sure we test the right time + if *r == lint.Error { + return + } + if t.Location() != time.UTC { + *r = lint.Error + } else { + *r = lint.Pass + } +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_utc_time_not_in_zulu", + Description: "UTCTime values MUST be expressed in Greenwich Mean Time (Zulu)", + Citation: "RFC 5280: 4.1.2.5.1", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &utcTimeGMT{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_wrong_time_format_pre2050.go b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_wrong_time_format_pre2050.go new file mode 100644 index 0000000000..f543c3a387 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/lints/rfc/lint_wrong_time_format_pre2050.go @@ -0,0 +1,86 @@ +package rfc + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +/********************************************************************* +CAs conforming to this profile MUST always encode certificate +validity dates through the year 2049 as UTCTime; certificate validity +dates in 2050 or later MUST be encoded as GeneralizedTime. +Conforming applications MUST be able to process validity dates that +are encoded in either UTCTime or GeneralizedTime. +*********************************************************************/ + +import ( + "encoding/asn1" + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + "github.com/zmap/zlint/v2/util" +) + +type generalizedPre2050 struct{} + +func (l *generalizedPre2050) Initialize() error { + return nil +} + +func (l *generalizedPre2050) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *generalizedPre2050) Execute(c *x509.Certificate) *lint.LintResult { + date1, date2 := util.GetTimes(c) + var t time.Time + type1, type2 := util.FindTimeType(date1, date2) + if type1 == 24 { + temp, err := asn1.Marshal(date1) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + _, err = asn1.Unmarshal(temp, &t) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if t.Before(util.GeneralizedDate) { + return &lint.LintResult{Status: lint.Error} + } + } + if type2 == 24 { + temp, err := asn1.Marshal(date2) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + _, err = asn1.Unmarshal(temp, &t) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + if t.Before(util.GeneralizedDate) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_wrong_time_format_pre2050", + Description: "Certificates valid through the year 2049 MUST be encoded in UTC time", + Citation: "RFC 5280: 4.1.2.5", + Source: lint.RFC5280, + EffectiveDate: util.RFC2459Date, + Lint: &generalizedPre2050{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/makefile b/vendor/github.com/zmap/zlint/v2/makefile new file mode 100644 index 0000000000..6fb343ddb4 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/makefile @@ -0,0 +1,42 @@ +SHELL := /bin/bash +# Number of linting Go routines to use in integration tests +PARALLELISM := 5 +# Additional integration test flags. Example usage: +# make integration PARALLELISM=99 INT_FLAGS="-fingerprintSummary -forceDownload" +# make integration INT_FLAGS="-overwriteExpected -config custom.config.json" +# make integration INT_FLAGS="-fingerprintSummary -lintSummary -fingerprintFilter='^[ea]' -lintFilter='^w_ext_cert_policy_explicit_text_not_utf8' -config small.config.json" +# make integration INT_FLAGS="-lintSummary -fingerprintSummary -lintFilter='^e_' -config small.config.json" +# make integration INT_FLAGS="-lintSummary -fingerprintSummary -excludeSources='Mozilla,ETSI_ESI' -config small.config.json" +# make integration INT_FLAGS="-includeSources='Mozilla,ETSI_ESI' -config small.config.json" +INT_FLAGS := + +CMDS = zlint zlint-gtld-update +CMD_PREFIX = ./cmd/ +BUILD = $(GO_ENV) go build +TEST = $(GO_ENV) GORACE=halt_on_error=1 go test -race +INT_TEST = $(GO_ENV) go test -v -tags integration -timeout 20m ./integration/... -parallelism $(PARALLELISM) $(INT_FLAGS) + +all: $(CMDS) + +zlint: + $(BUILD) $(CMD_PREFIX)$(@) + +zlint-gtld-update: + $(BUILD) $(CMD_PREFIX)$(@) + +clean: + rm -f $(CMDS) + +test: + $(TEST) ./... + +integration: + $(INT_TEST) + +code-lint: + golangci-lint run + +testdata-lint: + ./test/prepend_testcerts_openssl.sh && git diff --exit-code testdata/ + +.PHONY: clean zlint zlint-gtld-update test integration code-lint testdata-lint diff --git a/vendor/github.com/zmap/zlint/v2/newLint.sh b/vendor/github.com/zmap/zlint/v2/newLint.sh new file mode 100644 index 0000000000..9bfd13ad70 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/newLint.sh @@ -0,0 +1,50 @@ +# Script to create new lint from template + +USAGE="Usage: $0 + +ARG1: Path_name +ARG2: File_name/TestName (no 'lint_' prefix) +ARG3: Struct_name" + +if [ $# -eq 0 ]; then + echo "No arguments provided..." + echo "$USAGE" + exit 1 +fi + +if [ $# -eq 1 ]; then + echo "Not enough arguments provided..." + echo "$USAGE" + exit 1 +fi + +if [ $# -eq 2 ]; then + echo "Not enough arguments provided..." + echo "$USAGE" + exit 1 +fi + +if [ ! -d lints/$1 ] +then + echo "Directory 'lints/$1' does not exist. Can't make new file." + exit 1 +fi + + +if [ -e lints/$1/lint_$2.go ] +then + echo "File already exists. Can't make new file." + exit 1 +fi + +PATHNAME=$1 +LINTNAME=$2 +# Remove the first two characters from ${LINTNAME} and save the resulting string into FILENAME +FILENAME=${LINTNAME:2} +STRUCTNAME=$3 + +sed -e "s/PACKAGE/${PATHNAME}/" \ + -e "s/SUBST/${STRUCTNAME}/g" \ + -e "s/SUBTEST/${LINTNAME}/g" template > lints/${PATHNAME}/lint_${FILENAME}.go + +echo "Created file lints/${PATHNAME}/lint_${FILENAME}.go with struct name ${STRUCTNAME}" diff --git a/vendor/github.com/zmap/zlint/v2/resultset.go b/vendor/github.com/zmap/zlint/v2/resultset.go new file mode 100644 index 0000000000..bb3a7533f1 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/resultset.go @@ -0,0 +1,58 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package zlint + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" +) + +// ResultSet contains the output of running all lints in a registry against +// a single certificate. +type ResultSet struct { + Version int64 `json:"version"` + Timestamp int64 `json:"timestamp"` + Results map[string]*lint.LintResult `json:"lints"` + NoticesPresent bool `json:"notices_present"` + WarningsPresent bool `json:"warnings_present"` + ErrorsPresent bool `json:"errors_present"` + FatalsPresent bool `json:"fatals_present"` +} + +// Execute lints the given certificate with all of the lints in the provided +// registry. The ResultSet is mutated to trace the lint results obtained from +// linting the certificate. +func (z *ResultSet) execute(cert *x509.Certificate, registry lint.Registry) { + z.Results = make(map[string]*lint.LintResult, len(registry.Names())) + // Run each lints from the registry. + for _, name := range registry.Names() { + res := registry.ByName(name).Execute(cert) + z.Results[name] = res + z.updateErrorStatePresent(res) + } +} + +func (z *ResultSet) updateErrorStatePresent(result *lint.LintResult) { + switch result.Status { + case lint.Notice: + z.NoticesPresent = true + case lint.Warn: + z.WarningsPresent = true + case lint.Error: + z.ErrorsPresent = true + case lint.Fatal: + z.FatalsPresent = true + } +} diff --git a/vendor/github.com/zmap/zlint/v2/template b/vendor/github.com/zmap/zlint/v2/template new file mode 100644 index 0000000000..35ea74b14d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/template @@ -0,0 +1,45 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package PACKAGE + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" +) + +type SUBST struct{} + +func (l *SUBST) Initialize() error { + return nil +} + +func (l *SUBST) CheckApplies(c *x509.Certificate) bool { + // Add conditions for application here +} + +func (l *SUBST) Execute(c *x509.Certificate) *lint.LintResult { + // Add actual lint here +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "SUBTEST", + Description: "Fill this in...", + Citation: "Fill this in...", + Source: UnknownLintSource, + EffectiveDate: "Change this...", + Lint: &SUBST{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/v2/util/algorithm_identifier.go b/vendor/github.com/zmap/zlint/v2/util/algorithm_identifier.go new file mode 100644 index 0000000000..1a3586fb10 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/algorithm_identifier.go @@ -0,0 +1,190 @@ +package util + +import ( + "bytes" + "encoding/asn1" + "errors" + "fmt" + + "github.com/zmap/zcrypto/x509" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" +) + +// additional OIDs not provided by the x509 package +var ( + // 1.2.840.10045.4.3.1 is SHA224withECDSA + OidSignatureSHA224withECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 1} +) + +// RSAAlgorithmIDToDER contains DER representations of pkix.AlgorithmIdentifier for different RSA OIDs with Parameters as asn1.NULL +var RSAAlgorithmIDToDER = map[string][]byte{ + // rsaEncryption + "1.2.840.113549.1.1.1": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0}, + // md2WithRSAEncryption + "1.2.840.113549.1.1.2": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x2, 0x5, 0x0}, + // md5WithRSAEncryption + "1.2.840.113549.1.1.4": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x4, 0x5, 0x0}, + // sha-1WithRSAEncryption + "1.2.840.113549.1.1.5": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5, 0x5, 0x0}, + // sha224WithRSAEncryption + "1.2.840.113549.1.1.14": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xe, 0x5, 0x0}, + // sha256WithRSAEncryption + "1.2.840.113549.1.1.11": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0}, + // sha384WithRSAEncryption + "1.2.840.113549.1.1.12": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xc, 0x5, 0x0}, + // sha512WithRSAEncryption + "1.2.840.113549.1.1.13": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xd, 0x5, 0x0}, +} + +// CheckAlgorithmIDParamNotNULL parses an AlgorithmIdentifier with algorithm OID rsaEncryption to check the Param field is asn1.NULL +// Expects DER-encoded AlgorithmIdentifier including tag and length +func CheckAlgorithmIDParamNotNULL(algorithmIdentifier []byte, requiredAlgoID asn1.ObjectIdentifier) error { + expectedAlgoIDBytes, ok := RSAAlgorithmIDToDER[requiredAlgoID.String()] + if !ok { + return errors.New("error algorithmID to check is not RSA") + } + + algorithmSequence := cryptobyte.String(algorithmIdentifier) + + // byte comparison of algorithm sequence and checking no trailing data is present + var algorithmBytes []byte + if algorithmSequence.ReadBytes(&algorithmBytes, len(expectedAlgoIDBytes)) { + if bytes.Equal(algorithmBytes, expectedAlgoIDBytes) && algorithmSequence.Empty() { + return nil + } + } + + // re-parse to get an error message detailing what did not match in the byte comparison + algorithmSequence = cryptobyte.String(algorithmIdentifier) + var algorithm cryptobyte.String + if !algorithmSequence.ReadASN1(&algorithm, cryptobyte_asn1.SEQUENCE) { + return errors.New("error reading algorithm") + } + + encryptionOID := asn1.ObjectIdentifier{} + if !algorithm.ReadASN1ObjectIdentifier(&encryptionOID) { + return errors.New("error reading algorithm OID") + } + + if !encryptionOID.Equal(requiredAlgoID) { + return fmt.Errorf("algorithm OID is not equal to %s", requiredAlgoID.String()) + } + + if algorithm.Empty() { + return errors.New("RSA algorithm identifier missing required NULL parameter") + } + + var nullValue cryptobyte.String + if !algorithm.ReadASN1(&nullValue, cryptobyte_asn1.NULL) { + return errors.New("RSA algorithm identifier with non-NULL parameter") + } + + if len(nullValue) != 0 { + return errors.New("RSA algorithm identifier with NULL parameter containing data") + } + + // ensure algorithm is empty and no trailing data is present + if !algorithm.Empty() { + return errors.New("RSA algorithm identifier with trailing data") + } + + return errors.New("RSA algorithm appears correct, but didn't match byte-wise comparison") +} + +// Returns the signature field of the tbsCertificate of this certificate in a DER encoded form or an error +// if the signature field could not be extracted. The encoded form contains the tag and the length. +// +// TBSCertificate ::= SEQUENCE { +// version [0] EXPLICIT Version DEFAULT v1, +// serialNumber CertificateSerialNumber, +// signature AlgorithmIdentifier, +// issuer Name, +// validity Validity, +// subject Name, +// subjectPublicKeyInfo SubjectPublicKeyInfo, +// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// extensions [3] EXPLICIT Extensions OPTIONAL +// -- If present, version MUST be v3 +// } +func GetSignatureAlgorithmInTBSEncoded(c *x509.Certificate) ([]byte, error) { + input := cryptobyte.String(c.RawTBSCertificate) + + var tbsCert cryptobyte.String + if !input.ReadASN1(&tbsCert, cryptobyte_asn1.SEQUENCE) { + return nil, errors.New("error reading tbsCertificate") + } + + if !tbsCert.SkipOptionalASN1(cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) { + return nil, errors.New("error reading tbsCertificate.version") + } + + if !tbsCert.SkipASN1(cryptobyte_asn1.INTEGER) { + return nil, errors.New("error reading tbsCertificate.serialNumber") + } + + var signatureAlgoID cryptobyte.String + var tag cryptobyte_asn1.Tag + // use ReadAnyElement to preserve tag and length octets + if !tbsCert.ReadAnyASN1Element(&signatureAlgoID, &tag) { + return nil, errors.New("error reading tbsCertificate.signature") + } + + return signatureAlgoID, nil +} + +// Returns the algorithm field of the SubjectPublicKeyInfo of the certificate or an error +// if the algorithm field could not be extracted. +// +// SubjectPublicKeyInfo ::= SEQUENCE { +// algorithm AlgorithmIdentifier, +// subjectPublicKey BIT STRING } +// +func GetPublicKeyOID(c *x509.Certificate) (asn1.ObjectIdentifier, error) { + input := cryptobyte.String(c.RawSubjectPublicKeyInfo) + + var publicKeyInfo cryptobyte.String + if !input.ReadASN1(&publicKeyInfo, cryptobyte_asn1.SEQUENCE) { + return nil, errors.New("error reading pkixPublicKey") + } + + var algorithm cryptobyte.String + if !publicKeyInfo.ReadASN1(&algorithm, cryptobyte_asn1.SEQUENCE) { + return nil, errors.New("error reading public key algorithm identifier") + } + + publicKeyOID := asn1.ObjectIdentifier{} + if !algorithm.ReadASN1ObjectIdentifier(&publicKeyOID) { + return nil, errors.New("error reading public key OID") + } + + return publicKeyOID, nil +} + +// Returns the algorithm field of the SubjectPublicKeyInfo of the certificate in its encoded form (containing Tag +// and Length) or an error if the algorithm field could not be extracted. +// +// SubjectPublicKeyInfo ::= SEQUENCE { +// algorithm AlgorithmIdentifier, +// subjectPublicKey BIT STRING } +// +func GetPublicKeyAidEncoded(c *x509.Certificate) ([]byte, error) { + input := cryptobyte.String(c.RawSubjectPublicKeyInfo) + var spkiContent cryptobyte.String + + if !input.ReadASN1(&spkiContent, cryptobyte_asn1.SEQUENCE) { + return nil, errors.New("error reading pkixPublicKey") + } + + var algorithm cryptobyte.String + var tag cryptobyte_asn1.Tag + + if !spkiContent.ReadAnyASN1Element(&algorithm, &tag) { + return nil, errors.New("error reading public key algorithm identifier") + } + + return algorithm, nil +} diff --git a/vendor/github.com/zmap/zlint/v2/util/ca.go b/vendor/github.com/zmap/zlint/v2/util/ca.go new file mode 100644 index 0000000000..b4efb0d2ac --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/ca.go @@ -0,0 +1,57 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "github.com/zmap/zcrypto/x509" +) + +// IsCACert returns true if c has IsCA set. +func IsCACert(c *x509.Certificate) bool { + return c.IsCA +} + +// IsRootCA returns true if c has IsCA set and is also self-signed. +func IsRootCA(c *x509.Certificate) bool { + return IsCACert(c) && IsSelfSigned(c) +} + +// IsSubCA returns true if c has IsCA set, but is not self-signed. +func IsSubCA(c *x509.Certificate) bool { + return IsCACert(c) && !IsSelfSigned(c) +} + +// IsSelfSigned returns true if SelfSigned is set. +func IsSelfSigned(c *x509.Certificate) bool { + return c.SelfSigned +} + +// IsSubscriberCert returns true for if a certificate is not a CA and not +// self-signed. +func IsSubscriberCert(c *x509.Certificate) bool { + return !IsCACert(c) && !IsSelfSigned(c) +} + +func IsServerAuthCert(cert *x509.Certificate) bool { + if len(cert.ExtKeyUsage) == 0 { + return true + } + for _, eku := range cert.ExtKeyUsage { + if eku == x509.ExtKeyUsageAny || eku == x509.ExtKeyUsageServerAuth { + return true + } + } + return false +} diff --git a/vendor/github.com/zmap/zlint/v2/util/countries.go b/vendor/github.com/zmap/zlint/v2/util/countries.go new file mode 100644 index 0000000000..afcc57e2ef --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/countries.go @@ -0,0 +1,51 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import "strings" + +var countries = map[string]bool{ + "AD": true, "AE": true, "AF": true, "AG": true, "AI": true, "AL": true, "AM": true, "AN": true, "AO": true, "AQ": true, "AR": true, + "AS": true, "AT": true, "AU": true, "AW": true, "AX": true, "AZ": true, "BA": true, "BB": true, "BD": true, "BE": true, "BF": true, "BG": true, + "BH": true, "BI": true, "BJ": true, "BL": true, "BM": true, "BN": true, "BO": true, "BQ": true, "BR": true, "BS": true, "BT": true, "BV": true, + "BW": true, "BY": true, "BZ": true, "CA": true, "CC": true, "CD": true, "CF": true, "CG": true, "CH": true, "CI": true, "CK": true, "CL": true, + "CM": true, "CN": true, "CO": true, "CR": true, "CU": true, "CV": true, "CW": true, "CX": true, "CY": true, "CZ": true, "DE": true, "DJ": true, + "DK": true, "DM": true, "DO": true, "DZ": true, "EC": true, "EE": true, "EG": true, "EH": true, "ER": true, "ES": true, "ET": true, "FI": true, + "FJ": true, "FK": true, "FM": true, "FO": true, "FR": true, "GA": true, "GB": true, "GD": true, "GE": true, "GF": true, "GG": true, "GH": true, + "GI": true, "GL": true, "GM": true, "GN": true, "GP": true, "GQ": true, "GR": true, "GS": true, "GT": true, "GU": true, "GW": true, "GY": true, + "HK": true, "HM": true, "HN": true, "HR": true, "HT": true, "HU": true, "ID": true, "IE": true, "IL": true, "IM": true, "IN": true, "IO": true, + "IQ": true, "IR": true, "IS": true, "IT": true, "JE": true, "JM": true, "JO": true, "JP": true, "KE": true, "KG": true, "KH": true, "KI": true, + "KM": true, "KN": true, "KP": true, "KR": true, "KW": true, "KY": true, "KZ": true, "LA": true, "LB": true, "LC": true, "LI": true, "LK": true, + "LR": true, "LS": true, "LT": true, "LU": true, "LV": true, "LY": true, "MA": true, "MC": true, "MD": true, "ME": true, "MF": true, "MG": true, + "MH": true, "MK": true, "ML": true, "MM": true, "MN": true, "MO": true, "MP": true, "MQ": true, "MR": true, "MS": true, "MT": true, "MU": true, + "MV": true, "MW": true, "MX": true, "MY": true, "MZ": true, "NA": true, "NC": true, "NE": true, "NF": true, "NG": true, "NI": true, "NL": true, + "NO": true, "NP": true, "NR": true, "NU": true, "NZ": true, "OM": true, "PA": true, "PE": true, "PF": true, "PG": true, "PH": true, "PK": true, + "PL": true, "PM": true, "PN": true, "PR": true, "PS": true, "PT": true, "PW": true, "PY": true, "QA": true, "RE": true, "RO": true, "RS": true, + "RU": true, "RW": true, "SA": true, "SB": true, "SC": true, "SD": true, "SE": true, "SG": true, "SH": true, "SI": true, "SJ": true, "SK": true, + "SL": true, "SM": true, "SN": true, "SO": true, "SR": true, "SS": true, "ST": true, "SV": true, "SX": true, "SY": true, "SZ": true, "TC": true, + "TD": true, "TF": true, "TG": true, "TH": true, "TJ": true, "TK": true, "TL": true, "TM": true, "TN": true, "TO": true, "TR": true, "TT": true, + "TV": true, "TW": true, "TZ": true, "UA": true, "UG": true, "UM": true, "US": true, "UY": true, "UZ": true, "VA": true, "VC": true, "VE": true, + "VG": true, "VI": true, "VN": true, "VU": true, "WF": true, "WS": true, "YE": true, "YT": true, "ZA": true, "ZM": true, "ZW": true, "XX": true, +} + +// IsISOCountryCode returns true if the input is a known two-letter country +// code. +// +// TODO: Document where the list of known countries came from. +func IsISOCountryCode(in string) bool { + in = strings.ToUpper(in) + _, ok := countries[in] + return ok +} diff --git a/vendor/github.com/zmap/zlint/v2/util/eku.go b/vendor/github.com/zmap/zlint/v2/util/eku.go new file mode 100644 index 0000000000..0f690808dc --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/eku.go @@ -0,0 +1,14 @@ +package util + +import "github.com/zmap/zcrypto/x509" + +// HasEKU tests whether an EKU is present in a certificate. +func HasEKU(cert *x509.Certificate, eku x509.ExtKeyUsage) bool { + for _, currentEku := range cert.ExtKeyUsage { + if currentEku == eku { + return true + } + } + + return false +} diff --git a/vendor/github.com/zmap/zlint/v2/util/encodings.go b/vendor/github.com/zmap/zlint/v2/util/encodings.go new file mode 100644 index 0000000000..f85d91f277 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/encodings.go @@ -0,0 +1,136 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "bytes" + "encoding/asn1" + "errors" + "regexp" + "strings" + "unicode" + "unicode/utf16" + + "github.com/zmap/zcrypto/x509/pkix" +) + +// CheckRDNSequenceWhiteSpace returns true if there is leading or trailing +// whitespace in any name attribute in the sequence, respectively. +func CheckRDNSequenceWhiteSpace(raw []byte) (leading, trailing bool, err error) { + var seq pkix.RDNSequence + if _, err = asn1.Unmarshal(raw, &seq); err != nil { + return + } + for _, rdn := range seq { + for _, atv := range rdn { + if !IsNameAttribute(atv.Type) { + continue + } + value, ok := atv.Value.(string) + if !ok { + continue + } + if leftStrip := strings.TrimLeftFunc(value, unicode.IsSpace); leftStrip != value { + leading = true + } + if rightStrip := strings.TrimRightFunc(value, unicode.IsSpace); rightStrip != value { + trailing = true + } + } + } + return +} + +// IsIA5String returns true if raw is an IA5String, and returns false otherwise. +func IsIA5String(raw []byte) bool { + for _, b := range raw { + i := int(b) + if i > 127 || i < 0 { + return false + } + } + return true +} + +func IsInPrefSyn(name string) bool { + // If the DNS name is just a space, it is valid + if name == " " { + return true + } + // This is the expression that matches the ABNF syntax from RFC 1034: Sec 3.5, specifically for subdomain since the " " case for domain is covered above + prefsyn := regexp.MustCompile(`^([[:alpha:]]{1}(([[:alnum:]]|[-])*[[:alnum:]]{1})*){1}([.][[:alpha:]]{1}(([[:alnum:]]|[-])*[[:alnum:]]{1})*)*$`) + return prefsyn.MatchString(name) +} + +// AllAlternateNameWithTagAreIA5 returns true if all sequence members with the +// given tag are encoded as IA5 strings, and false otherwise. If it encounters +// errors parsing asn1, err will be non-nil. +func AllAlternateNameWithTagAreIA5(ext *pkix.Extension, tag int) (bool, error) { + var seq asn1.RawValue + var err error + // Unmarshal the extension as a sequence + if _, err = asn1.Unmarshal(ext.Value, &seq); err != nil { + return false, err + } + // Ensure the sequence matches what we expect for SAN/IAN + if !seq.IsCompound || seq.Tag != asn1.TagSequence || seq.Class != asn1.ClassUniversal { + err = asn1.StructuralError{Msg: "bad alternate name sequence"} + return false, err + } + + // Iterate over the sequence and look for items tagged with tag + rest := seq.Bytes + for len(rest) > 0 { + var v asn1.RawValue + rest, err = asn1.Unmarshal(rest, &v) + if err != nil { + return false, err + } + if v.Tag == tag { + if !IsIA5String(v.Bytes) { + return false, nil + } + } + } + + return true, nil +} + +// IsEmptyASN1Sequence returns true if +// *input is an empty sequence (0x30, 0x00) or +// *len(inout) < 2 +// This check covers more cases than just empty sequence checks but it makes sense from the usage perspective +var emptyASN1Sequence = []byte{0x30, 0x00} + +func IsEmptyASN1Sequence(input []byte) bool { + return len(input) < 2 || bytes.Equal(input, emptyASN1Sequence) +} + +// ParseBMPString returns a uint16 encoded string following the specification for a BMPString type +func ParseBMPString(bmpString []byte) (string, error) { + if len(bmpString)%2 != 0 { + return "", errors.New("odd-length BMP string") + } + // strip terminator if present + if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 { + bmpString = bmpString[:l-2] + } + s := make([]uint16, 0, len(bmpString)/2) + for len(bmpString) > 0 { + s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1])) + bmpString = bmpString[2:] + } + return string(utf16.Decode(s)), nil +} diff --git a/vendor/github.com/zmap/zlint/v2/util/ev.go b/vendor/github.com/zmap/zlint/v2/util/ev.go new file mode 100644 index 0000000000..15c6ad4f50 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/ev.go @@ -0,0 +1,73 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "encoding/asn1" +) + +var evoids = map[string]bool{ + "1.3.159.1.17.1": true, + "1.3.6.1.4.1.34697.2.1": true, + "1.3.6.1.4.1.34697.2.2": true, + "1.3.6.1.4.1.34697.2.3": true, + "1.3.6.1.4.1.34697.2.4": true, + "1.2.40.0.17.1.22": true, + "2.16.578.1.26.1.3.3": true, + "1.3.6.1.4.1.17326.10.14.2.1.2": true, + "1.3.6.1.4.1.17326.10.8.2.1.2": true, + "1.3.6.1.4.1.6449.1.2.1.5.1": true, + "2.16.840.1.114412.2.1": true, + "2.16.840.1.114412.1.3.0.2": true, + "2.16.528.1.1001.1.1.1.12.6.1.1.1": true, + "2.16.792.3.0.4.1.1.4": true, + "2.16.840.1.114028.10.1.2": true, + "0.4.0.2042.1.4": true, + "0.4.0.2042.1.5": true, + "1.3.6.1.4.1.13177.10.1.3.10": true, + "1.3.6.1.4.1.14370.1.6": true, + "1.3.6.1.4.1.4146.1.1": true, + "2.16.840.1.114413.1.7.23.3": true, + "1.3.6.1.4.1.14777.6.1.1": true, + "2.16.792.1.2.1.1.5.7.1.9": true, + "1.3.6.1.4.1.782.1.2.1.8.1": true, + "1.3.6.1.4.1.22234.2.5.2.3.1": true, + "1.3.6.1.4.1.8024.0.2.100.1.2": true, + "1.2.392.200091.100.721.1": true, + "2.16.840.1.114414.1.7.23.3": true, + "1.3.6.1.4.1.23223.2": true, + "1.3.6.1.4.1.23223.1.1.1": true, + "2.16.756.1.83.21.0": true, + "2.16.756.1.89.1.2.1.1": true, + "1.3.6.1.4.1.7879.13.24.1": true, + "2.16.840.1.113733.1.7.48.1": true, + "2.16.840.1.114404.1.1.2.4.1": true, + "2.16.840.1.113733.1.7.23.6": true, + "1.3.6.1.4.1.6334.1.100.1": true, + "2.16.840.1.114171.500.9": true, + "1.3.6.1.4.1.36305.2": true, +} + +// IsEV returns true if the input is a known Extended Validation OID. +func IsEV(in []asn1.ObjectIdentifier) bool { + for _, oid := range in { + if _, ok := evoids[oid.String()]; ok { + return true + } + } + return false +} + +const OnionTLD = ".onion" diff --git a/vendor/github.com/zmap/zlint/v2/util/fqdn.go b/vendor/github.com/zmap/zlint/v2/util/fqdn.go new file mode 100644 index 0000000000..0877c11fa0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/fqdn.go @@ -0,0 +1,124 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "net" + "net/url" + "strings" + + "github.com/weppos/publicsuffix-go/publicsuffix" + zcutil "github.com/zmap/zcrypto/util" + "github.com/zmap/zcrypto/x509" +) + +func RemovePrependedQuestionMarks(domain string) string { + for strings.HasPrefix(domain, "?.") { + domain = domain[2:] + } + return domain +} + +func RemovePrependedWildcard(domain string) string { + return strings.TrimPrefix(domain, "*.") +} + +func IsFQDN(domain string) bool { + domain = RemovePrependedWildcard(domain) + domain = RemovePrependedQuestionMarks(domain) + return zcutil.IsURL(domain) +} + +func GetAuthority(uri string) string { + parsed, err := url.Parse(uri) + if err != nil { + return "" + } + if parsed.Opaque != "" { + // non-empty Opaque means that there is no authority + return "" + } + if len(uri) < 4 { + return "" + } + // https://tools.ietf.org/html/rfc3986#section-3 + // The only time an authority is present is if there is a // after the scheme. + firstColon := strings.Index(uri, ":") + postScheme := uri[firstColon+1:] + // After the scheme, there is the hier-part, optionally followed by a query or fragment. + if !strings.HasPrefix(postScheme, "//") { + // authority is always prefixed by // + return "" + } + for i := 2; i < len(postScheme); i++ { + // in the hier-part, the authority is followed by either an absolute path, or the empty string. + // So, the authority is terminated by the start of an absolute path (/), the start of a fragment (#) or the start of a query(?) + if postScheme[i] == '/' || postScheme[i] == '#' || postScheme[i] == '?' { + return postScheme[2:i] + } + } + // Found no absolute path, fragment or query -- so the authority is the only data after the scheme:// + return postScheme[2:] +} + +func GetHost(auth string) string { + begin := strings.Index(auth, "@") + if begin == len(auth)-1 { + begin = -1 + } + end := strings.Index(auth, ":") + if end == -1 { + end = len(auth) + } + if end < begin { + return "" + } + return auth[begin+1 : end] +} + +func AuthIsFQDNOrIP(auth string) bool { + return IsFQDNOrIP(GetHost(auth)) +} + +func IsFQDNOrIP(host string) bool { + if IsFQDN(host) { + return true + } + if net.ParseIP(host) != nil { + return true + } + return false +} + +func DNSNamesExist(cert *x509.Certificate) bool { + if cert.Subject.CommonName == "" && len(cert.DNSNames) == 0 { + return false + } else { + return true + } +} + +func ICANNPublicSuffixParse(domain string) (*publicsuffix.DomainName, error) { + return publicsuffix.ParseFromListWithOptions(publicsuffix.DefaultList, domain, &publicsuffix.FindOptions{IgnorePrivate: true, DefaultRule: publicsuffix.DefaultRule}) +} + +func CommonNameIsIP(cert *x509.Certificate) bool { + ip := net.ParseIP(cert.Subject.CommonName) + if ip == nil { + return false + } else { + return true + } +} diff --git a/vendor/github.com/zmap/zlint/v2/util/gtld.go b/vendor/github.com/zmap/zlint/v2/util/gtld.go new file mode 100644 index 0000000000..76ae1950b2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/gtld.go @@ -0,0 +1,120 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "fmt" + "strings" + "time" + + "github.com/zmap/zcrypto/x509" +) + +// This package uses the `zlint-gtld-update` command to generate a `tldMap` map. +//go:generate zlint-gtld-update ./gtld_map.go + +const ( + GTLDPeriodDateFormat = "2006-01-02" +) + +// GTLDPeriod is a struct representing a gTLD's validity period. The field names +// are chosen to match the data returned by the ICANN gTLD v2 JSON registry[0]. +// See the `zlint-gtld-update` command for more information. +// [0] - https://www.icann.org/resources/registries/gtlds/v2/gtlds.json +type GTLDPeriod struct { + // GTLD is the GTLD the period corresponds to. It is used only for friendly + // error messages from `Valid` + GTLD string + // DelegationDate is the date at which ICANN delegated the gTLD into existence + // from the root DNS, or is empty if the gTLD was never delegated. + DelegationDate string + // RemovalDate is the date at which ICANN removed the gTLD delegation from the + // root DNS, or is empty if the gTLD is still delegated and has not been + // removed. + RemovalDate string +} + +// Valid determines if the provided `when` time is within the GTLDPeriod for the +// gTLD. E.g. whether a certificate issued at `when` with a subject identifier +// using the specified gTLD can be considered a valid use of the gTLD. +func (p GTLDPeriod) Valid(when time.Time) error { + // NOTE: We can throw away the errors from time.Parse in this function because + // the zlint-gtld-update command only writes entries to the generated gTLD map + // after the dates have been verified as parseable + notBefore, _ := time.Parse(GTLDPeriodDateFormat, p.DelegationDate) + if when.Before(notBefore) { + return fmt.Errorf(`gTLD ".%s" is not valid until %s`, + p.GTLD, p.DelegationDate) + } + // The removal date may be empty. We only need to check `when` against the + // removal when it isn't empty + if p.RemovalDate != "" { + notAfter, _ := time.Parse(GTLDPeriodDateFormat, p.RemovalDate) + if when.After(notAfter) { + return fmt.Errorf(`gTLD ".%s" is not valid after %s`, + p.GTLD, p.RemovalDate) + } + } + return nil +} + +// HasValidTLD checks that a domain ends in a valid TLD that was delegated in +// the root DNS at the time specified. +func HasValidTLD(domain string, when time.Time) bool { + labels := strings.Split(strings.ToLower(domain), ".") + rightLabel := labels[len(labels)-1] + // if the rightmost label is not present in the tldMap, it isn't valid and + // never was. + if tldPeriod, present := tldMap[rightLabel]; !present { + return false + } else if tldPeriod.Valid(when) != nil { + // If the TLD exists but the date is outside of the gTLD's validity period + // then it is not a valid TLD. + return false + } + // Otherwise the TLD exists, and was a valid TLD delegated in the root DNS + // at the time of the given date. + return true +} + +// IsInTLDMap checks that a label is present in the TLD map. It does not +// consider the TLD's validity period and whether the TLD may have been removed, +// only whether it was ever a TLD that was delegated. +func IsInTLDMap(label string) bool { + label = strings.ToLower(label) + if _, ok := tldMap[label]; ok { + return true + } else { + return false + } +} + +// CertificateSubjContainsTLD checks whether the provided Certificate has +// a Subject Common Name or DNS Subject Alternate Name that ends in the provided +// TLD label. If IsInTLDMap(label) returns false then CertificateSubjInTLD will +// return false. +func CertificateSubjInTLD(c *x509.Certificate, label string) bool { + label = strings.ToLower(label) + label = strings.TrimPrefix(label, ".") + if !IsInTLDMap(label) { + return false + } + for _, name := range append(c.DNSNames, c.Subject.CommonName) { + if strings.HasSuffix(name, "."+label) { + return true + } + } + return false +} diff --git a/vendor/github.com/zmap/zlint/v2/util/gtld_map.go b/vendor/github.com/zmap/zlint/v2/util/gtld_map.go new file mode 100644 index 0000000000..d653325c37 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/gtld_map.go @@ -0,0 +1,7875 @@ +// Code generated by go generate; DO NOT EDIT. +// This file was generated by zlint-gtld-update. + +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +var tldMap = map[string]GTLDPeriod{ + "aaa": { + GTLD: "aaa", + DelegationDate: "2015-08-28", + RemovalDate: "", + }, + "aarp": { + GTLD: "aarp", + DelegationDate: "2015-11-03", + RemovalDate: "", + }, + "abarth": { + GTLD: "abarth", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "abb": { + GTLD: "abb", + DelegationDate: "2015-04-25", + RemovalDate: "", + }, + "abbott": { + GTLD: "abbott", + DelegationDate: "2015-03-07", + RemovalDate: "", + }, + "abbvie": { + GTLD: "abbvie", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "abc": { + GTLD: "abc", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "able": { + GTLD: "able", + DelegationDate: "2016-06-21", + RemovalDate: "", + }, + "abogado": { + GTLD: "abogado", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "abudhabi": { + GTLD: "abudhabi", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "ac": { + GTLD: "ac", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "academy": { + GTLD: "academy", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "accenture": { + GTLD: "accenture", + DelegationDate: "2015-05-09", + RemovalDate: "", + }, + "accountant": { + GTLD: "accountant", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "accountants": { + GTLD: "accountants", + DelegationDate: "2014-05-07", + RemovalDate: "", + }, + "aco": { + GTLD: "aco", + DelegationDate: "2015-08-27", + RemovalDate: "", + }, + "active": { + GTLD: "active", + DelegationDate: "2014-06-26", + RemovalDate: "2019-02-17", + }, + "actor": { + GTLD: "actor", + DelegationDate: "2014-02-26", + RemovalDate: "", + }, + "ad": { + GTLD: "ad", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "adac": { + GTLD: "adac", + DelegationDate: "2016-01-26", + RemovalDate: "", + }, + "ads": { + GTLD: "ads", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "adult": { + GTLD: "adult", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "ae": { + GTLD: "ae", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "aeg": { + GTLD: "aeg", + DelegationDate: "2015-06-20", + RemovalDate: "", + }, + "aero": { + GTLD: "aero", + DelegationDate: "2002-03-02", + RemovalDate: "", + }, + "aetna": { + GTLD: "aetna", + DelegationDate: "2016-05-20", + RemovalDate: "", + }, + "af": { + GTLD: "af", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "afamilycompany": { + GTLD: "afamilycompany", + DelegationDate: "2016-07-31", + RemovalDate: "", + }, + "afl": { + GTLD: "afl", + DelegationDate: "2015-03-28", + RemovalDate: "", + }, + "africa": { + GTLD: "africa", + DelegationDate: "2017-02-15", + RemovalDate: "", + }, + "ag": { + GTLD: "ag", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "agakhan": { + GTLD: "agakhan", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "agency": { + GTLD: "agency", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "ai": { + GTLD: "ai", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "aig": { + GTLD: "aig", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "aigo": { + GTLD: "aigo", + DelegationDate: "2016-08-16", + RemovalDate: "2020-06-26", + }, + "airbus": { + GTLD: "airbus", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "airforce": { + GTLD: "airforce", + DelegationDate: "2014-04-30", + RemovalDate: "", + }, + "airtel": { + GTLD: "airtel", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "akdn": { + GTLD: "akdn", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "al": { + GTLD: "al", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "alfaromeo": { + GTLD: "alfaromeo", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "alibaba": { + GTLD: "alibaba", + DelegationDate: "2016-01-16", + RemovalDate: "", + }, + "alipay": { + GTLD: "alipay", + DelegationDate: "2016-01-16", + RemovalDate: "", + }, + "allfinanz": { + GTLD: "allfinanz", + DelegationDate: "2014-10-01", + RemovalDate: "", + }, + "allstate": { + GTLD: "allstate", + DelegationDate: "2016-07-14", + RemovalDate: "", + }, + "ally": { + GTLD: "ally", + DelegationDate: "2016-03-24", + RemovalDate: "", + }, + "alsace": { + GTLD: "alsace", + DelegationDate: "2014-10-04", + RemovalDate: "", + }, + "alstom": { + GTLD: "alstom", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "am": { + GTLD: "am", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "amazon": { + GTLD: "amazon", + DelegationDate: "2020-06-02", + RemovalDate: "", + }, + "americanexpress": { + GTLD: "americanexpress", + DelegationDate: "2016-08-08", + RemovalDate: "", + }, + "americanfamily": { + GTLD: "americanfamily", + DelegationDate: "2016-07-26", + RemovalDate: "", + }, + "amex": { + GTLD: "amex", + DelegationDate: "2016-08-08", + RemovalDate: "", + }, + "amfam": { + GTLD: "amfam", + DelegationDate: "2016-07-23", + RemovalDate: "", + }, + "amica": { + GTLD: "amica", + DelegationDate: "2015-08-29", + RemovalDate: "", + }, + "amsterdam": { + GTLD: "amsterdam", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "analytics": { + GTLD: "analytics", + DelegationDate: "2015-12-21", + RemovalDate: "", + }, + "android": { + GTLD: "android", + DelegationDate: "2014-11-12", + RemovalDate: "", + }, + "anquan": { + GTLD: "anquan", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "anz": { + GTLD: "anz", + DelegationDate: "2016-06-21", + RemovalDate: "", + }, + "ao": { + GTLD: "ao", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "aol": { + GTLD: "aol", + DelegationDate: "2016-11-04", + RemovalDate: "", + }, + "apartments": { + GTLD: "apartments", + DelegationDate: "2015-02-10", + RemovalDate: "", + }, + "app": { + GTLD: "app", + DelegationDate: "2015-07-02", + RemovalDate: "", + }, + "apple": { + GTLD: "apple", + DelegationDate: "2015-11-03", + RemovalDate: "", + }, + "aq": { + GTLD: "aq", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "aquarelle": { + GTLD: "aquarelle", + DelegationDate: "2014-12-02", + RemovalDate: "", + }, + "ar": { + GTLD: "ar", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "arab": { + GTLD: "arab", + DelegationDate: "2017-05-23", + RemovalDate: "", + }, + "aramco": { + GTLD: "aramco", + DelegationDate: "2015-10-15", + RemovalDate: "", + }, + "archi": { + GTLD: "archi", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "army": { + GTLD: "army", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "arpa": { + GTLD: "arpa", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "art": { + GTLD: "art", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "arte": { + GTLD: "arte", + DelegationDate: "2015-10-20", + RemovalDate: "", + }, + "as": { + GTLD: "as", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "asda": { + GTLD: "asda", + DelegationDate: "2016-08-14", + RemovalDate: "", + }, + "asia": { + GTLD: "asia", + DelegationDate: "2007-05-02", + RemovalDate: "", + }, + "associates": { + GTLD: "associates", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "at": { + GTLD: "at", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "athleta": { + GTLD: "athleta", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "attorney": { + GTLD: "attorney", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "au": { + GTLD: "au", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "auction": { + GTLD: "auction", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "audi": { + GTLD: "audi", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "audible": { + GTLD: "audible", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "audio": { + GTLD: "audio", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "auspost": { + GTLD: "auspost", + DelegationDate: "2016-08-17", + RemovalDate: "", + }, + "author": { + GTLD: "author", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "auto": { + GTLD: "auto", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "autos": { + GTLD: "autos", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "avianca": { + GTLD: "avianca", + DelegationDate: "2016-03-09", + RemovalDate: "", + }, + "aw": { + GTLD: "aw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "aws": { + GTLD: "aws", + DelegationDate: "2016-03-25", + RemovalDate: "", + }, + "ax": { + GTLD: "ax", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "axa": { + GTLD: "axa", + DelegationDate: "2014-03-19", + RemovalDate: "", + }, + "az": { + GTLD: "az", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "azure": { + GTLD: "azure", + DelegationDate: "2015-06-06", + RemovalDate: "", + }, + "ba": { + GTLD: "ba", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "baby": { + GTLD: "baby", + DelegationDate: "2016-04-08", + RemovalDate: "", + }, + "baidu": { + GTLD: "baidu", + DelegationDate: "2016-01-05", + RemovalDate: "", + }, + "banamex": { + GTLD: "banamex", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "bananarepublic": { + GTLD: "bananarepublic", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "band": { + GTLD: "band", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "bank": { + GTLD: "bank", + DelegationDate: "2015-01-09", + RemovalDate: "", + }, + "bar": { + GTLD: "bar", + DelegationDate: "2014-02-27", + RemovalDate: "", + }, + "barcelona": { + GTLD: "barcelona", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "barclaycard": { + GTLD: "barclaycard", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "barclays": { + GTLD: "barclays", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "barefoot": { + GTLD: "barefoot", + DelegationDate: "2016-03-24", + RemovalDate: "", + }, + "bargains": { + GTLD: "bargains", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "baseball": { + GTLD: "baseball", + DelegationDate: "2016-10-30", + RemovalDate: "", + }, + "basketball": { + GTLD: "basketball", + DelegationDate: "2016-10-19", + RemovalDate: "", + }, + "bauhaus": { + GTLD: "bauhaus", + DelegationDate: "2015-04-05", + RemovalDate: "", + }, + "bayern": { + GTLD: "bayern", + DelegationDate: "2014-05-03", + RemovalDate: "", + }, + "bb": { + GTLD: "bb", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bbc": { + GTLD: "bbc", + DelegationDate: "2015-03-21", + RemovalDate: "", + }, + "bbt": { + GTLD: "bbt", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "bbva": { + GTLD: "bbva", + DelegationDate: "2015-05-27", + RemovalDate: "", + }, + "bcg": { + GTLD: "bcg", + DelegationDate: "2016-03-09", + RemovalDate: "", + }, + "bcn": { + GTLD: "bcn", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "bd": { + GTLD: "bd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "be": { + GTLD: "be", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "beats": { + GTLD: "beats", + DelegationDate: "2015-11-03", + RemovalDate: "", + }, + "beauty": { + GTLD: "beauty", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "beer": { + GTLD: "beer", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "bentley": { + GTLD: "bentley", + DelegationDate: "2015-07-09", + RemovalDate: "", + }, + "berlin": { + GTLD: "berlin", + DelegationDate: "2014-01-08", + RemovalDate: "", + }, + "best": { + GTLD: "best", + DelegationDate: "2014-02-27", + RemovalDate: "", + }, + "bestbuy": { + GTLD: "bestbuy", + DelegationDate: "2016-07-19", + RemovalDate: "", + }, + "bet": { + GTLD: "bet", + DelegationDate: "2015-07-24", + RemovalDate: "", + }, + "bf": { + GTLD: "bf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bg": { + GTLD: "bg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bh": { + GTLD: "bh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bharti": { + GTLD: "bharti", + DelegationDate: "2015-06-14", + RemovalDate: "", + }, + "bi": { + GTLD: "bi", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bible": { + GTLD: "bible", + DelegationDate: "2015-06-02", + RemovalDate: "", + }, + "bid": { + GTLD: "bid", + DelegationDate: "2014-03-02", + RemovalDate: "", + }, + "bike": { + GTLD: "bike", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "bing": { + GTLD: "bing", + DelegationDate: "2015-06-10", + RemovalDate: "", + }, + "bingo": { + GTLD: "bingo", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "bio": { + GTLD: "bio", + DelegationDate: "2014-06-02", + RemovalDate: "", + }, + "biz": { + GTLD: "biz", + DelegationDate: "2001-09-25", + RemovalDate: "", + }, + "bj": { + GTLD: "bj", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "black": { + GTLD: "black", + DelegationDate: "2014-03-27", + RemovalDate: "", + }, + "blackfriday": { + GTLD: "blackfriday", + DelegationDate: "2014-04-22", + RemovalDate: "", + }, + "blanco": { + GTLD: "blanco", + DelegationDate: "2016-06-21", + RemovalDate: "2019-02-13", + }, + "blockbuster": { + GTLD: "blockbuster", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "blog": { + GTLD: "blog", + DelegationDate: "2016-05-18", + RemovalDate: "", + }, + "bloomberg": { + GTLD: "bloomberg", + DelegationDate: "2014-11-05", + RemovalDate: "", + }, + "blue": { + GTLD: "blue", + DelegationDate: "2014-02-05", + RemovalDate: "", + }, + "bm": { + GTLD: "bm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bms": { + GTLD: "bms", + DelegationDate: "2015-09-22", + RemovalDate: "", + }, + "bmw": { + GTLD: "bmw", + DelegationDate: "2014-06-21", + RemovalDate: "", + }, + "bn": { + GTLD: "bn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bnl": { + GTLD: "bnl", + DelegationDate: "2015-06-26", + RemovalDate: "2019-07-30", + }, + "bnpparibas": { + GTLD: "bnpparibas", + DelegationDate: "2014-08-14", + RemovalDate: "", + }, + "bo": { + GTLD: "bo", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "boats": { + GTLD: "boats", + DelegationDate: "2015-02-25", + RemovalDate: "", + }, + "boehringer": { + GTLD: "boehringer", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "bofa": { + GTLD: "bofa", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "bom": { + GTLD: "bom", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "bond": { + GTLD: "bond", + DelegationDate: "2015-03-27", + RemovalDate: "", + }, + "boo": { + GTLD: "boo", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "book": { + GTLD: "book", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "booking": { + GTLD: "booking", + DelegationDate: "2016-07-23", + RemovalDate: "", + }, + "boots": { + GTLD: "boots", + DelegationDate: "2015-08-05", + RemovalDate: "2018-04-06", + }, + "bosch": { + GTLD: "bosch", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "bostik": { + GTLD: "bostik", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "boston": { + GTLD: "boston", + DelegationDate: "2016-11-29", + RemovalDate: "", + }, + "bot": { + GTLD: "bot", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "boutique": { + GTLD: "boutique", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "box": { + GTLD: "box", + DelegationDate: "2016-11-11", + RemovalDate: "", + }, + "br": { + GTLD: "br", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bradesco": { + GTLD: "bradesco", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "bridgestone": { + GTLD: "bridgestone", + DelegationDate: "2015-05-01", + RemovalDate: "", + }, + "broadway": { + GTLD: "broadway", + DelegationDate: "2015-11-18", + RemovalDate: "", + }, + "broker": { + GTLD: "broker", + DelegationDate: "2015-04-29", + RemovalDate: "", + }, + "brother": { + GTLD: "brother", + DelegationDate: "2015-05-12", + RemovalDate: "", + }, + "brussels": { + GTLD: "brussels", + DelegationDate: "2014-06-18", + RemovalDate: "", + }, + "bs": { + GTLD: "bs", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bt": { + GTLD: "bt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "budapest": { + GTLD: "budapest", + DelegationDate: "2014-09-23", + RemovalDate: "", + }, + "bugatti": { + GTLD: "bugatti", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "build": { + GTLD: "build", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "builders": { + GTLD: "builders", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "business": { + GTLD: "business", + DelegationDate: "2014-08-22", + RemovalDate: "", + }, + "buy": { + GTLD: "buy", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "buzz": { + GTLD: "buzz", + DelegationDate: "2013-12-18", + RemovalDate: "", + }, + "bv": { + GTLD: "bv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bw": { + GTLD: "bw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "by": { + GTLD: "by", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bz": { + GTLD: "bz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "bzh": { + GTLD: "bzh", + DelegationDate: "2014-06-17", + RemovalDate: "", + }, + "ca": { + GTLD: "ca", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cab": { + GTLD: "cab", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "cafe": { + GTLD: "cafe", + DelegationDate: "2015-04-05", + RemovalDate: "", + }, + "cal": { + GTLD: "cal", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "call": { + GTLD: "call", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "calvinklein": { + GTLD: "calvinklein", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "cam": { + GTLD: "cam", + DelegationDate: "2016-06-16", + RemovalDate: "", + }, + "camera": { + GTLD: "camera", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "camp": { + GTLD: "camp", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "cancerresearch": { + GTLD: "cancerresearch", + DelegationDate: "2014-07-03", + RemovalDate: "", + }, + "canon": { + GTLD: "canon", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "capetown": { + GTLD: "capetown", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "capital": { + GTLD: "capital", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "capitalone": { + GTLD: "capitalone", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "car": { + GTLD: "car", + DelegationDate: "2015-09-09", + RemovalDate: "", + }, + "caravan": { + GTLD: "caravan", + DelegationDate: "2014-08-15", + RemovalDate: "", + }, + "cards": { + GTLD: "cards", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "care": { + GTLD: "care", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "career": { + GTLD: "career", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "careers": { + GTLD: "careers", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "cars": { + GTLD: "cars", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "cartier": { + GTLD: "cartier", + DelegationDate: "2014-12-11", + RemovalDate: "2019-11-14", + }, + "casa": { + GTLD: "casa", + DelegationDate: "2014-09-23", + RemovalDate: "", + }, + "case": { + GTLD: "case", + DelegationDate: "2016-10-30", + RemovalDate: "", + }, + "caseih": { + GTLD: "caseih", + DelegationDate: "2016-10-30", + RemovalDate: "", + }, + "cash": { + GTLD: "cash", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "casino": { + GTLD: "casino", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "cat": { + GTLD: "cat", + DelegationDate: "2005-12-20", + RemovalDate: "", + }, + "catering": { + GTLD: "catering", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "catholic": { + GTLD: "catholic", + DelegationDate: "2016-12-01", + RemovalDate: "", + }, + "cba": { + GTLD: "cba", + DelegationDate: "2015-06-22", + RemovalDate: "", + }, + "cbn": { + GTLD: "cbn", + DelegationDate: "2015-02-13", + RemovalDate: "", + }, + "cbre": { + GTLD: "cbre", + DelegationDate: "2016-07-02", + RemovalDate: "", + }, + "cbs": { + GTLD: "cbs", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "cc": { + GTLD: "cc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cd": { + GTLD: "cd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ceb": { + GTLD: "ceb", + DelegationDate: "2015-08-08", + RemovalDate: "", + }, + "center": { + GTLD: "center", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "ceo": { + GTLD: "ceo", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "cern": { + GTLD: "cern", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "cf": { + GTLD: "cf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cfa": { + GTLD: "cfa", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "cfd": { + GTLD: "cfd", + DelegationDate: "2015-03-13", + RemovalDate: "", + }, + "cg": { + GTLD: "cg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ch": { + GTLD: "ch", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "chanel": { + GTLD: "chanel", + DelegationDate: "2015-08-05", + RemovalDate: "", + }, + "channel": { + GTLD: "channel", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "charity": { + GTLD: "charity", + DelegationDate: "2018-06-07", + RemovalDate: "", + }, + "chase": { + GTLD: "chase", + DelegationDate: "2016-02-27", + RemovalDate: "", + }, + "chat": { + GTLD: "chat", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "cheap": { + GTLD: "cheap", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "chintai": { + GTLD: "chintai", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "chloe": { + GTLD: "chloe", + DelegationDate: "2015-03-09", + RemovalDate: "2017-10-06", + }, + "christmas": { + GTLD: "christmas", + DelegationDate: "2014-02-26", + RemovalDate: "", + }, + "chrome": { + GTLD: "chrome", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "chrysler": { + GTLD: "chrysler", + DelegationDate: "2016-07-28", + RemovalDate: "2019-11-19", + }, + "church": { + GTLD: "church", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "ci": { + GTLD: "ci", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cipriani": { + GTLD: "cipriani", + DelegationDate: "2015-10-09", + RemovalDate: "", + }, + "circle": { + GTLD: "circle", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "cisco": { + GTLD: "cisco", + DelegationDate: "2015-05-15", + RemovalDate: "", + }, + "citadel": { + GTLD: "citadel", + DelegationDate: "2016-07-23", + RemovalDate: "", + }, + "citi": { + GTLD: "citi", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "citic": { + GTLD: "citic", + DelegationDate: "2014-04-29", + RemovalDate: "", + }, + "city": { + GTLD: "city", + DelegationDate: "2014-07-10", + RemovalDate: "", + }, + "cityeats": { + GTLD: "cityeats", + DelegationDate: "2015-11-10", + RemovalDate: "", + }, + "ck": { + GTLD: "ck", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cl": { + GTLD: "cl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "claims": { + GTLD: "claims", + DelegationDate: "2014-05-07", + RemovalDate: "", + }, + "cleaning": { + GTLD: "cleaning", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "click": { + GTLD: "click", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "clinic": { + GTLD: "clinic", + DelegationDate: "2014-04-22", + RemovalDate: "", + }, + "clinique": { + GTLD: "clinique", + DelegationDate: "2015-12-28", + RemovalDate: "", + }, + "clothing": { + GTLD: "clothing", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "cloud": { + GTLD: "cloud", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "club": { + GTLD: "club", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "clubmed": { + GTLD: "clubmed", + DelegationDate: "2015-10-02", + RemovalDate: "", + }, + "cm": { + GTLD: "cm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cn": { + GTLD: "cn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "co": { + GTLD: "co", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "coach": { + GTLD: "coach", + DelegationDate: "2014-11-26", + RemovalDate: "", + }, + "codes": { + GTLD: "codes", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "coffee": { + GTLD: "coffee", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "college": { + GTLD: "college", + DelegationDate: "2014-04-10", + RemovalDate: "", + }, + "cologne": { + GTLD: "cologne", + DelegationDate: "2014-03-19", + RemovalDate: "", + }, + "com": { + GTLD: "com", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "comcast": { + GTLD: "comcast", + DelegationDate: "2016-07-07", + RemovalDate: "", + }, + "commbank": { + GTLD: "commbank", + DelegationDate: "2015-06-22", + RemovalDate: "", + }, + "community": { + GTLD: "community", + DelegationDate: "2014-01-25", + RemovalDate: "", + }, + "company": { + GTLD: "company", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "compare": { + GTLD: "compare", + DelegationDate: "2016-01-15", + RemovalDate: "", + }, + "computer": { + GTLD: "computer", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "comsec": { + GTLD: "comsec", + DelegationDate: "2015-11-16", + RemovalDate: "", + }, + "condos": { + GTLD: "condos", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "construction": { + GTLD: "construction", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "consulting": { + GTLD: "consulting", + DelegationDate: "2014-04-01", + RemovalDate: "", + }, + "contact": { + GTLD: "contact", + DelegationDate: "2015-12-22", + RemovalDate: "", + }, + "contractors": { + GTLD: "contractors", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "cooking": { + GTLD: "cooking", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "cookingchannel": { + GTLD: "cookingchannel", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "cool": { + GTLD: "cool", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "coop": { + GTLD: "coop", + DelegationDate: "2001-12-20", + RemovalDate: "", + }, + "corsica": { + GTLD: "corsica", + DelegationDate: "2015-05-16", + RemovalDate: "", + }, + "country": { + GTLD: "country", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "coupon": { + GTLD: "coupon", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "coupons": { + GTLD: "coupons", + DelegationDate: "2015-05-13", + RemovalDate: "", + }, + "courses": { + GTLD: "courses", + DelegationDate: "2015-02-25", + RemovalDate: "", + }, + "cpa": { + GTLD: "cpa", + DelegationDate: "2019-09-20", + RemovalDate: "", + }, + "cr": { + GTLD: "cr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "credit": { + GTLD: "credit", + DelegationDate: "2014-05-07", + RemovalDate: "", + }, + "creditcard": { + GTLD: "creditcard", + DelegationDate: "2014-04-29", + RemovalDate: "", + }, + "creditunion": { + GTLD: "creditunion", + DelegationDate: "2015-11-10", + RemovalDate: "", + }, + "cricket": { + GTLD: "cricket", + DelegationDate: "2014-11-17", + RemovalDate: "", + }, + "crown": { + GTLD: "crown", + DelegationDate: "2015-06-19", + RemovalDate: "", + }, + "crs": { + GTLD: "crs", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "cruise": { + GTLD: "cruise", + DelegationDate: "2016-11-12", + RemovalDate: "", + }, + "cruises": { + GTLD: "cruises", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "csc": { + GTLD: "csc", + DelegationDate: "2015-09-01", + RemovalDate: "", + }, + "cu": { + GTLD: "cu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cuisinella": { + GTLD: "cuisinella", + DelegationDate: "2014-07-03", + RemovalDate: "", + }, + "cv": { + GTLD: "cv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cw": { + GTLD: "cw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cx": { + GTLD: "cx", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cy": { + GTLD: "cy", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "cymru": { + GTLD: "cymru", + DelegationDate: "2014-08-08", + RemovalDate: "", + }, + "cyou": { + GTLD: "cyou", + DelegationDate: "2015-04-03", + RemovalDate: "", + }, + "cz": { + GTLD: "cz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "dabur": { + GTLD: "dabur", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "dad": { + GTLD: "dad", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "dance": { + GTLD: "dance", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "data": { + GTLD: "data", + DelegationDate: "2016-12-20", + RemovalDate: "", + }, + "date": { + GTLD: "date", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "dating": { + GTLD: "dating", + DelegationDate: "2014-01-25", + RemovalDate: "", + }, + "datsun": { + GTLD: "datsun", + DelegationDate: "2015-03-04", + RemovalDate: "", + }, + "day": { + GTLD: "day", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "dclk": { + GTLD: "dclk", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "dds": { + GTLD: "dds", + DelegationDate: "2016-05-11", + RemovalDate: "", + }, + "de": { + GTLD: "de", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "deal": { + GTLD: "deal", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "dealer": { + GTLD: "dealer", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "deals": { + GTLD: "deals", + DelegationDate: "2014-07-10", + RemovalDate: "", + }, + "degree": { + GTLD: "degree", + DelegationDate: "2014-05-30", + RemovalDate: "", + }, + "delivery": { + GTLD: "delivery", + DelegationDate: "2014-11-01", + RemovalDate: "", + }, + "dell": { + GTLD: "dell", + DelegationDate: "2015-10-14", + RemovalDate: "", + }, + "deloitte": { + GTLD: "deloitte", + DelegationDate: "2016-01-29", + RemovalDate: "", + }, + "delta": { + GTLD: "delta", + DelegationDate: "2015-07-11", + RemovalDate: "", + }, + "democrat": { + GTLD: "democrat", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "dental": { + GTLD: "dental", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "dentist": { + GTLD: "dentist", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "desi": { + GTLD: "desi", + DelegationDate: "2014-04-10", + RemovalDate: "", + }, + "design": { + GTLD: "design", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "dev": { + GTLD: "dev", + DelegationDate: "2014-12-18", + RemovalDate: "", + }, + "dhl": { + GTLD: "dhl", + DelegationDate: "2016-06-02", + RemovalDate: "", + }, + "diamonds": { + GTLD: "diamonds", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "diet": { + GTLD: "diet", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "digital": { + GTLD: "digital", + DelegationDate: "2014-05-07", + RemovalDate: "", + }, + "direct": { + GTLD: "direct", + DelegationDate: "2014-07-02", + RemovalDate: "", + }, + "directory": { + GTLD: "directory", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "discount": { + GTLD: "discount", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "discover": { + GTLD: "discover", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "dish": { + GTLD: "dish", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "diy": { + GTLD: "diy", + DelegationDate: "2016-08-25", + RemovalDate: "", + }, + "dj": { + GTLD: "dj", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "dk": { + GTLD: "dk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "dm": { + GTLD: "dm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "dnp": { + GTLD: "dnp", + DelegationDate: "2014-03-11", + RemovalDate: "", + }, + "do": { + GTLD: "do", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "docs": { + GTLD: "docs", + DelegationDate: "2014-12-18", + RemovalDate: "", + }, + "doctor": { + GTLD: "doctor", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "dodge": { + GTLD: "dodge", + DelegationDate: "2016-08-04", + RemovalDate: "2019-11-19", + }, + "dog": { + GTLD: "dog", + DelegationDate: "2015-04-29", + RemovalDate: "", + }, + "doha": { + GTLD: "doha", + DelegationDate: "2015-03-25", + RemovalDate: "2019-04-09", + }, + "domains": { + GTLD: "domains", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "doosan": { + GTLD: "doosan", + DelegationDate: "2014-12-13", + RemovalDate: "2016-02-24", + }, + "dot": { + GTLD: "dot", + DelegationDate: "2016-05-18", + RemovalDate: "", + }, + "download": { + GTLD: "download", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "drive": { + GTLD: "drive", + DelegationDate: "2015-06-20", + RemovalDate: "", + }, + "dtv": { + GTLD: "dtv", + DelegationDate: "2016-05-27", + RemovalDate: "", + }, + "dubai": { + GTLD: "dubai", + DelegationDate: "2016-01-07", + RemovalDate: "", + }, + "duck": { + GTLD: "duck", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "dunlop": { + GTLD: "dunlop", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "duns": { + GTLD: "duns", + DelegationDate: "2016-07-23", + RemovalDate: "2019-08-30", + }, + "dupont": { + GTLD: "dupont", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "durban": { + GTLD: "durban", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "dvag": { + GTLD: "dvag", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "dvr": { + GTLD: "dvr", + DelegationDate: "2016-09-30", + RemovalDate: "", + }, + "dz": { + GTLD: "dz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "earth": { + GTLD: "earth", + DelegationDate: "2015-05-14", + RemovalDate: "", + }, + "eat": { + GTLD: "eat", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "ec": { + GTLD: "ec", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "eco": { + GTLD: "eco", + DelegationDate: "2016-08-28", + RemovalDate: "", + }, + "edeka": { + GTLD: "edeka", + DelegationDate: "2016-01-21", + RemovalDate: "", + }, + "edu": { + GTLD: "edu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "education": { + GTLD: "education", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "ee": { + GTLD: "ee", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "eg": { + GTLD: "eg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "email": { + GTLD: "email", + DelegationDate: "2014-01-02", + RemovalDate: "", + }, + "emerck": { + GTLD: "emerck", + DelegationDate: "2014-10-22", + RemovalDate: "", + }, + "energy": { + GTLD: "energy", + DelegationDate: "2014-11-01", + RemovalDate: "", + }, + "engineer": { + GTLD: "engineer", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "engineering": { + GTLD: "engineering", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "enterprises": { + GTLD: "enterprises", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "epost": { + GTLD: "epost", + DelegationDate: "2016-06-07", + RemovalDate: "2019-02-15", + }, + "epson": { + GTLD: "epson", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "equipment": { + GTLD: "equipment", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "er": { + GTLD: "er", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ericsson": { + GTLD: "ericsson", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "erni": { + GTLD: "erni", + DelegationDate: "2015-03-12", + RemovalDate: "", + }, + "es": { + GTLD: "es", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "esq": { + GTLD: "esq", + DelegationDate: "2014-08-29", + RemovalDate: "", + }, + "estate": { + GTLD: "estate", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "esurance": { + GTLD: "esurance", + DelegationDate: "2016-07-23", + RemovalDate: "2020-05-26", + }, + "et": { + GTLD: "et", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "etisalat": { + GTLD: "etisalat", + DelegationDate: "2017-06-01", + RemovalDate: "", + }, + "eu": { + GTLD: "eu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "eurovision": { + GTLD: "eurovision", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "eus": { + GTLD: "eus", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "events": { + GTLD: "events", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "everbank": { + GTLD: "everbank", + DelegationDate: "2014-11-26", + RemovalDate: "2019-11-14", + }, + "exchange": { + GTLD: "exchange", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "expert": { + GTLD: "expert", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "exposed": { + GTLD: "exposed", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "express": { + GTLD: "express", + DelegationDate: "2015-04-05", + RemovalDate: "", + }, + "extraspace": { + GTLD: "extraspace", + DelegationDate: "2016-03-25", + RemovalDate: "", + }, + "fage": { + GTLD: "fage", + DelegationDate: "2015-08-08", + RemovalDate: "", + }, + "fail": { + GTLD: "fail", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "fairwinds": { + GTLD: "fairwinds", + DelegationDate: "2015-11-13", + RemovalDate: "", + }, + "faith": { + GTLD: "faith", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "family": { + GTLD: "family", + DelegationDate: "2015-08-11", + RemovalDate: "", + }, + "fan": { + GTLD: "fan", + DelegationDate: "2015-03-16", + RemovalDate: "", + }, + "fans": { + GTLD: "fans", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "farm": { + GTLD: "farm", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "farmers": { + GTLD: "farmers", + DelegationDate: "2016-06-25", + RemovalDate: "", + }, + "fashion": { + GTLD: "fashion", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "fast": { + GTLD: "fast", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "fedex": { + GTLD: "fedex", + DelegationDate: "2016-06-25", + RemovalDate: "", + }, + "feedback": { + GTLD: "feedback", + DelegationDate: "2014-04-10", + RemovalDate: "", + }, + "ferrari": { + GTLD: "ferrari", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "ferrero": { + GTLD: "ferrero", + DelegationDate: "2015-11-07", + RemovalDate: "", + }, + "fi": { + GTLD: "fi", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "fiat": { + GTLD: "fiat", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "fidelity": { + GTLD: "fidelity", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "fido": { + GTLD: "fido", + DelegationDate: "2016-09-20", + RemovalDate: "", + }, + "film": { + GTLD: "film", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "final": { + GTLD: "final", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "finance": { + GTLD: "finance", + DelegationDate: "2014-04-29", + RemovalDate: "", + }, + "financial": { + GTLD: "financial", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "fire": { + GTLD: "fire", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "firestone": { + GTLD: "firestone", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "firmdale": { + GTLD: "firmdale", + DelegationDate: "2014-11-20", + RemovalDate: "", + }, + "fish": { + GTLD: "fish", + DelegationDate: "2014-02-21", + RemovalDate: "", + }, + "fishing": { + GTLD: "fishing", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "fit": { + GTLD: "fit", + DelegationDate: "2015-01-09", + RemovalDate: "", + }, + "fitness": { + GTLD: "fitness", + DelegationDate: "2014-04-22", + RemovalDate: "", + }, + "fj": { + GTLD: "fj", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "fk": { + GTLD: "fk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "flickr": { + GTLD: "flickr", + DelegationDate: "2016-02-13", + RemovalDate: "", + }, + "flights": { + GTLD: "flights", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "flir": { + GTLD: "flir", + DelegationDate: "2016-05-10", + RemovalDate: "", + }, + "florist": { + GTLD: "florist", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "flowers": { + GTLD: "flowers", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "flsmidth": { + GTLD: "flsmidth", + DelegationDate: "2014-10-15", + RemovalDate: "2016-07-29", + }, + "fly": { + GTLD: "fly", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "fm": { + GTLD: "fm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "fo": { + GTLD: "fo", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "foo": { + GTLD: "foo", + DelegationDate: "2014-04-19", + RemovalDate: "", + }, + "food": { + GTLD: "food", + DelegationDate: "2016-11-10", + RemovalDate: "", + }, + "foodnetwork": { + GTLD: "foodnetwork", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "football": { + GTLD: "football", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "ford": { + GTLD: "ford", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "forex": { + GTLD: "forex", + DelegationDate: "2015-03-12", + RemovalDate: "", + }, + "forsale": { + GTLD: "forsale", + DelegationDate: "2014-10-01", + RemovalDate: "", + }, + "forum": { + GTLD: "forum", + DelegationDate: "2015-07-01", + RemovalDate: "", + }, + "foundation": { + GTLD: "foundation", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "fox": { + GTLD: "fox", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "fr": { + GTLD: "fr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "free": { + GTLD: "free", + DelegationDate: "2016-11-08", + RemovalDate: "", + }, + "fresenius": { + GTLD: "fresenius", + DelegationDate: "2016-01-09", + RemovalDate: "", + }, + "frl": { + GTLD: "frl", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "frogans": { + GTLD: "frogans", + DelegationDate: "2014-04-19", + RemovalDate: "", + }, + "frontdoor": { + GTLD: "frontdoor", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "frontier": { + GTLD: "frontier", + DelegationDate: "2016-02-06", + RemovalDate: "", + }, + "ftr": { + GTLD: "ftr", + DelegationDate: "2016-04-17", + RemovalDate: "", + }, + "fujitsu": { + GTLD: "fujitsu", + DelegationDate: "2016-07-07", + RemovalDate: "", + }, + "fujixerox": { + GTLD: "fujixerox", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "fun": { + GTLD: "fun", + DelegationDate: "2016-12-21", + RemovalDate: "", + }, + "fund": { + GTLD: "fund", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "furniture": { + GTLD: "furniture", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "futbol": { + GTLD: "futbol", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "fyi": { + GTLD: "fyi", + DelegationDate: "2015-05-22", + RemovalDate: "", + }, + "ga": { + GTLD: "ga", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gal": { + GTLD: "gal", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "gallery": { + GTLD: "gallery", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "gallo": { + GTLD: "gallo", + DelegationDate: "2016-03-22", + RemovalDate: "", + }, + "gallup": { + GTLD: "gallup", + DelegationDate: "2016-02-11", + RemovalDate: "", + }, + "game": { + GTLD: "game", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "games": { + GTLD: "games", + DelegationDate: "2016-06-02", + RemovalDate: "", + }, + "gap": { + GTLD: "gap", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "garden": { + GTLD: "garden", + DelegationDate: "2014-12-13", + RemovalDate: "", + }, + "gay": { + GTLD: "gay", + DelegationDate: "2019-08-09", + RemovalDate: "", + }, + "gb": { + GTLD: "gb", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gbiz": { + GTLD: "gbiz", + DelegationDate: "2014-08-27", + RemovalDate: "", + }, + "gd": { + GTLD: "gd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gdn": { + GTLD: "gdn", + DelegationDate: "2015-02-13", + RemovalDate: "", + }, + "ge": { + GTLD: "ge", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gea": { + GTLD: "gea", + DelegationDate: "2015-08-28", + RemovalDate: "", + }, + "gent": { + GTLD: "gent", + DelegationDate: "2014-07-12", + RemovalDate: "", + }, + "genting": { + GTLD: "genting", + DelegationDate: "2015-06-20", + RemovalDate: "", + }, + "george": { + GTLD: "george", + DelegationDate: "2016-08-18", + RemovalDate: "", + }, + "gf": { + GTLD: "gf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gg": { + GTLD: "gg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ggee": { + GTLD: "ggee", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "gh": { + GTLD: "gh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gi": { + GTLD: "gi", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gift": { + GTLD: "gift", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "gifts": { + GTLD: "gifts", + DelegationDate: "2014-08-08", + RemovalDate: "", + }, + "gives": { + GTLD: "gives", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "giving": { + GTLD: "giving", + DelegationDate: "2015-08-06", + RemovalDate: "", + }, + "gl": { + GTLD: "gl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "glade": { + GTLD: "glade", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "glass": { + GTLD: "glass", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "gle": { + GTLD: "gle", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "global": { + GTLD: "global", + DelegationDate: "2014-06-11", + RemovalDate: "", + }, + "globo": { + GTLD: "globo", + DelegationDate: "2014-05-03", + RemovalDate: "", + }, + "gm": { + GTLD: "gm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gmail": { + GTLD: "gmail", + DelegationDate: "2014-08-27", + RemovalDate: "", + }, + "gmbh": { + GTLD: "gmbh", + DelegationDate: "2016-03-09", + RemovalDate: "", + }, + "gmo": { + GTLD: "gmo", + DelegationDate: "2014-05-03", + RemovalDate: "", + }, + "gmx": { + GTLD: "gmx", + DelegationDate: "2014-09-05", + RemovalDate: "", + }, + "gn": { + GTLD: "gn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "godaddy": { + GTLD: "godaddy", + DelegationDate: "2016-07-07", + RemovalDate: "", + }, + "gold": { + GTLD: "gold", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "goldpoint": { + GTLD: "goldpoint", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "golf": { + GTLD: "golf", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "goo": { + GTLD: "goo", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "goodhands": { + GTLD: "goodhands", + DelegationDate: "2016-07-14", + RemovalDate: "2018-09-20", + }, + "goodyear": { + GTLD: "goodyear", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "goog": { + GTLD: "goog", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "google": { + GTLD: "google", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "gop": { + GTLD: "gop", + DelegationDate: "2014-04-04", + RemovalDate: "", + }, + "got": { + GTLD: "got", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "gov": { + GTLD: "gov", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gp": { + GTLD: "gp", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gq": { + GTLD: "gq", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gr": { + GTLD: "gr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "grainger": { + GTLD: "grainger", + DelegationDate: "2015-11-13", + RemovalDate: "", + }, + "graphics": { + GTLD: "graphics", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "gratis": { + GTLD: "gratis", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "green": { + GTLD: "green", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "gripe": { + GTLD: "gripe", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "grocery": { + GTLD: "grocery", + DelegationDate: "2017-06-28", + RemovalDate: "", + }, + "group": { + GTLD: "group", + DelegationDate: "2015-08-08", + RemovalDate: "", + }, + "gs": { + GTLD: "gs", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gt": { + GTLD: "gt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gu": { + GTLD: "gu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "guardian": { + GTLD: "guardian", + DelegationDate: "2016-05-13", + RemovalDate: "", + }, + "gucci": { + GTLD: "gucci", + DelegationDate: "2015-10-27", + RemovalDate: "", + }, + "guge": { + GTLD: "guge", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "guide": { + GTLD: "guide", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "guitars": { + GTLD: "guitars", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "guru": { + GTLD: "guru", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "gw": { + GTLD: "gw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "gy": { + GTLD: "gy", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hair": { + GTLD: "hair", + DelegationDate: "2016-12-02", + RemovalDate: "", + }, + "hamburg": { + GTLD: "hamburg", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "hangout": { + GTLD: "hangout", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "haus": { + GTLD: "haus", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "hbo": { + GTLD: "hbo", + DelegationDate: "2016-08-14", + RemovalDate: "", + }, + "hdfc": { + GTLD: "hdfc", + DelegationDate: "2016-08-16", + RemovalDate: "", + }, + "hdfcbank": { + GTLD: "hdfcbank", + DelegationDate: "2016-02-11", + RemovalDate: "", + }, + "health": { + GTLD: "health", + DelegationDate: "2016-01-26", + RemovalDate: "", + }, + "healthcare": { + GTLD: "healthcare", + DelegationDate: "2014-07-30", + RemovalDate: "", + }, + "help": { + GTLD: "help", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "helsinki": { + GTLD: "helsinki", + DelegationDate: "2016-01-26", + RemovalDate: "", + }, + "here": { + GTLD: "here", + DelegationDate: "2014-08-29", + RemovalDate: "", + }, + "hermes": { + GTLD: "hermes", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "hgtv": { + GTLD: "hgtv", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "hiphop": { + GTLD: "hiphop", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "hisamitsu": { + GTLD: "hisamitsu", + DelegationDate: "2016-06-02", + RemovalDate: "", + }, + "hitachi": { + GTLD: "hitachi", + DelegationDate: "2015-05-01", + RemovalDate: "", + }, + "hiv": { + GTLD: "hiv", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "hk": { + GTLD: "hk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hkt": { + GTLD: "hkt", + DelegationDate: "2016-05-12", + RemovalDate: "", + }, + "hm": { + GTLD: "hm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hn": { + GTLD: "hn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hockey": { + GTLD: "hockey", + DelegationDate: "2015-05-07", + RemovalDate: "", + }, + "holdings": { + GTLD: "holdings", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "holiday": { + GTLD: "holiday", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "homedepot": { + GTLD: "homedepot", + DelegationDate: "2015-06-04", + RemovalDate: "", + }, + "homegoods": { + GTLD: "homegoods", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "homes": { + GTLD: "homes", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "homesense": { + GTLD: "homesense", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "honda": { + GTLD: "honda", + DelegationDate: "2015-04-30", + RemovalDate: "", + }, + "honeywell": { + GTLD: "honeywell", + DelegationDate: "2016-07-26", + RemovalDate: "2019-06-06", + }, + "horse": { + GTLD: "horse", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "hospital": { + GTLD: "hospital", + DelegationDate: "2016-12-09", + RemovalDate: "", + }, + "host": { + GTLD: "host", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "hosting": { + GTLD: "hosting", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "hot": { + GTLD: "hot", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "hoteles": { + GTLD: "hoteles", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "hotels": { + GTLD: "hotels", + DelegationDate: "2017-04-07", + RemovalDate: "", + }, + "hotmail": { + GTLD: "hotmail", + DelegationDate: "2015-06-10", + RemovalDate: "", + }, + "house": { + GTLD: "house", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "how": { + GTLD: "how", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "hr": { + GTLD: "hr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hsbc": { + GTLD: "hsbc", + DelegationDate: "2015-07-10", + RemovalDate: "", + }, + "ht": { + GTLD: "ht", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "htc": { + GTLD: "htc", + DelegationDate: "2016-04-02", + RemovalDate: "2017-10-24", + }, + "hu": { + GTLD: "hu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "hughes": { + GTLD: "hughes", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "hyatt": { + GTLD: "hyatt", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "hyundai": { + GTLD: "hyundai", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "ibm": { + GTLD: "ibm", + DelegationDate: "2014-10-01", + RemovalDate: "", + }, + "icbc": { + GTLD: "icbc", + DelegationDate: "2015-05-13", + RemovalDate: "", + }, + "ice": { + GTLD: "ice", + DelegationDate: "2015-07-22", + RemovalDate: "", + }, + "icu": { + GTLD: "icu", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "id": { + GTLD: "id", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ie": { + GTLD: "ie", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ieee": { + GTLD: "ieee", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "ifm": { + GTLD: "ifm", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "iinet": { + GTLD: "iinet", + DelegationDate: "2015-07-09", + RemovalDate: "2016-12-21", + }, + "ikano": { + GTLD: "ikano", + DelegationDate: "2016-07-01", + RemovalDate: "", + }, + "il": { + GTLD: "il", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "im": { + GTLD: "im", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "imamat": { + GTLD: "imamat", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "imdb": { + GTLD: "imdb", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "immo": { + GTLD: "immo", + DelegationDate: "2014-08-27", + RemovalDate: "", + }, + "immobilien": { + GTLD: "immobilien", + DelegationDate: "2014-01-02", + RemovalDate: "", + }, + "in": { + GTLD: "in", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "inc": { + GTLD: "inc", + DelegationDate: "2018-07-17", + RemovalDate: "", + }, + "industries": { + GTLD: "industries", + DelegationDate: "2014-02-21", + RemovalDate: "", + }, + "infiniti": { + GTLD: "infiniti", + DelegationDate: "2015-03-04", + RemovalDate: "", + }, + "info": { + GTLD: "info", + DelegationDate: "2001-09-19", + RemovalDate: "", + }, + "ing": { + GTLD: "ing", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "ink": { + GTLD: "ink", + DelegationDate: "2014-03-11", + RemovalDate: "", + }, + "institute": { + GTLD: "institute", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "insurance": { + GTLD: "insurance", + DelegationDate: "2015-12-03", + RemovalDate: "", + }, + "insure": { + GTLD: "insure", + DelegationDate: "2014-04-29", + RemovalDate: "", + }, + "int": { + GTLD: "int", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "intel": { + GTLD: "intel", + DelegationDate: "2016-07-28", + RemovalDate: "2020-10-07", + }, + "international": { + GTLD: "international", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "intuit": { + GTLD: "intuit", + DelegationDate: "2016-07-12", + RemovalDate: "", + }, + "investments": { + GTLD: "investments", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "io": { + GTLD: "io", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ipiranga": { + GTLD: "ipiranga", + DelegationDate: "2015-07-26", + RemovalDate: "", + }, + "iq": { + GTLD: "iq", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ir": { + GTLD: "ir", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "irish": { + GTLD: "irish", + DelegationDate: "2014-12-02", + RemovalDate: "", + }, + "is": { + GTLD: "is", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "iselect": { + GTLD: "iselect", + DelegationDate: "2016-01-15", + RemovalDate: "2019-08-05", + }, + "ismaili": { + GTLD: "ismaili", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "ist": { + GTLD: "ist", + DelegationDate: "2015-07-11", + RemovalDate: "", + }, + "istanbul": { + GTLD: "istanbul", + DelegationDate: "2015-07-11", + RemovalDate: "", + }, + "it": { + GTLD: "it", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "itau": { + GTLD: "itau", + DelegationDate: "2015-07-22", + RemovalDate: "", + }, + "itv": { + GTLD: "itv", + DelegationDate: "2016-06-21", + RemovalDate: "", + }, + "iveco": { + GTLD: "iveco", + DelegationDate: "2016-10-30", + RemovalDate: "", + }, + "iwc": { + GTLD: "iwc", + DelegationDate: "2014-12-13", + RemovalDate: "2018-06-28", + }, + "jaguar": { + GTLD: "jaguar", + DelegationDate: "2015-10-27", + RemovalDate: "", + }, + "java": { + GTLD: "java", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "jcb": { + GTLD: "jcb", + DelegationDate: "2015-01-23", + RemovalDate: "", + }, + "jcp": { + GTLD: "jcp", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "je": { + GTLD: "je", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "jeep": { + GTLD: "jeep", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "jetzt": { + GTLD: "jetzt", + DelegationDate: "2014-03-15", + RemovalDate: "", + }, + "jewelry": { + GTLD: "jewelry", + DelegationDate: "2015-04-16", + RemovalDate: "", + }, + "jio": { + GTLD: "jio", + DelegationDate: "2016-11-15", + RemovalDate: "", + }, + "jlc": { + GTLD: "jlc", + DelegationDate: "2015-06-10", + RemovalDate: "2018-09-18", + }, + "jll": { + GTLD: "jll", + DelegationDate: "2015-05-22", + RemovalDate: "", + }, + "jm": { + GTLD: "jm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "jmp": { + GTLD: "jmp", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "jnj": { + GTLD: "jnj", + DelegationDate: "2016-04-08", + RemovalDate: "", + }, + "jo": { + GTLD: "jo", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "jobs": { + GTLD: "jobs", + DelegationDate: "2005-09-09", + RemovalDate: "", + }, + "joburg": { + GTLD: "joburg", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "jot": { + GTLD: "jot", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "joy": { + GTLD: "joy", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "jp": { + GTLD: "jp", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "jpmorgan": { + GTLD: "jpmorgan", + DelegationDate: "2016-02-27", + RemovalDate: "", + }, + "jprs": { + GTLD: "jprs", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "juegos": { + GTLD: "juegos", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "juniper": { + GTLD: "juniper", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "kaufen": { + GTLD: "kaufen", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "kddi": { + GTLD: "kddi", + DelegationDate: "2015-01-09", + RemovalDate: "", + }, + "ke": { + GTLD: "ke", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kerryhotels": { + GTLD: "kerryhotels", + DelegationDate: "2016-03-05", + RemovalDate: "", + }, + "kerrylogistics": { + GTLD: "kerrylogistics", + DelegationDate: "2016-03-05", + RemovalDate: "", + }, + "kerryproperties": { + GTLD: "kerryproperties", + DelegationDate: "2016-03-05", + RemovalDate: "", + }, + "kfh": { + GTLD: "kfh", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "kg": { + GTLD: "kg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kh": { + GTLD: "kh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ki": { + GTLD: "ki", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kia": { + GTLD: "kia", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "kim": { + GTLD: "kim", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "kinder": { + GTLD: "kinder", + DelegationDate: "2015-10-09", + RemovalDate: "", + }, + "kindle": { + GTLD: "kindle", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "kitchen": { + GTLD: "kitchen", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "kiwi": { + GTLD: "kiwi", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "km": { + GTLD: "km", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kn": { + GTLD: "kn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "koeln": { + GTLD: "koeln", + DelegationDate: "2014-03-05", + RemovalDate: "", + }, + "komatsu": { + GTLD: "komatsu", + DelegationDate: "2015-03-26", + RemovalDate: "", + }, + "kosher": { + GTLD: "kosher", + DelegationDate: "2016-06-10", + RemovalDate: "", + }, + "kp": { + GTLD: "kp", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kpmg": { + GTLD: "kpmg", + DelegationDate: "2016-04-05", + RemovalDate: "", + }, + "kpn": { + GTLD: "kpn", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "kr": { + GTLD: "kr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "krd": { + GTLD: "krd", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "kred": { + GTLD: "kred", + DelegationDate: "2014-02-27", + RemovalDate: "", + }, + "kuokgroup": { + GTLD: "kuokgroup", + DelegationDate: "2016-03-05", + RemovalDate: "", + }, + "kw": { + GTLD: "kw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ky": { + GTLD: "ky", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "kyoto": { + GTLD: "kyoto", + DelegationDate: "2015-01-28", + RemovalDate: "", + }, + "kz": { + GTLD: "kz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "la": { + GTLD: "la", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "lacaixa": { + GTLD: "lacaixa", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "ladbrokes": { + GTLD: "ladbrokes", + DelegationDate: "2016-07-29", + RemovalDate: "2019-11-19", + }, + "lamborghini": { + GTLD: "lamborghini", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "lamer": { + GTLD: "lamer", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "lancaster": { + GTLD: "lancaster", + DelegationDate: "2015-07-15", + RemovalDate: "", + }, + "lancia": { + GTLD: "lancia", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "lancome": { + GTLD: "lancome", + DelegationDate: "2016-07-15", + RemovalDate: "2019-11-28", + }, + "land": { + GTLD: "land", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "landrover": { + GTLD: "landrover", + DelegationDate: "2015-10-27", + RemovalDate: "", + }, + "lanxess": { + GTLD: "lanxess", + DelegationDate: "2016-01-26", + RemovalDate: "", + }, + "lasalle": { + GTLD: "lasalle", + DelegationDate: "2015-06-11", + RemovalDate: "", + }, + "lat": { + GTLD: "lat", + DelegationDate: "2015-01-09", + RemovalDate: "", + }, + "latino": { + GTLD: "latino", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "latrobe": { + GTLD: "latrobe", + DelegationDate: "2014-12-02", + RemovalDate: "", + }, + "law": { + GTLD: "law", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "lawyer": { + GTLD: "lawyer", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "lb": { + GTLD: "lb", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "lc": { + GTLD: "lc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "lds": { + GTLD: "lds", + DelegationDate: "2014-11-19", + RemovalDate: "", + }, + "lease": { + GTLD: "lease", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "leclerc": { + GTLD: "leclerc", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "lefrak": { + GTLD: "lefrak", + DelegationDate: "2016-07-14", + RemovalDate: "", + }, + "legal": { + GTLD: "legal", + DelegationDate: "2014-11-26", + RemovalDate: "", + }, + "lego": { + GTLD: "lego", + DelegationDate: "2016-06-16", + RemovalDate: "", + }, + "lexus": { + GTLD: "lexus", + DelegationDate: "2015-07-26", + RemovalDate: "", + }, + "lgbt": { + GTLD: "lgbt", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "li": { + GTLD: "li", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "liaison": { + GTLD: "liaison", + DelegationDate: "2015-05-02", + RemovalDate: "2020-01-04", + }, + "lidl": { + GTLD: "lidl", + DelegationDate: "2014-12-13", + RemovalDate: "", + }, + "life": { + GTLD: "life", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "lifeinsurance": { + GTLD: "lifeinsurance", + DelegationDate: "2016-01-19", + RemovalDate: "", + }, + "lifestyle": { + GTLD: "lifestyle", + DelegationDate: "2015-11-10", + RemovalDate: "", + }, + "lighting": { + GTLD: "lighting", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "like": { + GTLD: "like", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "lilly": { + GTLD: "lilly", + DelegationDate: "2016-07-31", + RemovalDate: "", + }, + "limited": { + GTLD: "limited", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "limo": { + GTLD: "limo", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "lincoln": { + GTLD: "lincoln", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "linde": { + GTLD: "linde", + DelegationDate: "2015-09-16", + RemovalDate: "", + }, + "link": { + GTLD: "link", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "lipsy": { + GTLD: "lipsy", + DelegationDate: "2016-05-03", + RemovalDate: "", + }, + "live": { + GTLD: "live", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "living": { + GTLD: "living", + DelegationDate: "2015-12-28", + RemovalDate: "", + }, + "lixil": { + GTLD: "lixil", + DelegationDate: "2015-07-30", + RemovalDate: "", + }, + "lk": { + GTLD: "lk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "llc": { + GTLD: "llc", + DelegationDate: "2018-02-22", + RemovalDate: "", + }, + "llp": { + GTLD: "llp", + DelegationDate: "2019-12-05", + RemovalDate: "", + }, + "loan": { + GTLD: "loan", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "loans": { + GTLD: "loans", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "locker": { + GTLD: "locker", + DelegationDate: "2016-05-27", + RemovalDate: "", + }, + "locus": { + GTLD: "locus", + DelegationDate: "2016-03-09", + RemovalDate: "", + }, + "loft": { + GTLD: "loft", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "lol": { + GTLD: "lol", + DelegationDate: "2015-05-02", + RemovalDate: "", + }, + "london": { + GTLD: "london", + DelegationDate: "2014-03-22", + RemovalDate: "", + }, + "lotte": { + GTLD: "lotte", + DelegationDate: "2015-01-14", + RemovalDate: "", + }, + "lotto": { + GTLD: "lotto", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "love": { + GTLD: "love", + DelegationDate: "2015-04-02", + RemovalDate: "", + }, + "lpl": { + GTLD: "lpl", + DelegationDate: "2016-07-19", + RemovalDate: "", + }, + "lplfinancial": { + GTLD: "lplfinancial", + DelegationDate: "2016-07-19", + RemovalDate: "", + }, + "lr": { + GTLD: "lr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ls": { + GTLD: "ls", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "lt": { + GTLD: "lt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ltd": { + GTLD: "ltd", + DelegationDate: "2015-09-23", + RemovalDate: "", + }, + "ltda": { + GTLD: "ltda", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "lu": { + GTLD: "lu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "lundbeck": { + GTLD: "lundbeck", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "lupin": { + GTLD: "lupin", + DelegationDate: "2015-05-16", + RemovalDate: "", + }, + "luxe": { + GTLD: "luxe", + DelegationDate: "2014-05-15", + RemovalDate: "", + }, + "luxury": { + GTLD: "luxury", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "lv": { + GTLD: "lv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ly": { + GTLD: "ly", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ma": { + GTLD: "ma", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "macys": { + GTLD: "macys", + DelegationDate: "2016-07-12", + RemovalDate: "", + }, + "madrid": { + GTLD: "madrid", + DelegationDate: "2014-11-20", + RemovalDate: "", + }, + "maif": { + GTLD: "maif", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "maison": { + GTLD: "maison", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "makeup": { + GTLD: "makeup", + DelegationDate: "2016-01-15", + RemovalDate: "", + }, + "man": { + GTLD: "man", + DelegationDate: "2015-07-26", + RemovalDate: "", + }, + "management": { + GTLD: "management", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "mango": { + GTLD: "mango", + DelegationDate: "2014-02-16", + RemovalDate: "", + }, + "map": { + GTLD: "map", + DelegationDate: "2017-06-29", + RemovalDate: "", + }, + "market": { + GTLD: "market", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "marketing": { + GTLD: "marketing", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "markets": { + GTLD: "markets", + DelegationDate: "2015-03-12", + RemovalDate: "", + }, + "marriott": { + GTLD: "marriott", + DelegationDate: "2015-01-14", + RemovalDate: "", + }, + "marshalls": { + GTLD: "marshalls", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "maserati": { + GTLD: "maserati", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "mattel": { + GTLD: "mattel", + DelegationDate: "2016-05-28", + RemovalDate: "", + }, + "mba": { + GTLD: "mba", + DelegationDate: "2015-05-22", + RemovalDate: "", + }, + "mc": { + GTLD: "mc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mcd": { + GTLD: "mcd", + DelegationDate: "2016-08-08", + RemovalDate: "2017-08-31", + }, + "mcdonalds": { + GTLD: "mcdonalds", + DelegationDate: "2016-08-08", + RemovalDate: "2017-08-31", + }, + "mckinsey": { + GTLD: "mckinsey", + DelegationDate: "2016-07-31", + RemovalDate: "", + }, + "md": { + GTLD: "md", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "me": { + GTLD: "me", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "med": { + GTLD: "med", + DelegationDate: "2015-12-03", + RemovalDate: "", + }, + "media": { + GTLD: "media", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "meet": { + GTLD: "meet", + DelegationDate: "2014-03-27", + RemovalDate: "", + }, + "melbourne": { + GTLD: "melbourne", + DelegationDate: "2014-07-10", + RemovalDate: "", + }, + "meme": { + GTLD: "meme", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "memorial": { + GTLD: "memorial", + DelegationDate: "2014-11-26", + RemovalDate: "", + }, + "men": { + GTLD: "men", + DelegationDate: "2015-05-20", + RemovalDate: "", + }, + "menu": { + GTLD: "menu", + DelegationDate: "2013-11-30", + RemovalDate: "", + }, + "meo": { + GTLD: "meo", + DelegationDate: "2015-10-29", + RemovalDate: "2018-05-26", + }, + "merckmsd": { + GTLD: "merckmsd", + DelegationDate: "2017-07-10", + RemovalDate: "", + }, + "metlife": { + GTLD: "metlife", + DelegationDate: "2016-05-11", + RemovalDate: "2020-09-07", + }, + "mg": { + GTLD: "mg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mh": { + GTLD: "mh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "miami": { + GTLD: "miami", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "microsoft": { + GTLD: "microsoft", + DelegationDate: "2015-06-10", + RemovalDate: "", + }, + "mil": { + GTLD: "mil", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mini": { + GTLD: "mini", + DelegationDate: "2014-06-24", + RemovalDate: "", + }, + "mint": { + GTLD: "mint", + DelegationDate: "2016-07-12", + RemovalDate: "", + }, + "mit": { + GTLD: "mit", + DelegationDate: "2016-07-06", + RemovalDate: "", + }, + "mitsubishi": { + GTLD: "mitsubishi", + DelegationDate: "2016-07-07", + RemovalDate: "", + }, + "mk": { + GTLD: "mk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ml": { + GTLD: "ml", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mlb": { + GTLD: "mlb", + DelegationDate: "2016-05-25", + RemovalDate: "", + }, + "mls": { + GTLD: "mls", + DelegationDate: "2016-04-20", + RemovalDate: "", + }, + "mm": { + GTLD: "mm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mma": { + GTLD: "mma", + DelegationDate: "2015-03-31", + RemovalDate: "", + }, + "mn": { + GTLD: "mn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mo": { + GTLD: "mo", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mobi": { + GTLD: "mobi", + DelegationDate: "2005-10-20", + RemovalDate: "", + }, + "mobile": { + GTLD: "mobile", + DelegationDate: "2016-12-20", + RemovalDate: "", + }, + "mobily": { + GTLD: "mobily", + DelegationDate: "2015-12-23", + RemovalDate: "2019-09-09", + }, + "moda": { + GTLD: "moda", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "moe": { + GTLD: "moe", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "moi": { + GTLD: "moi", + DelegationDate: "2015-10-07", + RemovalDate: "", + }, + "mom": { + GTLD: "mom", + DelegationDate: "2015-08-19", + RemovalDate: "", + }, + "monash": { + GTLD: "monash", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "money": { + GTLD: "money", + DelegationDate: "2014-11-26", + RemovalDate: "", + }, + "monster": { + GTLD: "monster", + DelegationDate: "2016-09-14", + RemovalDate: "", + }, + "montblanc": { + GTLD: "montblanc", + DelegationDate: "2015-06-05", + RemovalDate: "2017-09-01", + }, + "mopar": { + GTLD: "mopar", + DelegationDate: "2016-08-02", + RemovalDate: "2019-11-19", + }, + "mormon": { + GTLD: "mormon", + DelegationDate: "2014-11-19", + RemovalDate: "", + }, + "mortgage": { + GTLD: "mortgage", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "moscow": { + GTLD: "moscow", + DelegationDate: "2014-04-24", + RemovalDate: "", + }, + "moto": { + GTLD: "moto", + DelegationDate: "2016-11-12", + RemovalDate: "", + }, + "motorcycles": { + GTLD: "motorcycles", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "mov": { + GTLD: "mov", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "movie": { + GTLD: "movie", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "movistar": { + GTLD: "movistar", + DelegationDate: "2015-06-26", + RemovalDate: "2019-12-23", + }, + "mp": { + GTLD: "mp", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mq": { + GTLD: "mq", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mr": { + GTLD: "mr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ms": { + GTLD: "ms", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "msd": { + GTLD: "msd", + DelegationDate: "2016-07-23", + RemovalDate: "", + }, + "mt": { + GTLD: "mt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mtn": { + GTLD: "mtn", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "mtpc": { + GTLD: "mtpc", + DelegationDate: "2015-03-04", + RemovalDate: "2017-05-15", + }, + "mtr": { + GTLD: "mtr", + DelegationDate: "2015-10-07", + RemovalDate: "", + }, + "mu": { + GTLD: "mu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "museum": { + GTLD: "museum", + DelegationDate: "2001-11-01", + RemovalDate: "", + }, + "mutual": { + GTLD: "mutual", + DelegationDate: "2016-04-05", + RemovalDate: "", + }, + "mutuelle": { + GTLD: "mutuelle", + DelegationDate: "2015-10-23", + RemovalDate: "2016-12-21", + }, + "mv": { + GTLD: "mv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mw": { + GTLD: "mw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mx": { + GTLD: "mx", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "my": { + GTLD: "my", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "mz": { + GTLD: "mz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "na": { + GTLD: "na", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nab": { + GTLD: "nab", + DelegationDate: "2016-08-18", + RemovalDate: "", + }, + "nadex": { + GTLD: "nadex", + DelegationDate: "2015-05-02", + RemovalDate: "2020-03-27", + }, + "nagoya": { + GTLD: "nagoya", + DelegationDate: "2014-01-29", + RemovalDate: "", + }, + "name": { + GTLD: "name", + DelegationDate: "2002-01-04", + RemovalDate: "", + }, + "nationwide": { + GTLD: "nationwide", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "natura": { + GTLD: "natura", + DelegationDate: "2016-02-11", + RemovalDate: "", + }, + "navy": { + GTLD: "navy", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "nba": { + GTLD: "nba", + DelegationDate: "2016-08-02", + RemovalDate: "", + }, + "nc": { + GTLD: "nc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ne": { + GTLD: "ne", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nec": { + GTLD: "nec", + DelegationDate: "2015-05-09", + RemovalDate: "", + }, + "net": { + GTLD: "net", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "netbank": { + GTLD: "netbank", + DelegationDate: "2015-06-22", + RemovalDate: "", + }, + "netflix": { + GTLD: "netflix", + DelegationDate: "2016-05-28", + RemovalDate: "", + }, + "network": { + GTLD: "network", + DelegationDate: "2014-08-22", + RemovalDate: "", + }, + "neustar": { + GTLD: "neustar", + DelegationDate: "2014-02-19", + RemovalDate: "", + }, + "new": { + GTLD: "new", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "newholland": { + GTLD: "newholland", + DelegationDate: "2016-10-30", + RemovalDate: "", + }, + "news": { + GTLD: "news", + DelegationDate: "2015-03-21", + RemovalDate: "", + }, + "next": { + GTLD: "next", + DelegationDate: "2016-05-03", + RemovalDate: "", + }, + "nextdirect": { + GTLD: "nextdirect", + DelegationDate: "2016-05-03", + RemovalDate: "", + }, + "nexus": { + GTLD: "nexus", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "nf": { + GTLD: "nf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nfl": { + GTLD: "nfl", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "ng": { + GTLD: "ng", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ngo": { + GTLD: "ngo", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "nhk": { + GTLD: "nhk", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "ni": { + GTLD: "ni", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nico": { + GTLD: "nico", + DelegationDate: "2015-02-10", + RemovalDate: "", + }, + "nike": { + GTLD: "nike", + DelegationDate: "2016-07-09", + RemovalDate: "", + }, + "nikon": { + GTLD: "nikon", + DelegationDate: "2016-01-28", + RemovalDate: "", + }, + "ninja": { + GTLD: "ninja", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "nissan": { + GTLD: "nissan", + DelegationDate: "2015-03-04", + RemovalDate: "", + }, + "nissay": { + GTLD: "nissay", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "nl": { + GTLD: "nl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "no": { + GTLD: "no", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nokia": { + GTLD: "nokia", + DelegationDate: "2015-07-15", + RemovalDate: "", + }, + "northwesternmutual": { + GTLD: "northwesternmutual", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "norton": { + GTLD: "norton", + DelegationDate: "2015-12-03", + RemovalDate: "", + }, + "now": { + GTLD: "now", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "nowruz": { + GTLD: "nowruz", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "nowtv": { + GTLD: "nowtv", + DelegationDate: "2016-05-11", + RemovalDate: "", + }, + "np": { + GTLD: "np", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nr": { + GTLD: "nr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nra": { + GTLD: "nra", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "nrw": { + GTLD: "nrw", + DelegationDate: "2014-07-11", + RemovalDate: "", + }, + "ntt": { + GTLD: "ntt", + DelegationDate: "2015-02-03", + RemovalDate: "", + }, + "nu": { + GTLD: "nu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "nyc": { + GTLD: "nyc", + DelegationDate: "2014-03-20", + RemovalDate: "", + }, + "nz": { + GTLD: "nz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "obi": { + GTLD: "obi", + DelegationDate: "2015-09-23", + RemovalDate: "", + }, + "observer": { + GTLD: "observer", + DelegationDate: "2016-09-27", + RemovalDate: "", + }, + "off": { + GTLD: "off", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "office": { + GTLD: "office", + DelegationDate: "2015-06-23", + RemovalDate: "", + }, + "okinawa": { + GTLD: "okinawa", + DelegationDate: "2014-03-02", + RemovalDate: "", + }, + "olayan": { + GTLD: "olayan", + DelegationDate: "2016-05-03", + RemovalDate: "", + }, + "olayangroup": { + GTLD: "olayangroup", + DelegationDate: "2016-05-06", + RemovalDate: "", + }, + "oldnavy": { + GTLD: "oldnavy", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "ollo": { + GTLD: "ollo", + DelegationDate: "2016-05-27", + RemovalDate: "", + }, + "om": { + GTLD: "om", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "omega": { + GTLD: "omega", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "one": { + GTLD: "one", + DelegationDate: "2015-01-22", + RemovalDate: "", + }, + "ong": { + GTLD: "ong", + DelegationDate: "2014-07-27", + RemovalDate: "", + }, + "onl": { + GTLD: "onl", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "online": { + GTLD: "online", + DelegationDate: "2015-03-16", + RemovalDate: "", + }, + "onyourside": { + GTLD: "onyourside", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "ooo": { + GTLD: "ooo", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "open": { + GTLD: "open", + DelegationDate: "2016-08-08", + RemovalDate: "", + }, + "oracle": { + GTLD: "oracle", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "orange": { + GTLD: "orange", + DelegationDate: "2015-07-09", + RemovalDate: "", + }, + "org": { + GTLD: "org", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "organic": { + GTLD: "organic", + DelegationDate: "2014-06-13", + RemovalDate: "", + }, + "orientexpress": { + GTLD: "orientexpress", + DelegationDate: "2016-06-22", + RemovalDate: "2017-04-14", + }, + "origins": { + GTLD: "origins", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "osaka": { + GTLD: "osaka", + DelegationDate: "2014-12-13", + RemovalDate: "", + }, + "otsuka": { + GTLD: "otsuka", + DelegationDate: "2014-08-27", + RemovalDate: "", + }, + "ott": { + GTLD: "ott", + DelegationDate: "2016-05-27", + RemovalDate: "", + }, + "ovh": { + GTLD: "ovh", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "pa": { + GTLD: "pa", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "page": { + GTLD: "page", + DelegationDate: "2015-03-16", + RemovalDate: "", + }, + "pamperedchef": { + GTLD: "pamperedchef", + DelegationDate: "2016-01-21", + RemovalDate: "2017-09-20", + }, + "panasonic": { + GTLD: "panasonic", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "panerai": { + GTLD: "panerai", + DelegationDate: "2015-03-25", + RemovalDate: "2018-09-18", + }, + "paris": { + GTLD: "paris", + DelegationDate: "2014-04-19", + RemovalDate: "", + }, + "pars": { + GTLD: "pars", + DelegationDate: "2015-12-07", + RemovalDate: "", + }, + "partners": { + GTLD: "partners", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "parts": { + GTLD: "parts", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "party": { + GTLD: "party", + DelegationDate: "2014-11-17", + RemovalDate: "", + }, + "passagens": { + GTLD: "passagens", + DelegationDate: "2016-03-02", + RemovalDate: "", + }, + "pay": { + GTLD: "pay", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "pccw": { + GTLD: "pccw", + DelegationDate: "2016-05-11", + RemovalDate: "", + }, + "pe": { + GTLD: "pe", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pet": { + GTLD: "pet", + DelegationDate: "2015-07-26", + RemovalDate: "", + }, + "pf": { + GTLD: "pf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pfizer": { + GTLD: "pfizer", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "pg": { + GTLD: "pg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ph": { + GTLD: "ph", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pharmacy": { + GTLD: "pharmacy", + DelegationDate: "2014-09-05", + RemovalDate: "", + }, + "phd": { + GTLD: "phd", + DelegationDate: "2017-06-29", + RemovalDate: "", + }, + "philips": { + GTLD: "philips", + DelegationDate: "2015-05-09", + RemovalDate: "", + }, + "phone": { + GTLD: "phone", + DelegationDate: "2016-12-20", + RemovalDate: "", + }, + "photo": { + GTLD: "photo", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "photography": { + GTLD: "photography", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "photos": { + GTLD: "photos", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "physio": { + GTLD: "physio", + DelegationDate: "2014-06-19", + RemovalDate: "", + }, + "piaget": { + GTLD: "piaget", + DelegationDate: "2015-03-16", + RemovalDate: "2019-11-14", + }, + "pics": { + GTLD: "pics", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "pictet": { + GTLD: "pictet", + DelegationDate: "2015-03-07", + RemovalDate: "", + }, + "pictures": { + GTLD: "pictures", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "pid": { + GTLD: "pid", + DelegationDate: "2015-12-22", + RemovalDate: "", + }, + "pin": { + GTLD: "pin", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "ping": { + GTLD: "ping", + DelegationDate: "2015-10-29", + RemovalDate: "", + }, + "pink": { + GTLD: "pink", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "pioneer": { + GTLD: "pioneer", + DelegationDate: "2016-06-02", + RemovalDate: "", + }, + "pizza": { + GTLD: "pizza", + DelegationDate: "2014-08-27", + RemovalDate: "", + }, + "pk": { + GTLD: "pk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pl": { + GTLD: "pl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "place": { + GTLD: "place", + DelegationDate: "2014-07-02", + RemovalDate: "", + }, + "play": { + GTLD: "play", + DelegationDate: "2015-06-20", + RemovalDate: "", + }, + "playstation": { + GTLD: "playstation", + DelegationDate: "2015-11-07", + RemovalDate: "", + }, + "plumbing": { + GTLD: "plumbing", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "plus": { + GTLD: "plus", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "pm": { + GTLD: "pm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pn": { + GTLD: "pn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pnc": { + GTLD: "pnc", + DelegationDate: "2016-07-01", + RemovalDate: "", + }, + "pohl": { + GTLD: "pohl", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "poker": { + GTLD: "poker", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "politie": { + GTLD: "politie", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "porn": { + GTLD: "porn", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "post": { + GTLD: "post", + DelegationDate: "2012-08-07", + RemovalDate: "", + }, + "pr": { + GTLD: "pr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pramerica": { + GTLD: "pramerica", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "praxi": { + GTLD: "praxi", + DelegationDate: "2014-07-22", + RemovalDate: "", + }, + "press": { + GTLD: "press", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "prime": { + GTLD: "prime", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "pro": { + GTLD: "pro", + DelegationDate: "2004-05-27", + RemovalDate: "", + }, + "prod": { + GTLD: "prod", + DelegationDate: "2014-08-29", + RemovalDate: "", + }, + "productions": { + GTLD: "productions", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "prof": { + GTLD: "prof", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "progressive": { + GTLD: "progressive", + DelegationDate: "2016-04-20", + RemovalDate: "", + }, + "promo": { + GTLD: "promo", + DelegationDate: "2015-12-31", + RemovalDate: "", + }, + "properties": { + GTLD: "properties", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "property": { + GTLD: "property", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "protection": { + GTLD: "protection", + DelegationDate: "2015-09-13", + RemovalDate: "", + }, + "pru": { + GTLD: "pru", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "prudential": { + GTLD: "prudential", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "ps": { + GTLD: "ps", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pt": { + GTLD: "pt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pub": { + GTLD: "pub", + DelegationDate: "2014-02-26", + RemovalDate: "", + }, + "pw": { + GTLD: "pw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "pwc": { + GTLD: "pwc", + DelegationDate: "2016-02-11", + RemovalDate: "", + }, + "py": { + GTLD: "py", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "qa": { + GTLD: "qa", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "qpon": { + GTLD: "qpon", + DelegationDate: "2014-02-12", + RemovalDate: "", + }, + "quebec": { + GTLD: "quebec", + DelegationDate: "2014-04-16", + RemovalDate: "", + }, + "quest": { + GTLD: "quest", + DelegationDate: "2016-02-06", + RemovalDate: "", + }, + "qvc": { + GTLD: "qvc", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "racing": { + GTLD: "racing", + DelegationDate: "2015-04-03", + RemovalDate: "", + }, + "radio": { + GTLD: "radio", + DelegationDate: "2016-10-12", + RemovalDate: "", + }, + "raid": { + GTLD: "raid", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "re": { + GTLD: "re", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "read": { + GTLD: "read", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "realestate": { + GTLD: "realestate", + DelegationDate: "2016-05-23", + RemovalDate: "", + }, + "realtor": { + GTLD: "realtor", + DelegationDate: "2014-07-30", + RemovalDate: "", + }, + "realty": { + GTLD: "realty", + DelegationDate: "2015-07-01", + RemovalDate: "", + }, + "recipes": { + GTLD: "recipes", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "red": { + GTLD: "red", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "redstone": { + GTLD: "redstone", + DelegationDate: "2015-03-28", + RemovalDate: "", + }, + "redumbrella": { + GTLD: "redumbrella", + DelegationDate: "2015-12-11", + RemovalDate: "", + }, + "rehab": { + GTLD: "rehab", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "reise": { + GTLD: "reise", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "reisen": { + GTLD: "reisen", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "reit": { + GTLD: "reit", + DelegationDate: "2014-11-12", + RemovalDate: "", + }, + "reliance": { + GTLD: "reliance", + DelegationDate: "2016-11-15", + RemovalDate: "", + }, + "ren": { + GTLD: "ren", + DelegationDate: "2014-03-27", + RemovalDate: "", + }, + "rent": { + GTLD: "rent", + DelegationDate: "2015-04-30", + RemovalDate: "", + }, + "rentals": { + GTLD: "rentals", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "repair": { + GTLD: "repair", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "report": { + GTLD: "report", + DelegationDate: "2014-02-04", + RemovalDate: "", + }, + "republican": { + GTLD: "republican", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "rest": { + GTLD: "rest", + DelegationDate: "2014-04-02", + RemovalDate: "", + }, + "restaurant": { + GTLD: "restaurant", + DelegationDate: "2014-08-08", + RemovalDate: "", + }, + "review": { + GTLD: "review", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "reviews": { + GTLD: "reviews", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "rexroth": { + GTLD: "rexroth", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "rich": { + GTLD: "rich", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "richardli": { + GTLD: "richardli", + DelegationDate: "2016-05-11", + RemovalDate: "", + }, + "ricoh": { + GTLD: "ricoh", + DelegationDate: "2015-06-22", + RemovalDate: "", + }, + "rightathome": { + GTLD: "rightathome", + DelegationDate: "2016-07-21", + RemovalDate: "2020-07-28", + }, + "ril": { + GTLD: "ril", + DelegationDate: "2016-11-15", + RemovalDate: "", + }, + "rio": { + GTLD: "rio", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "rip": { + GTLD: "rip", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "rmit": { + GTLD: "rmit", + DelegationDate: "2016-11-24", + RemovalDate: "", + }, + "ro": { + GTLD: "ro", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "rocher": { + GTLD: "rocher", + DelegationDate: "2015-11-07", + RemovalDate: "", + }, + "rocks": { + GTLD: "rocks", + DelegationDate: "2014-04-10", + RemovalDate: "", + }, + "rodeo": { + GTLD: "rodeo", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "rogers": { + GTLD: "rogers", + DelegationDate: "2016-09-20", + RemovalDate: "", + }, + "room": { + GTLD: "room", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "rs": { + GTLD: "rs", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "rsvp": { + GTLD: "rsvp", + DelegationDate: "2014-08-30", + RemovalDate: "", + }, + "ru": { + GTLD: "ru", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "rugby": { + GTLD: "rugby", + DelegationDate: "2017-04-07", + RemovalDate: "", + }, + "ruhr": { + GTLD: "ruhr", + DelegationDate: "2013-12-10", + RemovalDate: "", + }, + "run": { + GTLD: "run", + DelegationDate: "2015-05-07", + RemovalDate: "", + }, + "rw": { + GTLD: "rw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "rwe": { + GTLD: "rwe", + DelegationDate: "2015-10-27", + RemovalDate: "", + }, + "ryukyu": { + GTLD: "ryukyu", + DelegationDate: "2014-04-03", + RemovalDate: "", + }, + "sa": { + GTLD: "sa", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "saarland": { + GTLD: "saarland", + DelegationDate: "2014-04-02", + RemovalDate: "", + }, + "safe": { + GTLD: "safe", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "safety": { + GTLD: "safety", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "sakura": { + GTLD: "sakura", + DelegationDate: "2015-07-02", + RemovalDate: "", + }, + "sale": { + GTLD: "sale", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "salon": { + GTLD: "salon", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "samsclub": { + GTLD: "samsclub", + DelegationDate: "2016-08-18", + RemovalDate: "", + }, + "samsung": { + GTLD: "samsung", + DelegationDate: "2014-12-10", + RemovalDate: "", + }, + "sandvik": { + GTLD: "sandvik", + DelegationDate: "2015-05-27", + RemovalDate: "", + }, + "sandvikcoromant": { + GTLD: "sandvikcoromant", + DelegationDate: "2015-05-27", + RemovalDate: "", + }, + "sanofi": { + GTLD: "sanofi", + DelegationDate: "2015-07-24", + RemovalDate: "", + }, + "sap": { + GTLD: "sap", + DelegationDate: "2015-03-26", + RemovalDate: "", + }, + "sapo": { + GTLD: "sapo", + DelegationDate: "2015-10-29", + RemovalDate: "2018-05-26", + }, + "sarl": { + GTLD: "sarl", + DelegationDate: "2014-08-08", + RemovalDate: "", + }, + "sas": { + GTLD: "sas", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "save": { + GTLD: "save", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "saxo": { + GTLD: "saxo", + DelegationDate: "2015-02-10", + RemovalDate: "", + }, + "sb": { + GTLD: "sb", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sbi": { + GTLD: "sbi", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "sbs": { + GTLD: "sbs", + DelegationDate: "2015-10-29", + RemovalDate: "", + }, + "sc": { + GTLD: "sc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sca": { + GTLD: "sca", + DelegationDate: "2014-08-14", + RemovalDate: "", + }, + "scb": { + GTLD: "scb", + DelegationDate: "2014-07-11", + RemovalDate: "", + }, + "schaeffler": { + GTLD: "schaeffler", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "schmidt": { + GTLD: "schmidt", + DelegationDate: "2014-07-03", + RemovalDate: "", + }, + "scholarships": { + GTLD: "scholarships", + DelegationDate: "2015-04-02", + RemovalDate: "", + }, + "school": { + GTLD: "school", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "schule": { + GTLD: "schule", + DelegationDate: "2014-04-22", + RemovalDate: "", + }, + "schwarz": { + GTLD: "schwarz", + DelegationDate: "2014-12-13", + RemovalDate: "", + }, + "science": { + GTLD: "science", + DelegationDate: "2014-11-15", + RemovalDate: "", + }, + "scjohnson": { + GTLD: "scjohnson", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "scor": { + GTLD: "scor", + DelegationDate: "2015-06-23", + RemovalDate: "2020-05-27", + }, + "scot": { + GTLD: "scot", + DelegationDate: "2014-06-13", + RemovalDate: "", + }, + "sd": { + GTLD: "sd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "se": { + GTLD: "se", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "search": { + GTLD: "search", + DelegationDate: "2017-06-29", + RemovalDate: "", + }, + "seat": { + GTLD: "seat", + DelegationDate: "2015-04-18", + RemovalDate: "", + }, + "secure": { + GTLD: "secure", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "security": { + GTLD: "security", + DelegationDate: "2015-09-17", + RemovalDate: "", + }, + "seek": { + GTLD: "seek", + DelegationDate: "2015-08-11", + RemovalDate: "", + }, + "select": { + GTLD: "select", + DelegationDate: "2016-01-15", + RemovalDate: "", + }, + "sener": { + GTLD: "sener", + DelegationDate: "2015-05-01", + RemovalDate: "", + }, + "services": { + GTLD: "services", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "ses": { + GTLD: "ses", + DelegationDate: "2016-07-09", + RemovalDate: "", + }, + "seven": { + GTLD: "seven", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "sew": { + GTLD: "sew", + DelegationDate: "2014-12-13", + RemovalDate: "", + }, + "sex": { + GTLD: "sex", + DelegationDate: "2015-04-18", + RemovalDate: "", + }, + "sexy": { + GTLD: "sexy", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "sfr": { + GTLD: "sfr", + DelegationDate: "2015-12-01", + RemovalDate: "", + }, + "sg": { + GTLD: "sg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sh": { + GTLD: "sh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "shangrila": { + GTLD: "shangrila", + DelegationDate: "2016-07-02", + RemovalDate: "", + }, + "sharp": { + GTLD: "sharp", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "shaw": { + GTLD: "shaw", + DelegationDate: "2016-03-22", + RemovalDate: "", + }, + "shell": { + GTLD: "shell", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "shia": { + GTLD: "shia", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "shiksha": { + GTLD: "shiksha", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "shoes": { + GTLD: "shoes", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "shop": { + GTLD: "shop", + DelegationDate: "2016-05-23", + RemovalDate: "", + }, + "shopping": { + GTLD: "shopping", + DelegationDate: "2016-06-21", + RemovalDate: "", + }, + "shouji": { + GTLD: "shouji", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "show": { + GTLD: "show", + DelegationDate: "2015-04-16", + RemovalDate: "", + }, + "showtime": { + GTLD: "showtime", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "shriram": { + GTLD: "shriram", + DelegationDate: "2014-12-30", + RemovalDate: "", + }, + "si": { + GTLD: "si", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "silk": { + GTLD: "silk", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "sina": { + GTLD: "sina", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "singles": { + GTLD: "singles", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "site": { + GTLD: "site", + DelegationDate: "2015-03-16", + RemovalDate: "", + }, + "sj": { + GTLD: "sj", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sk": { + GTLD: "sk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ski": { + GTLD: "ski", + DelegationDate: "2015-05-30", + RemovalDate: "", + }, + "skin": { + GTLD: "skin", + DelegationDate: "2016-01-15", + RemovalDate: "", + }, + "sky": { + GTLD: "sky", + DelegationDate: "2014-12-12", + RemovalDate: "", + }, + "skype": { + GTLD: "skype", + DelegationDate: "2015-06-23", + RemovalDate: "", + }, + "sl": { + GTLD: "sl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sling": { + GTLD: "sling", + DelegationDate: "2016-08-10", + RemovalDate: "", + }, + "sm": { + GTLD: "sm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "smart": { + GTLD: "smart", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "smile": { + GTLD: "smile", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "sn": { + GTLD: "sn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sncf": { + GTLD: "sncf", + DelegationDate: "2015-06-03", + RemovalDate: "", + }, + "so": { + GTLD: "so", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "soccer": { + GTLD: "soccer", + DelegationDate: "2015-05-13", + RemovalDate: "", + }, + "social": { + GTLD: "social", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "softbank": { + GTLD: "softbank", + DelegationDate: "2016-01-16", + RemovalDate: "", + }, + "software": { + GTLD: "software", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "sohu": { + GTLD: "sohu", + DelegationDate: "2014-03-25", + RemovalDate: "", + }, + "solar": { + GTLD: "solar", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "solutions": { + GTLD: "solutions", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "song": { + GTLD: "song", + DelegationDate: "2016-02-24", + RemovalDate: "", + }, + "sony": { + GTLD: "sony", + DelegationDate: "2015-04-16", + RemovalDate: "", + }, + "soy": { + GTLD: "soy", + DelegationDate: "2014-04-19", + RemovalDate: "", + }, + "space": { + GTLD: "space", + DelegationDate: "2014-05-30", + RemovalDate: "", + }, + "spiegel": { + GTLD: "spiegel", + DelegationDate: "2014-07-18", + RemovalDate: "2018-12-15", + }, + "sport": { + GTLD: "sport", + DelegationDate: "2018-01-10", + RemovalDate: "", + }, + "spot": { + GTLD: "spot", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "spreadbetting": { + GTLD: "spreadbetting", + DelegationDate: "2015-03-13", + RemovalDate: "", + }, + "sr": { + GTLD: "sr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "srl": { + GTLD: "srl", + DelegationDate: "2015-07-24", + RemovalDate: "", + }, + "srt": { + GTLD: "srt", + DelegationDate: "2016-07-28", + RemovalDate: "2019-11-19", + }, + "ss": { + GTLD: "ss", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "st": { + GTLD: "st", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "stada": { + GTLD: "stada", + DelegationDate: "2015-09-13", + RemovalDate: "", + }, + "staples": { + GTLD: "staples", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "star": { + GTLD: "star", + DelegationDate: "2015-12-22", + RemovalDate: "", + }, + "starhub": { + GTLD: "starhub", + DelegationDate: "2015-06-22", + RemovalDate: "2019-08-02", + }, + "statebank": { + GTLD: "statebank", + DelegationDate: "2016-04-16", + RemovalDate: "", + }, + "statefarm": { + GTLD: "statefarm", + DelegationDate: "2015-12-24", + RemovalDate: "", + }, + "statoil": { + GTLD: "statoil", + DelegationDate: "2015-06-19", + RemovalDate: "2018-10-03", + }, + "stc": { + GTLD: "stc", + DelegationDate: "2015-08-29", + RemovalDate: "", + }, + "stcgroup": { + GTLD: "stcgroup", + DelegationDate: "2015-08-28", + RemovalDate: "", + }, + "stockholm": { + GTLD: "stockholm", + DelegationDate: "2015-09-26", + RemovalDate: "", + }, + "storage": { + GTLD: "storage", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "store": { + GTLD: "store", + DelegationDate: "2016-02-22", + RemovalDate: "", + }, + "stream": { + GTLD: "stream", + DelegationDate: "2016-03-18", + RemovalDate: "", + }, + "studio": { + GTLD: "studio", + DelegationDate: "2015-07-08", + RemovalDate: "", + }, + "study": { + GTLD: "study", + DelegationDate: "2015-02-25", + RemovalDate: "", + }, + "style": { + GTLD: "style", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "su": { + GTLD: "su", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sucks": { + GTLD: "sucks", + DelegationDate: "2015-02-25", + RemovalDate: "", + }, + "supplies": { + GTLD: "supplies", + DelegationDate: "2014-02-25", + RemovalDate: "", + }, + "supply": { + GTLD: "supply", + DelegationDate: "2014-02-21", + RemovalDate: "", + }, + "support": { + GTLD: "support", + DelegationDate: "2013-12-18", + RemovalDate: "", + }, + "surf": { + GTLD: "surf", + DelegationDate: "2014-06-18", + RemovalDate: "", + }, + "surgery": { + GTLD: "surgery", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "suzuki": { + GTLD: "suzuki", + DelegationDate: "2014-07-02", + RemovalDate: "", + }, + "sv": { + GTLD: "sv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "swatch": { + GTLD: "swatch", + DelegationDate: "2015-06-26", + RemovalDate: "", + }, + "swiftcover": { + GTLD: "swiftcover", + DelegationDate: "2016-07-21", + RemovalDate: "", + }, + "swiss": { + GTLD: "swiss", + DelegationDate: "2015-04-29", + RemovalDate: "", + }, + "sx": { + GTLD: "sx", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sy": { + GTLD: "sy", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "sydney": { + GTLD: "sydney", + DelegationDate: "2014-11-05", + RemovalDate: "", + }, + "symantec": { + GTLD: "symantec", + DelegationDate: "2015-12-03", + RemovalDate: "2020-07-17", + }, + "systems": { + GTLD: "systems", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "sz": { + GTLD: "sz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tab": { + GTLD: "tab", + DelegationDate: "2015-11-13", + RemovalDate: "", + }, + "taipei": { + GTLD: "taipei", + DelegationDate: "2014-10-23", + RemovalDate: "", + }, + "talk": { + GTLD: "talk", + DelegationDate: "2016-03-25", + RemovalDate: "", + }, + "taobao": { + GTLD: "taobao", + DelegationDate: "2016-01-21", + RemovalDate: "", + }, + "target": { + GTLD: "target", + DelegationDate: "2016-08-04", + RemovalDate: "", + }, + "tatamotors": { + GTLD: "tatamotors", + DelegationDate: "2015-07-24", + RemovalDate: "", + }, + "tatar": { + GTLD: "tatar", + DelegationDate: "2014-08-07", + RemovalDate: "", + }, + "tattoo": { + GTLD: "tattoo", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "tax": { + GTLD: "tax", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "taxi": { + GTLD: "taxi", + DelegationDate: "2015-05-07", + RemovalDate: "", + }, + "tc": { + GTLD: "tc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tci": { + GTLD: "tci", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "td": { + GTLD: "td", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tdk": { + GTLD: "tdk", + DelegationDate: "2016-06-07", + RemovalDate: "", + }, + "team": { + GTLD: "team", + DelegationDate: "2015-04-16", + RemovalDate: "", + }, + "tech": { + GTLD: "tech", + DelegationDate: "2015-03-21", + RemovalDate: "", + }, + "technology": { + GTLD: "technology", + DelegationDate: "2013-11-14", + RemovalDate: "", + }, + "tel": { + GTLD: "tel", + DelegationDate: "2007-03-02", + RemovalDate: "", + }, + "telecity": { + GTLD: "telecity", + DelegationDate: "2016-02-25", + RemovalDate: "2018-08-19", + }, + "telefonica": { + GTLD: "telefonica", + DelegationDate: "2015-06-26", + RemovalDate: "2019-12-23", + }, + "temasek": { + GTLD: "temasek", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "tennis": { + GTLD: "tennis", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "teva": { + GTLD: "teva", + DelegationDate: "2016-04-13", + RemovalDate: "", + }, + "tf": { + GTLD: "tf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tg": { + GTLD: "tg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "th": { + GTLD: "th", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "thd": { + GTLD: "thd", + DelegationDate: "2015-05-22", + RemovalDate: "", + }, + "theater": { + GTLD: "theater", + DelegationDate: "2015-05-06", + RemovalDate: "", + }, + "theatre": { + GTLD: "theatre", + DelegationDate: "2015-09-13", + RemovalDate: "", + }, + "tiaa": { + GTLD: "tiaa", + DelegationDate: "2016-07-20", + RemovalDate: "", + }, + "tickets": { + GTLD: "tickets", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "tienda": { + GTLD: "tienda", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "tiffany": { + GTLD: "tiffany", + DelegationDate: "2016-01-21", + RemovalDate: "", + }, + "tips": { + GTLD: "tips", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "tires": { + GTLD: "tires", + DelegationDate: "2014-12-18", + RemovalDate: "", + }, + "tirol": { + GTLD: "tirol", + DelegationDate: "2014-06-04", + RemovalDate: "", + }, + "tj": { + GTLD: "tj", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tjmaxx": { + GTLD: "tjmaxx", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "tjx": { + GTLD: "tjx", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "tk": { + GTLD: "tk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tkmaxx": { + GTLD: "tkmaxx", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "tl": { + GTLD: "tl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tm": { + GTLD: "tm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tmall": { + GTLD: "tmall", + DelegationDate: "2016-01-21", + RemovalDate: "", + }, + "tn": { + GTLD: "tn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "to": { + GTLD: "to", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "today": { + GTLD: "today", + DelegationDate: "2013-11-19", + RemovalDate: "", + }, + "tokyo": { + GTLD: "tokyo", + DelegationDate: "2014-01-29", + RemovalDate: "", + }, + "tools": { + GTLD: "tools", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "top": { + GTLD: "top", + DelegationDate: "2014-08-03", + RemovalDate: "", + }, + "toray": { + GTLD: "toray", + DelegationDate: "2015-05-01", + RemovalDate: "", + }, + "toshiba": { + GTLD: "toshiba", + DelegationDate: "2015-02-04", + RemovalDate: "", + }, + "total": { + GTLD: "total", + DelegationDate: "2016-03-09", + RemovalDate: "", + }, + "tours": { + GTLD: "tours", + DelegationDate: "2015-03-24", + RemovalDate: "", + }, + "town": { + GTLD: "town", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "toyota": { + GTLD: "toyota", + DelegationDate: "2015-07-26", + RemovalDate: "", + }, + "toys": { + GTLD: "toys", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "tr": { + GTLD: "tr", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "trade": { + GTLD: "trade", + DelegationDate: "2014-03-19", + RemovalDate: "", + }, + "trading": { + GTLD: "trading", + DelegationDate: "2015-03-13", + RemovalDate: "", + }, + "training": { + GTLD: "training", + DelegationDate: "2013-12-28", + RemovalDate: "", + }, + "travel": { + GTLD: "travel", + DelegationDate: "2005-07-21", + RemovalDate: "", + }, + "travelchannel": { + GTLD: "travelchannel", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "travelers": { + GTLD: "travelers", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "travelersinsurance": { + GTLD: "travelersinsurance", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "trust": { + GTLD: "trust", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "trv": { + GTLD: "trv", + DelegationDate: "2015-12-11", + RemovalDate: "", + }, + "tt": { + GTLD: "tt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tube": { + GTLD: "tube", + DelegationDate: "2016-01-11", + RemovalDate: "", + }, + "tui": { + GTLD: "tui", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "tunes": { + GTLD: "tunes", + DelegationDate: "2016-02-25", + RemovalDate: "", + }, + "tushu": { + GTLD: "tushu", + DelegationDate: "2015-12-14", + RemovalDate: "", + }, + "tv": { + GTLD: "tv", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tvs": { + GTLD: "tvs", + DelegationDate: "2016-02-13", + RemovalDate: "", + }, + "tw": { + GTLD: "tw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "tz": { + GTLD: "tz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ua": { + GTLD: "ua", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ubank": { + GTLD: "ubank", + DelegationDate: "2016-08-18", + RemovalDate: "", + }, + "ubs": { + GTLD: "ubs", + DelegationDate: "2015-07-11", + RemovalDate: "", + }, + "uconnect": { + GTLD: "uconnect", + DelegationDate: "2016-07-28", + RemovalDate: "2019-11-19", + }, + "ug": { + GTLD: "ug", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "uk": { + GTLD: "uk", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "unicom": { + GTLD: "unicom", + DelegationDate: "2016-02-04", + RemovalDate: "", + }, + "university": { + GTLD: "university", + DelegationDate: "2014-04-11", + RemovalDate: "", + }, + "uno": { + GTLD: "uno", + DelegationDate: "2013-11-30", + RemovalDate: "", + }, + "uol": { + GTLD: "uol", + DelegationDate: "2014-08-16", + RemovalDate: "", + }, + "ups": { + GTLD: "ups", + DelegationDate: "2016-05-31", + RemovalDate: "", + }, + "us": { + GTLD: "us", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "uy": { + GTLD: "uy", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "uz": { + GTLD: "uz", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "va": { + GTLD: "va", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "vacations": { + GTLD: "vacations", + DelegationDate: "2014-02-21", + RemovalDate: "", + }, + "vana": { + GTLD: "vana", + DelegationDate: "2015-11-10", + RemovalDate: "", + }, + "vanguard": { + GTLD: "vanguard", + DelegationDate: "2016-08-28", + RemovalDate: "", + }, + "vc": { + GTLD: "vc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "ve": { + GTLD: "ve", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "vegas": { + GTLD: "vegas", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "ventures": { + GTLD: "ventures", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "verisign": { + GTLD: "verisign", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "versicherung": { + GTLD: "versicherung", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "vet": { + GTLD: "vet", + DelegationDate: "2014-05-31", + RemovalDate: "", + }, + "vg": { + GTLD: "vg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "vi": { + GTLD: "vi", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "viajes": { + GTLD: "viajes", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "video": { + GTLD: "video", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "vig": { + GTLD: "vig", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "viking": { + GTLD: "viking", + DelegationDate: "2016-02-22", + RemovalDate: "", + }, + "villas": { + GTLD: "villas", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "vin": { + GTLD: "vin", + DelegationDate: "2015-08-05", + RemovalDate: "", + }, + "vip": { + GTLD: "vip", + DelegationDate: "2015-11-25", + RemovalDate: "", + }, + "virgin": { + GTLD: "virgin", + DelegationDate: "2015-10-07", + RemovalDate: "", + }, + "visa": { + GTLD: "visa", + DelegationDate: "2016-07-28", + RemovalDate: "", + }, + "vision": { + GTLD: "vision", + DelegationDate: "2014-02-11", + RemovalDate: "", + }, + "vista": { + GTLD: "vista", + DelegationDate: "2015-06-22", + RemovalDate: "2018-09-13", + }, + "vistaprint": { + GTLD: "vistaprint", + DelegationDate: "2015-06-22", + RemovalDate: "2020-03-13", + }, + "viva": { + GTLD: "viva", + DelegationDate: "2015-08-28", + RemovalDate: "", + }, + "vivo": { + GTLD: "vivo", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "vlaanderen": { + GTLD: "vlaanderen", + DelegationDate: "2014-06-18", + RemovalDate: "", + }, + "vn": { + GTLD: "vn", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "vodka": { + GTLD: "vodka", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "volkswagen": { + GTLD: "volkswagen", + DelegationDate: "2016-01-09", + RemovalDate: "", + }, + "volvo": { + GTLD: "volvo", + DelegationDate: "2016-10-24", + RemovalDate: "", + }, + "vote": { + GTLD: "vote", + DelegationDate: "2014-03-02", + RemovalDate: "", + }, + "voting": { + GTLD: "voting", + DelegationDate: "2014-01-29", + RemovalDate: "", + }, + "voto": { + GTLD: "voto", + DelegationDate: "2014-03-02", + RemovalDate: "", + }, + "voyage": { + GTLD: "voyage", + DelegationDate: "2013-11-06", + RemovalDate: "", + }, + "vu": { + GTLD: "vu", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "vuelos": { + GTLD: "vuelos", + DelegationDate: "2016-03-02", + RemovalDate: "", + }, + "wales": { + GTLD: "wales", + DelegationDate: "2014-08-07", + RemovalDate: "", + }, + "walmart": { + GTLD: "walmart", + DelegationDate: "2016-08-18", + RemovalDate: "", + }, + "walter": { + GTLD: "walter", + DelegationDate: "2015-05-27", + RemovalDate: "", + }, + "wang": { + GTLD: "wang", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "wanggou": { + GTLD: "wanggou", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "warman": { + GTLD: "warman", + DelegationDate: "2016-05-03", + RemovalDate: "2019-11-19", + }, + "watch": { + GTLD: "watch", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "watches": { + GTLD: "watches", + DelegationDate: "2015-12-14", + RemovalDate: "", + }, + "weather": { + GTLD: "weather", + DelegationDate: "2016-01-12", + RemovalDate: "", + }, + "weatherchannel": { + GTLD: "weatherchannel", + DelegationDate: "2016-01-28", + RemovalDate: "", + }, + "webcam": { + GTLD: "webcam", + DelegationDate: "2014-03-19", + RemovalDate: "", + }, + "weber": { + GTLD: "weber", + DelegationDate: "2015-12-22", + RemovalDate: "", + }, + "website": { + GTLD: "website", + DelegationDate: "2014-05-30", + RemovalDate: "", + }, + "wed": { + GTLD: "wed", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "wedding": { + GTLD: "wedding", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "weibo": { + GTLD: "weibo", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "weir": { + GTLD: "weir", + DelegationDate: "2015-04-17", + RemovalDate: "", + }, + "wf": { + GTLD: "wf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "whoswho": { + GTLD: "whoswho", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "wien": { + GTLD: "wien", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "wiki": { + GTLD: "wiki", + DelegationDate: "2014-02-19", + RemovalDate: "", + }, + "williamhill": { + GTLD: "williamhill", + DelegationDate: "2014-07-27", + RemovalDate: "", + }, + "win": { + GTLD: "win", + DelegationDate: "2015-03-25", + RemovalDate: "", + }, + "windows": { + GTLD: "windows", + DelegationDate: "2015-06-10", + RemovalDate: "", + }, + "wine": { + GTLD: "wine", + DelegationDate: "2015-08-05", + RemovalDate: "", + }, + "winners": { + GTLD: "winners", + DelegationDate: "2016-07-15", + RemovalDate: "", + }, + "wme": { + GTLD: "wme", + DelegationDate: "2014-09-10", + RemovalDate: "", + }, + "wolterskluwer": { + GTLD: "wolterskluwer", + DelegationDate: "2016-02-11", + RemovalDate: "", + }, + "woodside": { + GTLD: "woodside", + DelegationDate: "2016-06-23", + RemovalDate: "", + }, + "work": { + GTLD: "work", + DelegationDate: "2014-09-23", + RemovalDate: "", + }, + "works": { + GTLD: "works", + DelegationDate: "2014-01-23", + RemovalDate: "", + }, + "world": { + GTLD: "world", + DelegationDate: "2014-09-19", + RemovalDate: "", + }, + "wow": { + GTLD: "wow", + DelegationDate: "2016-09-26", + RemovalDate: "", + }, + "ws": { + GTLD: "ws", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "wtc": { + GTLD: "wtc", + DelegationDate: "2014-04-29", + RemovalDate: "", + }, + "wtf": { + GTLD: "wtf", + DelegationDate: "2014-04-23", + RemovalDate: "", + }, + "xbox": { + GTLD: "xbox", + DelegationDate: "2015-06-04", + RemovalDate: "", + }, + "xerox": { + GTLD: "xerox", + DelegationDate: "2015-04-16", + RemovalDate: "", + }, + "xfinity": { + GTLD: "xfinity", + DelegationDate: "2016-07-07", + RemovalDate: "", + }, + "xihuan": { + GTLD: "xihuan", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "xin": { + GTLD: "xin", + DelegationDate: "2015-03-07", + RemovalDate: "", + }, + "xn--11b4c3d": { + GTLD: "xn--11b4c3d", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--1ck2e1b": { + GTLD: "xn--1ck2e1b", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "xn--1qqw23a": { + GTLD: "xn--1qqw23a", + DelegationDate: "2014-08-14", + RemovalDate: "", + }, + "xn--2scrj9c": { + GTLD: "xn--2scrj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--30rr7y": { + GTLD: "xn--30rr7y", + DelegationDate: "2015-03-31", + RemovalDate: "", + }, + "xn--3bst00m": { + GTLD: "xn--3bst00m", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "xn--3ds443g": { + GTLD: "xn--3ds443g", + DelegationDate: "2014-01-02", + RemovalDate: "", + }, + "xn--3e0b707e": { + GTLD: "xn--3e0b707e", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--3hcrj9c": { + GTLD: "xn--3hcrj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--3oq18vl8pn36a": { + GTLD: "xn--3oq18vl8pn36a", + DelegationDate: "2016-08-16", + RemovalDate: "", + }, + "xn--3pxu8k": { + GTLD: "xn--3pxu8k", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--42c2d9a": { + GTLD: "xn--42c2d9a", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--45br5cyl": { + GTLD: "xn--45br5cyl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--45brj9c": { + GTLD: "xn--45brj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--45q11c": { + GTLD: "xn--45q11c", + DelegationDate: "2014-11-17", + RemovalDate: "", + }, + "xn--4gbrim": { + GTLD: "xn--4gbrim", + DelegationDate: "2014-05-28", + RemovalDate: "", + }, + "xn--54b7fta0cc": { + GTLD: "xn--54b7fta0cc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--55qw42g": { + GTLD: "xn--55qw42g", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "xn--55qx5d": { + GTLD: "xn--55qx5d", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "xn--5su34j936bgsg": { + GTLD: "xn--5su34j936bgsg", + DelegationDate: "2016-07-02", + RemovalDate: "", + }, + "xn--5tzm5g": { + GTLD: "xn--5tzm5g", + DelegationDate: "2016-04-17", + RemovalDate: "", + }, + "xn--6frz82g": { + GTLD: "xn--6frz82g", + DelegationDate: "2014-02-05", + RemovalDate: "", + }, + "xn--6qq986b3xl": { + GTLD: "xn--6qq986b3xl", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "xn--80adxhks": { + GTLD: "xn--80adxhks", + DelegationDate: "2014-04-24", + RemovalDate: "", + }, + "xn--80ao21a": { + GTLD: "xn--80ao21a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--80aqecdr1a": { + GTLD: "xn--80aqecdr1a", + DelegationDate: "2016-12-01", + RemovalDate: "", + }, + "xn--80asehdb": { + GTLD: "xn--80asehdb", + DelegationDate: "2013-10-23", + RemovalDate: "", + }, + "xn--80aswg": { + GTLD: "xn--80aswg", + DelegationDate: "2013-10-23", + RemovalDate: "", + }, + "xn--8y0a063a": { + GTLD: "xn--8y0a063a", + DelegationDate: "2016-02-06", + RemovalDate: "", + }, + "xn--90a3ac": { + GTLD: "xn--90a3ac", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--90ae": { + GTLD: "xn--90ae", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--90ais": { + GTLD: "xn--90ais", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--9dbq2a": { + GTLD: "xn--9dbq2a", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--9et52u": { + GTLD: "xn--9et52u", + DelegationDate: "2015-03-27", + RemovalDate: "", + }, + "xn--9krt00a": { + GTLD: "xn--9krt00a", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "xn--b4w605ferd": { + GTLD: "xn--b4w605ferd", + DelegationDate: "2015-01-24", + RemovalDate: "", + }, + "xn--bck1b9a5dre4c": { + GTLD: "xn--bck1b9a5dre4c", + DelegationDate: "2016-02-21", + RemovalDate: "", + }, + "xn--c1avg": { + GTLD: "xn--c1avg", + DelegationDate: "2014-03-05", + RemovalDate: "", + }, + "xn--c2br7g": { + GTLD: "xn--c2br7g", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--cck2b3b": { + GTLD: "xn--cck2b3b", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "xn--cckwcxetd": { + GTLD: "xn--cckwcxetd", + DelegationDate: "2020-06-02", + RemovalDate: "", + }, + "xn--cg4bki": { + GTLD: "xn--cg4bki", + DelegationDate: "2014-02-21", + RemovalDate: "", + }, + "xn--clchc0ea0b2g2a9gcd": { + GTLD: "xn--clchc0ea0b2g2a9gcd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--czr694b": { + GTLD: "xn--czr694b", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "xn--czrs0t": { + GTLD: "xn--czrs0t", + DelegationDate: "2014-12-06", + RemovalDate: "", + }, + "xn--czru2d": { + GTLD: "xn--czru2d", + DelegationDate: "2014-03-31", + RemovalDate: "", + }, + "xn--d1acj3b": { + GTLD: "xn--d1acj3b", + DelegationDate: "2014-02-26", + RemovalDate: "", + }, + "xn--d1alf": { + GTLD: "xn--d1alf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--e1a4c": { + GTLD: "xn--e1a4c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--eckvdtc9d": { + GTLD: "xn--eckvdtc9d", + DelegationDate: "2015-12-14", + RemovalDate: "", + }, + "xn--efvy88h": { + GTLD: "xn--efvy88h", + DelegationDate: "2015-08-24", + RemovalDate: "", + }, + "xn--estv75g": { + GTLD: "xn--estv75g", + DelegationDate: "2015-05-07", + RemovalDate: "2020-04-01", + }, + "xn--fct429k": { + GTLD: "xn--fct429k", + DelegationDate: "2016-03-25", + RemovalDate: "", + }, + "xn--fhbei": { + GTLD: "xn--fhbei", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--fiq228c5hs": { + GTLD: "xn--fiq228c5hs", + DelegationDate: "2014-01-03", + RemovalDate: "", + }, + "xn--fiq64b": { + GTLD: "xn--fiq64b", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "xn--fiqs8s": { + GTLD: "xn--fiqs8s", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--fiqz9s": { + GTLD: "xn--fiqz9s", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--fjq720a": { + GTLD: "xn--fjq720a", + DelegationDate: "2015-05-09", + RemovalDate: "", + }, + "xn--flw351e": { + GTLD: "xn--flw351e", + DelegationDate: "2014-11-20", + RemovalDate: "", + }, + "xn--fpcrj9c3d": { + GTLD: "xn--fpcrj9c3d", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--fzc2c9e2c": { + GTLD: "xn--fzc2c9e2c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--fzys8d69uvgm": { + GTLD: "xn--fzys8d69uvgm", + DelegationDate: "2016-05-11", + RemovalDate: "", + }, + "xn--g2xx48c": { + GTLD: "xn--g2xx48c", + DelegationDate: "2016-01-16", + RemovalDate: "", + }, + "xn--gckr3f0f": { + GTLD: "xn--gckr3f0f", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "xn--gecrj9c": { + GTLD: "xn--gecrj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--gk3at1e": { + GTLD: "xn--gk3at1e", + DelegationDate: "2016-09-30", + RemovalDate: "", + }, + "xn--h2breg3eve": { + GTLD: "xn--h2breg3eve", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--h2brj9c": { + GTLD: "xn--h2brj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--h2brj9c8c": { + GTLD: "xn--h2brj9c8c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--hxt814e": { + GTLD: "xn--hxt814e", + DelegationDate: "2014-12-02", + RemovalDate: "", + }, + "xn--i1b6b1a6a2e": { + GTLD: "xn--i1b6b1a6a2e", + DelegationDate: "2014-03-09", + RemovalDate: "", + }, + "xn--imr513n": { + GTLD: "xn--imr513n", + DelegationDate: "2015-05-30", + RemovalDate: "", + }, + "xn--io0a7i": { + GTLD: "xn--io0a7i", + DelegationDate: "2014-01-18", + RemovalDate: "", + }, + "xn--j1aef": { + GTLD: "xn--j1aef", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--j1amh": { + GTLD: "xn--j1amh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--j6w193g": { + GTLD: "xn--j6w193g", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--jlq480n2rg": { + GTLD: "xn--jlq480n2rg", + DelegationDate: "2020-06-02", + RemovalDate: "", + }, + "xn--jlq61u9w7b": { + GTLD: "xn--jlq61u9w7b", + DelegationDate: "2015-12-18", + RemovalDate: "", + }, + "xn--jvr189m": { + GTLD: "xn--jvr189m", + DelegationDate: "2016-02-22", + RemovalDate: "", + }, + "xn--kcrx77d1x4a": { + GTLD: "xn--kcrx77d1x4a", + DelegationDate: "2015-04-07", + RemovalDate: "", + }, + "xn--kprw13d": { + GTLD: "xn--kprw13d", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--kpry57d": { + GTLD: "xn--kpry57d", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--kpu716f": { + GTLD: "xn--kpu716f", + DelegationDate: "2015-12-15", + RemovalDate: "2020-06-26", + }, + "xn--kput3i": { + GTLD: "xn--kput3i", + DelegationDate: "2014-06-17", + RemovalDate: "", + }, + "xn--l1acc": { + GTLD: "xn--l1acc", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--lgbbat1ad8j": { + GTLD: "xn--lgbbat1ad8j", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgb9awbf": { + GTLD: "xn--mgb9awbf", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgba3a3ejt": { + GTLD: "xn--mgba3a3ejt", + DelegationDate: "2015-10-15", + RemovalDate: "", + }, + "xn--mgba3a4f16a": { + GTLD: "xn--mgba3a4f16a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgba7c0bbn0a": { + GTLD: "xn--mgba7c0bbn0a", + DelegationDate: "2016-05-03", + RemovalDate: "", + }, + "xn--mgbaakc7dvf": { + GTLD: "xn--mgbaakc7dvf", + DelegationDate: "2017-06-10", + RemovalDate: "", + }, + "xn--mgbaam7a8h": { + GTLD: "xn--mgbaam7a8h", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbab2bd": { + GTLD: "xn--mgbab2bd", + DelegationDate: "2014-02-18", + RemovalDate: "", + }, + "xn--mgbah1a3hjkrd": { + GTLD: "xn--mgbah1a3hjkrd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbai9azgqp6j": { + GTLD: "xn--mgbai9azgqp6j", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbayh7gpa": { + GTLD: "xn--mgbayh7gpa", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbb9fbpob": { + GTLD: "xn--mgbb9fbpob", + DelegationDate: "2015-12-23", + RemovalDate: "2019-09-09", + }, + "xn--mgbbh1a": { + GTLD: "xn--mgbbh1a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbbh1a71e": { + GTLD: "xn--mgbbh1a71e", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbc0a9azcg": { + GTLD: "xn--mgbc0a9azcg", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbca7dzdo": { + GTLD: "xn--mgbca7dzdo", + DelegationDate: "2016-04-06", + RemovalDate: "", + }, + "xn--mgbcpq6gpa1a": { + GTLD: "xn--mgbcpq6gpa1a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgberp4a5d4ar": { + GTLD: "xn--mgberp4a5d4ar", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbgu82a": { + GTLD: "xn--mgbgu82a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbi4ecexp": { + GTLD: "xn--mgbi4ecexp", + DelegationDate: "2016-12-01", + RemovalDate: "", + }, + "xn--mgbpl2fh": { + GTLD: "xn--mgbpl2fh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbt3dhd": { + GTLD: "xn--mgbt3dhd", + DelegationDate: "2015-12-07", + RemovalDate: "", + }, + "xn--mgbtx2b": { + GTLD: "xn--mgbtx2b", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mgbx4cd0ab": { + GTLD: "xn--mgbx4cd0ab", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mix891f": { + GTLD: "xn--mix891f", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--mk1bu44c": { + GTLD: "xn--mk1bu44c", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--mxtq1m": { + GTLD: "xn--mxtq1m", + DelegationDate: "2015-03-03", + RemovalDate: "", + }, + "xn--ngbc5azd": { + GTLD: "xn--ngbc5azd", + DelegationDate: "2013-10-23", + RemovalDate: "", + }, + "xn--ngbe9e0a": { + GTLD: "xn--ngbe9e0a", + DelegationDate: "2015-12-15", + RemovalDate: "", + }, + "xn--ngbrx": { + GTLD: "xn--ngbrx", + DelegationDate: "2017-05-23", + RemovalDate: "", + }, + "xn--node": { + GTLD: "xn--node", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--nqv7f": { + GTLD: "xn--nqv7f", + DelegationDate: "2014-03-09", + RemovalDate: "", + }, + "xn--nqv7fs00ema": { + GTLD: "xn--nqv7fs00ema", + DelegationDate: "2014-03-09", + RemovalDate: "", + }, + "xn--nyqy26a": { + GTLD: "xn--nyqy26a", + DelegationDate: "2015-04-02", + RemovalDate: "", + }, + "xn--o3cw4h": { + GTLD: "xn--o3cw4h", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--ogbpf8fl": { + GTLD: "xn--ogbpf8fl", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--otu796d": { + GTLD: "xn--otu796d", + DelegationDate: "2018-01-24", + RemovalDate: "", + }, + "xn--p1acf": { + GTLD: "xn--p1acf", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "xn--p1ai": { + GTLD: "xn--p1ai", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--pbt977c": { + GTLD: "xn--pbt977c", + DelegationDate: "2015-12-15", + RemovalDate: "2020-06-26", + }, + "xn--pgbs0dh": { + GTLD: "xn--pgbs0dh", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--pssy2u": { + GTLD: "xn--pssy2u", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--q7ce6a": { + GTLD: "xn--q7ce6a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--q9jyb4c": { + GTLD: "xn--q9jyb4c", + DelegationDate: "2013-11-23", + RemovalDate: "", + }, + "xn--qcka1pmc": { + GTLD: "xn--qcka1pmc", + DelegationDate: "2014-11-20", + RemovalDate: "", + }, + "xn--qxa6a": { + GTLD: "xn--qxa6a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--qxam": { + GTLD: "xn--qxam", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--rhqv96g": { + GTLD: "xn--rhqv96g", + DelegationDate: "2014-03-12", + RemovalDate: "", + }, + "xn--rovu88b": { + GTLD: "xn--rovu88b", + DelegationDate: "2016-02-19", + RemovalDate: "", + }, + "xn--rvc1e0am3e": { + GTLD: "xn--rvc1e0am3e", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--s9brj9c": { + GTLD: "xn--s9brj9c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--ses554g": { + GTLD: "xn--ses554g", + DelegationDate: "2014-04-10", + RemovalDate: "", + }, + "xn--t60b56a": { + GTLD: "xn--t60b56a", + DelegationDate: "2015-07-28", + RemovalDate: "", + }, + "xn--tckwe": { + GTLD: "xn--tckwe", + DelegationDate: "2015-07-29", + RemovalDate: "", + }, + "xn--tiq49xqyj": { + GTLD: "xn--tiq49xqyj", + DelegationDate: "2016-12-01", + RemovalDate: "", + }, + "xn--unup4y": { + GTLD: "xn--unup4y", + DelegationDate: "2013-10-23", + RemovalDate: "", + }, + "xn--vermgensberater-ctb": { + GTLD: "xn--vermgensberater-ctb", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "xn--vermgensberatung-pwb": { + GTLD: "xn--vermgensberatung-pwb", + DelegationDate: "2014-09-27", + RemovalDate: "", + }, + "xn--vhquv": { + GTLD: "xn--vhquv", + DelegationDate: "2014-08-22", + RemovalDate: "", + }, + "xn--vuq861b": { + GTLD: "xn--vuq861b", + DelegationDate: "2015-03-18", + RemovalDate: "", + }, + "xn--w4r85el8fhu5dnra": { + GTLD: "xn--w4r85el8fhu5dnra", + DelegationDate: "2016-03-05", + RemovalDate: "", + }, + "xn--w4rs40l": { + GTLD: "xn--w4rs40l", + DelegationDate: "2016-05-16", + RemovalDate: "", + }, + "xn--wgbh1c": { + GTLD: "xn--wgbh1c", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--wgbl6a": { + GTLD: "xn--wgbl6a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--xhq521b": { + GTLD: "xn--xhq521b", + DelegationDate: "2014-08-14", + RemovalDate: "", + }, + "xn--xkc2al3hye2a": { + GTLD: "xn--xkc2al3hye2a", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--xkc2dl3a5ee0h": { + GTLD: "xn--xkc2dl3a5ee0h", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--y9a3aq": { + GTLD: "xn--y9a3aq", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--yfro4i67o": { + GTLD: "xn--yfro4i67o", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--ygbi2ammx": { + GTLD: "xn--ygbi2ammx", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "xn--zfr164b": { + GTLD: "xn--zfr164b", + DelegationDate: "2013-12-17", + RemovalDate: "", + }, + "xperia": { + GTLD: "xperia", + DelegationDate: "2015-08-05", + RemovalDate: "2018-07-20", + }, + "xxx": { + GTLD: "xxx", + DelegationDate: "2011-04-15", + RemovalDate: "", + }, + "xyz": { + GTLD: "xyz", + DelegationDate: "2014-02-19", + RemovalDate: "", + }, + "yachts": { + GTLD: "yachts", + DelegationDate: "2014-05-22", + RemovalDate: "", + }, + "yahoo": { + GTLD: "yahoo", + DelegationDate: "2016-02-13", + RemovalDate: "", + }, + "yamaxun": { + GTLD: "yamaxun", + DelegationDate: "2015-10-07", + RemovalDate: "", + }, + "yandex": { + GTLD: "yandex", + DelegationDate: "2014-07-18", + RemovalDate: "", + }, + "ye": { + GTLD: "ye", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "yodobashi": { + GTLD: "yodobashi", + DelegationDate: "2015-02-19", + RemovalDate: "", + }, + "yoga": { + GTLD: "yoga", + DelegationDate: "2014-10-15", + RemovalDate: "", + }, + "yokohama": { + GTLD: "yokohama", + DelegationDate: "2014-04-03", + RemovalDate: "", + }, + "you": { + GTLD: "you", + DelegationDate: "2016-03-25", + RemovalDate: "", + }, + "youtube": { + GTLD: "youtube", + DelegationDate: "2014-08-29", + RemovalDate: "", + }, + "yt": { + GTLD: "yt", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "yun": { + GTLD: "yun", + DelegationDate: "2016-03-30", + RemovalDate: "", + }, + "za": { + GTLD: "za", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "zappos": { + GTLD: "zappos", + DelegationDate: "2016-06-02", + RemovalDate: "", + }, + "zara": { + GTLD: "zara", + DelegationDate: "2015-10-27", + RemovalDate: "", + }, + "zero": { + GTLD: "zero", + DelegationDate: "2015-12-05", + RemovalDate: "", + }, + "zip": { + GTLD: "zip", + DelegationDate: "2014-09-15", + RemovalDate: "", + }, + "zippo": { + GTLD: "zippo", + DelegationDate: "2016-07-02", + RemovalDate: "2019-02-15", + }, + "zm": { + GTLD: "zm", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + "zone": { + GTLD: "zone", + DelegationDate: "2014-01-14", + RemovalDate: "", + }, + "zuerich": { + GTLD: "zuerich", + DelegationDate: "2014-12-25", + RemovalDate: "", + }, + "zw": { + GTLD: "zw", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, + // .onion is a special case and not a general gTLD. However, it is allowed in + // some circumstances in the web PKI so the Zlint gtldMap includes it with + // a delegationDate based on the CABF ballot to allow EV issuance for .onion + // domains: https://cabforum.org/2015/02/18/ballot-144-validation-rules-dot-onion-names/ + "onion": { + GTLD: "onion", + DelegationDate: "2015-02-18", + RemovalDate: "", + }, +} diff --git a/vendor/github.com/zmap/zlint/v2/util/ip.go b/vendor/github.com/zmap/zlint/v2/util/ip.go new file mode 100644 index 0000000000..104645086e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/ip.go @@ -0,0 +1,127 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// contains helper functions for ip address lints + +package util + +import ( + "fmt" + "net" +) + +type subnetCategory int + +const ( + privateUse subnetCategory = iota + sharedAddressSpace + benchmarking + documentation + reserved + protocolAssignment + as112 + amt + orchidV2 + _ // deprecated: lisp + thisHostOnThisNetwork + translatableAddress6to4 + translatableAddress4to6 + dummyAddress + portControlProtocolAnycast + traversalUsingRelaysAroundNATAnycast + nat64DNS64Discovery + limitedBroadcast + discardOnly + teredo + uniqueLocal + linkLocalUnicast + ianaReservedForFutureUse + ianaReservedMulticast +) + +var reservedNetworks []*net.IPNet + +// IsIANAReserved checks IP validity as per IANA reserved IPs +// IPv4 +// https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +// https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xml +// IPv6 +// https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml +// https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml +func IsIANAReserved(ip net.IP) bool { + if !ip.IsGlobalUnicast() { + return true + } + + for _, network := range reservedNetworks { + if network.Contains(ip) { + return true + } + } + + return false +} + +// IntersectsIANAReserved checks if a CIDR intersects any IANA reserved CIDRs +func IntersectsIANAReserved(net net.IPNet) bool { + if !net.IP.IsGlobalUnicast() { + return true + } + for _, reserved := range reservedNetworks { + if reserved.Contains(net.IP) || net.Contains(reserved.IP) { + return true + } + } + return false +} + +func init() { + var networks = map[subnetCategory][]string{ + privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + sharedAddressSpace: {"100.64.0.0/10"}, + benchmarking: {"198.18.0.0/15", "2001:2::/48"}, + documentation: {"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24", "2001:db8::/32"}, + reserved: {"240.0.0.0/4", "0400::/6", "0800::/5", "1000::/4", "4000::/3", "6000::/3", "8000::/3", "a000::/3", "c000::/3", "e000::/4", "f000::/5", "f800::/6", "fe00::/9"}, // https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml + protocolAssignment: {"192.0.0.0/24", "2001::/23"}, // 192.0.0.0/24 contains 192.0.0.0/29 - IPv4 Service Continuity Prefix + as112: {"192.31.196.0/24", "192.175.48.0/24", "2001:4:112::/48", "2620:4f:8000::/48"}, + amt: {"192.52.193.0/24", "2001:3::/32"}, + orchidV2: {"2001:20::/28"}, + thisHostOnThisNetwork: {"0.0.0.0/8"}, + translatableAddress4to6: {"2002::/16"}, + translatableAddress6to4: {"64:ff9b::/96", "64:ff9b:1::/48"}, + dummyAddress: {"192.0.0.8/32"}, + portControlProtocolAnycast: {"192.0.0.9/32", "2001:1::1/128"}, + traversalUsingRelaysAroundNATAnycast: {"192.0.0.10/32", "2001:1::2/128"}, + nat64DNS64Discovery: {"192.0.0.170/32", "192.0.0.171/32"}, + limitedBroadcast: {"255.255.255.255/32"}, + discardOnly: {"100::/64"}, + teredo: {"2001::/32"}, + uniqueLocal: {"fc00::/7"}, + linkLocalUnicast: {"fe80::/10", "169.254.0.0/16"}, // this range is covered by ip.IsLinkLocalUnicast(), which is in turn called by net.IP.IsGlobalUnicast(ip) + ianaReservedForFutureUse: {"255.0.0.0/8", "254.0.0.0/8", "253.0.0.0/8", "252.0.0.0/8", "251.0.0.0/8", "250.0.0.0/8", "249.0.0.0/8", "248.0.0.0/8", "247.0.0.0/8", "246.0.0.0/8", "245.0.0.0/8", "244.0.0.0/8", "243.0.0.0/8", "242.0.0.0/8", "241.0.0.0/8", "240.0.0.0/8"}, + ianaReservedMulticast: {"239.0.0.0/8", "238.0.0.0/8", "237.0.0.0/8", "236.0.0.0/8", "235.0.0.0/8", "234.0.0.0/8", "233.0.0.0/8", "232.0.0.0/8", "231.0.0.0/8", "230.0.0.0/8", "229.0.0.0/8", "228.0.0.0/8", "227.0.0.0/8", "226.0.0.0/8", "225.0.0.0/8", "224.0.0.0/8", "ff00::/8"}, // this range is covered by ip.IsMulticast() call, which is in turn called by net.IP.IsGlobalUnicast(ip) + } + + for _, netList := range networks { + for _, network := range netList { + var ipNet *net.IPNet + var err error + + if _, ipNet, err = net.ParseCIDR(network); err != nil { + panic(fmt.Sprintf("unexpected internal network value provided: %s", err.Error())) + } + reservedNetworks = append(reservedNetworks, ipNet) + } + } +} diff --git a/vendor/github.com/zmap/zlint/v2/util/ku.go b/vendor/github.com/zmap/zlint/v2/util/ku.go new file mode 100644 index 0000000000..31a828fb4e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/ku.go @@ -0,0 +1,18 @@ +package util + +import "github.com/zmap/zcrypto/x509" + +var ( + // KeyUsageToString maps an x509.KeyUsage bitmask to its name. + KeyUsageToString = map[x509.KeyUsage]string{ + x509.KeyUsageDigitalSignature: "KeyUsageDigitalSignature", + x509.KeyUsageContentCommitment: "KeyUsageContentCommitment", + x509.KeyUsageKeyEncipherment: "KeyUsageKeyEncipherment", + x509.KeyUsageDataEncipherment: "KeyUsageDataEncipherment", + x509.KeyUsageKeyAgreement: "KeyUsageKeyAgreement", + x509.KeyUsageCertSign: "KeyUsageCertSign", + x509.KeyUsageCRLSign: "KeyUsageCRLSign", + x509.KeyUsageEncipherOnly: "KeyUsageEncipherOnly", + x509.KeyUsageDecipherOnly: "KeyUsageDecipherOnly", + } +) diff --git a/vendor/github.com/zmap/zlint/v2/util/names.go b/vendor/github.com/zmap/zlint/v2/util/names.go new file mode 100644 index 0000000000..861194e0a9 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/names.go @@ -0,0 +1,64 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "encoding/asn1" + + "github.com/zmap/zcrypto/x509/pkix" +) + +type empty struct{} + +var nameAttributePrefix = asn1.ObjectIdentifier{2, 5, 4} +var nameAttributeLeaves = map[int]empty{ + // Name attributes defined in RFC 5280 appendix A + 3: {}, // id-at-commonName AttributeType ::= { id-at 3 } + 4: {}, // id-at-surname AttributeType ::= { id-at 4 } + 5: {}, // id-at-serialNumber AttributeType ::= { id-at 5 } + 6: {}, // id-at-countryName AttributeType ::= { id-at 6 } + 7: {}, // id-at-localityName AttributeType ::= { id-at 7 } + 8: {}, // id-at-stateOrProvinceName AttributeType ::= { id-at 8 } + 10: {}, // id-at-organizationName AttributeType ::= { id-at 10 } + 11: {}, // id-at-organizationalUnitName AttributeType ::= { id-at 11 } + 12: {}, // id-at-title AttributeType ::= { id-at 12 } + 41: {}, // id-at-name AttributeType ::= { id-at 41 } + 42: {}, // id-at-givenName AttributeType ::= { id-at 42 } + 43: {}, // id-at-initials AttributeType ::= { id-at 43 } + 44: {}, // id-at-generationQualifier AttributeType ::= { id-at 44 } + 46: {}, // id-at-dnQualifier AttributeType ::= { id-at 46 } + + // Name attributes not present in RFC 5280, but appeared in Go's crypto/x509/pkix.go + 9: {}, // id-at-streetName AttributeType ::= { id-at 9 } + 17: {}, // id-at-postalCodeName AttributeType ::= { id-at 17 } +} + +// IsNameAttribute returns true if the given ObjectIdentifier corresponds with +// the type of any name attribute for PKIX. +func IsNameAttribute(oid asn1.ObjectIdentifier) bool { + if len(oid) != 4 { + return false + } + if !nameAttributePrefix.Equal(oid[0:3]) { + return false + } + _, ok := nameAttributeLeaves[oid[3]] + return ok +} + +func NotAllNameFieldsAreEmpty(name *pkix.Name) bool { + //Return true if at least one field is non-empty + return len(name.Names) >= 1 +} diff --git a/vendor/github.com/zmap/zlint/v2/util/oid.go b/vendor/github.com/zmap/zlint/v2/util/oid.go new file mode 100644 index 0000000000..f52b2fb755 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/oid.go @@ -0,0 +1,183 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "encoding/asn1" + "errors" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" +) + +var ( + //extension OIDs + AiaOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1} // Authority Information Access + AuthkeyOID = asn1.ObjectIdentifier{2, 5, 29, 35} // Authority Key Identifier + BasicConstOID = asn1.ObjectIdentifier{2, 5, 29, 19} // Basic Constraints + CertPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 32} // Certificate Policies + CrlDistOID = asn1.ObjectIdentifier{2, 5, 29, 31} // CRL Distribution Points + CtPoisonOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // CT Poison + EkuSynOid = asn1.ObjectIdentifier{2, 5, 29, 37} // Extended Key Usage Syntax + FreshCRLOID = asn1.ObjectIdentifier{2, 5, 29, 46} // Freshest CRL + InhibitAnyPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 54} // Inhibit Any Policy + IssuerAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 18} // Issuer Alt Name + KeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 15} // Key Usage + LogoTypeOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 12} // Logo Type Ext + NameConstOID = asn1.ObjectIdentifier{2, 5, 29, 30} // Name Constraints + OscpNoCheckOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5} // OSCP No Check + PolicyConstOID = asn1.ObjectIdentifier{2, 5, 29, 36} // Policy Constraints + PolicyMapOID = asn1.ObjectIdentifier{2, 5, 29, 33} // Policy Mappings + PrivKeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 16} // Private Key Usage Period + QcStateOid = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3} // QC Statements + TimestampOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} // Signed Certificate Timestamp List + SmimeOID = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 15} // Smime Capabilities + SubjectAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 17} // Subject Alt Name + SubjectDirAttrOID = asn1.ObjectIdentifier{2, 5, 29, 9} // Subject Directory Attributes + SubjectInfoAccessOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11} // Subject Info Access Syntax + SubjectKeyIdentityOID = asn1.ObjectIdentifier{2, 5, 29, 14} // Subject Key Identifier + // CA/B reserved policies + BRDomainValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1} // CA/B BR Domain-Validated + BROrganizationValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2} // CA/B BR Organization-Validated + BRIndividualValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3} // CA/B BR Individual-Validated + BRTorServiceDescriptor = asn1.ObjectIdentifier{2, 23, 140, 1, 31} // CA/B BR Tor Service Descriptor + //X.500 attribute types + CommonNameOID = asn1.ObjectIdentifier{2, 5, 4, 3} + SurnameOID = asn1.ObjectIdentifier{2, 5, 4, 4} + SerialOID = asn1.ObjectIdentifier{2, 5, 4, 5} + CountryNameOID = asn1.ObjectIdentifier{2, 5, 4, 6} + LocalityNameOID = asn1.ObjectIdentifier{2, 5, 4, 7} + StateOrProvinceNameOID = asn1.ObjectIdentifier{2, 5, 4, 8} + StreetAddressOID = asn1.ObjectIdentifier{2, 5, 4, 9} + OrganizationNameOID = asn1.ObjectIdentifier{2, 5, 4, 10} + OrganizationalUnitNameOID = asn1.ObjectIdentifier{2, 5, 4, 11} + BusinessOID = asn1.ObjectIdentifier{2, 5, 4, 15} + PostalCodeOID = asn1.ObjectIdentifier{2, 5, 4, 17} + GivenNameOID = asn1.ObjectIdentifier{2, 5, 4, 42} + // Hash algorithms - see https://golang.org/src/crypto/x509/x509.go + SHA256OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} + SHA384OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} + SHA512OID = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} + // other OIDs + OidRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} + OidRSASSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} + OidMD2WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} + OidMD5WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} + OidSHA1WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} + OidSHA224WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 14} + OidSHA256WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} + OidSHA384WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} + OidSHA512WithRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} + AnyPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 32, 0} + UserNoticeOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2} + CpsOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1} + IdEtsiQcsQcCompliance = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 1} + IdEtsiQcsQcLimitValue = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 2} + IdEtsiQcsQcRetentionPeriod = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 3} + IdEtsiQcsQcSSCD = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 4} + IdEtsiQcsQcEuPDS = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 5} + IdEtsiQcsQcType = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6} + IdEtsiQcsQctEsign = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 1} + IdEtsiQcsQctEseal = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 2} + IdEtsiQcsQctWeb = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 3} +) + +const ( + // Tags + DNSNameTag = 2 +) + +// IsExtInCert is equivalent to GetExtFromCert() != nil. +func IsExtInCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) bool { + if cert != nil && GetExtFromCert(cert, oid) != nil { + return true + } + return false +} + +// GetExtFromCert returns the extension with the matching OID, if present. If +// the extension if not present, it returns nil. +//nolint:interfacer +func GetExtFromCert(cert *x509.Certificate, oid asn1.ObjectIdentifier) *pkix.Extension { + // Since this function is called by many Lint CheckApplies functions we use + // the x509.Certificate.ExtensionsMap field added by zcrypto to check for + // the extension in O(1) instead of looping through the + // `x509.Certificate.Extensions` in O(n). + if ext, found := cert.ExtensionsMap[oid.String()]; found { + return &ext + } + return nil +} + +// Helper function that checks if an []asn1.ObjectIdentifier slice contains an asn1.ObjectIdentifier +func SliceContainsOID(list []asn1.ObjectIdentifier, oid asn1.ObjectIdentifier) bool { + for _, v := range list { + if oid.Equal(v) { + return true + } + } + return false +} + +// Helper function that checks for a name type in a pkix.Name +func TypeInName(name *pkix.Name, oid asn1.ObjectIdentifier) bool { + for _, v := range name.Names { + if oid.Equal(v.Type) { + return true + } + } + return false +} + +//helper function to parse policyMapping extensions, returns slices of CertPolicyIds separated by domain +func GetMappedPolicies(polMap *pkix.Extension) ([][2]asn1.ObjectIdentifier, error) { + if polMap == nil { + return nil, errors.New("policyMap: null pointer") + } + var outSeq, inSeq asn1.RawValue + + empty, err := asn1.Unmarshal(polMap.Value, &outSeq) //strip outer sequence tag/length should be nothing extra + if err != nil || len(empty) != 0 || outSeq.Class != 0 || outSeq.Tag != 16 || !outSeq.IsCompound { + return nil, errors.New("policyMap: Could not unmarshal outer sequence.") + } + + var out [][2]asn1.ObjectIdentifier + for done := false; !done; { //loop through SEQUENCE OF + outSeq.Bytes, err = asn1.Unmarshal(outSeq.Bytes, &inSeq) //extract next inner SEQUENCE (OID pair) + if err != nil || inSeq.Class != 0 || inSeq.Tag != 16 || !inSeq.IsCompound { + return nil, errors.New("policyMap: Could not unmarshal inner sequence.") + } + if len(outSeq.Bytes) == 0 { //nothing remaining to parse, stop looping after + done = true + } + + var oidIssue, oidSubject asn1.ObjectIdentifier + var restIn asn1.RawContent + restIn, err = asn1.Unmarshal(inSeq.Bytes, &oidIssue) //extract first inner CertPolicyId (issuer domain) + if err != nil || len(restIn) == 0 { + return nil, errors.New("policyMap: Could not unmarshal inner sequence.") + } + + empty, err = asn1.Unmarshal(restIn, &oidSubject) //extract second inner CertPolicyId (subject domain) + if err != nil || len(empty) != 0 { + return nil, errors.New("policyMap: Could not unmarshal inner sequence.") + } + + //append found OIDs + out = append(out, [2]asn1.ObjectIdentifier{oidIssue, oidSubject}) + } + + return out, nil +} diff --git a/vendor/github.com/zmap/zlint/v2/util/primes.go b/vendor/github.com/zmap/zlint/v2/util/primes.go new file mode 100644 index 0000000000..f7833b6469 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/primes.go @@ -0,0 +1,57 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import "math/big" + +var bigIntPrimes = []*big.Int{ + big.NewInt(2), big.NewInt(3), big.NewInt(5), big.NewInt(7), big.NewInt(11), big.NewInt(13), + big.NewInt(17), big.NewInt(19), big.NewInt(23), big.NewInt(29), big.NewInt(31), big.NewInt(37), + big.NewInt(41), big.NewInt(43), big.NewInt(47), big.NewInt(53), big.NewInt(59), big.NewInt(61), + big.NewInt(67), big.NewInt(71), big.NewInt(73), big.NewInt(79), big.NewInt(83), big.NewInt(89), + big.NewInt(97), big.NewInt(101), big.NewInt(103), big.NewInt(107), big.NewInt(109), big.NewInt(113), + big.NewInt(127), big.NewInt(131), big.NewInt(137), big.NewInt(139), big.NewInt(149), big.NewInt(151), + big.NewInt(157), big.NewInt(163), big.NewInt(167), big.NewInt(173), big.NewInt(179), big.NewInt(181), + big.NewInt(191), big.NewInt(193), big.NewInt(197), big.NewInt(199), big.NewInt(211), big.NewInt(223), + big.NewInt(227), big.NewInt(229), big.NewInt(233), big.NewInt(239), big.NewInt(241), big.NewInt(251), + big.NewInt(257), big.NewInt(263), big.NewInt(269), big.NewInt(271), big.NewInt(277), big.NewInt(281), + big.NewInt(283), big.NewInt(293), big.NewInt(307), big.NewInt(311), big.NewInt(353), big.NewInt(359), + big.NewInt(367), big.NewInt(373), big.NewInt(379), big.NewInt(383), big.NewInt(313), big.NewInt(317), + big.NewInt(331), big.NewInt(337), big.NewInt(347), big.NewInt(349), big.NewInt(389), big.NewInt(397), + big.NewInt(401), big.NewInt(409), big.NewInt(419), big.NewInt(421), big.NewInt(431), big.NewInt(433), + big.NewInt(439), big.NewInt(443), big.NewInt(449), big.NewInt(457), big.NewInt(461), big.NewInt(463), + big.NewInt(467), big.NewInt(479), big.NewInt(487), big.NewInt(491), big.NewInt(499), big.NewInt(503), + big.NewInt(509), big.NewInt(521), big.NewInt(523), big.NewInt(541), big.NewInt(547), big.NewInt(557), + big.NewInt(563), big.NewInt(569), big.NewInt(571), big.NewInt(577), big.NewInt(587), big.NewInt(593), + big.NewInt(599), big.NewInt(601), big.NewInt(607), big.NewInt(613), big.NewInt(617), big.NewInt(619), + big.NewInt(631), big.NewInt(641), big.NewInt(643), big.NewInt(647), big.NewInt(653), big.NewInt(659), + big.NewInt(661), big.NewInt(673), big.NewInt(677), big.NewInt(683), big.NewInt(691), big.NewInt(701), + big.NewInt(709), big.NewInt(719), big.NewInt(727), big.NewInt(733), big.NewInt(739), big.NewInt(743), + big.NewInt(751), +} + +var zero = big.NewInt(0) + +func PrimeNoSmallerThan752(dividend *big.Int) bool { + quotient := big.NewInt(0) + mod := big.NewInt(0) + for _, divisor := range bigIntPrimes { + quotient.DivMod(dividend, divisor, mod) + if mod.Cmp(zero) == 0 { + return false + } + } + return true +} diff --git a/vendor/github.com/zmap/zlint/v2/util/qc_stmt.go b/vendor/github.com/zmap/zlint/v2/util/qc_stmt.go new file mode 100644 index 0000000000..156210f50f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/qc_stmt.go @@ -0,0 +1,253 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "bytes" + "encoding/asn1" + "fmt" + "reflect" +) + +type anyContent struct { + Raw asn1.RawContent +} + +type qcStatementWithInfoField struct { + Oid asn1.ObjectIdentifier + Any asn1.RawValue +} +type qcStatementWithoutInfoField struct { + Oid asn1.ObjectIdentifier +} + +type etsiBase struct { + errorInfo string + isPresent bool +} + +func (this etsiBase) GetErrorInfo() string { + return this.errorInfo +} + +func (this etsiBase) IsPresent() bool { + return this.isPresent +} + +type EtsiQcStmtIf interface { + GetErrorInfo() string + IsPresent() bool +} + +type Etsi421QualEuCert struct { + etsiBase +} + +type Etsi423QcType struct { + etsiBase + TypeOids []asn1.ObjectIdentifier +} + +type EtsiQcSscd struct { + etsiBase +} + +type EtsiMonetaryValueAlph struct { + Iso4217CurrencyCodeAlph string `asn1:"printable"` + Amount int + Exponent int +} +type EtsiMonetaryValueNum struct { + Iso4217CurrencyCodeNum int + Amount int + Exponent int +} + +type EtsiQcLimitValue struct { + etsiBase + Amount int + Exponent int + IsNum bool + CurrencyAlph string + CurrencyNum int +} + +type EtsiQcRetentionPeriod struct { + etsiBase + Period int +} +type PdsLocation struct { + Url string `asn1:"ia5"` + Language string `asn1:"printable"` +} +type EtsiQcPds struct { + etsiBase + PdsLocations []PdsLocation +} + +func AppendToStringSemicolonDelim(this *string, s string) { + if len(*this) > 0 && len(s) > 0 { + (*this) += "; " + } + (*this) += s +} + +func checkAsn1Reencoding(i interface{}, originalEncoding []byte, appendIfComparisonFails string) string { + result := "" + reencoded, marshErr := asn1.Marshal(i) + if marshErr != nil { + AppendToStringSemicolonDelim(&result, fmt.Sprintf("error reencoding ASN1 value of statementInfo field: %s", + marshErr)) + } + if !bytes.Equal(reencoded, originalEncoding) { + AppendToStringSemicolonDelim(&result, appendIfComparisonFails) + } + return result +} + +func IsAnyEtsiQcStatementPresent(extVal []byte) bool { + oidList := make([]*asn1.ObjectIdentifier, 6) + oidList[0] = &IdEtsiQcsQcCompliance + oidList[1] = &IdEtsiQcsQcLimitValue + oidList[2] = &IdEtsiQcsQcRetentionPeriod + oidList[3] = &IdEtsiQcsQcSSCD + oidList[4] = &IdEtsiQcsQcEuPDS + oidList[5] = &IdEtsiQcsQcType + for _, oid := range oidList { + r := ParseQcStatem(extVal, *oid) + if r.IsPresent() { + return true + } + } + return false +} + +//nolint:gocyclo +func ParseQcStatem(extVal []byte, sought asn1.ObjectIdentifier) EtsiQcStmtIf { + sl := make([]anyContent, 0) + rest, err := asn1.Unmarshal(extVal, &sl) + if err != nil { + return etsiBase{errorInfo: "error parsing outer SEQ", isPresent: true} + } + if len(rest) != 0 { + return etsiBase{errorInfo: "rest len of outer seq != 0", isPresent: true} + } + + for _, raw := range sl { + parseErrorString := "format error in at least one QC statement within the QC statements extension." + + " this message may appear multiple times for the same error cause." + var statem qcStatementWithInfoField + rest, err = asn1.Unmarshal(raw.Raw, &statem) + if err != nil { + var statemWithoutInfo qcStatementWithoutInfoField + + rest, err = asn1.Unmarshal(raw.Raw, &statemWithoutInfo) + if err != nil || len(rest) != 0 { + return etsiBase{errorInfo: parseErrorString, isPresent: false} + } + copy(statem.Oid, statemWithoutInfo.Oid) + if len(statem.Any.FullBytes) != 0 { + return etsiBase{errorInfo: "internal error, default optional content len is not zero"} + } + } else if 0 != len(rest) { + return etsiBase{errorInfo: parseErrorString, isPresent: false} + } + + if !statem.Oid.Equal(sought) { + continue + } + if statem.Oid.Equal(IdEtsiQcsQcCompliance) { + etsiObj := Etsi421QualEuCert{etsiBase: etsiBase{isPresent: true}} + statemWithoutInfo := qcStatementWithoutInfoField{Oid: statem.Oid} + AppendToStringSemicolonDelim(&etsiObj.errorInfo, checkAsn1Reencoding(reflect.ValueOf(statemWithoutInfo).Interface(), raw.Raw, + "invalid format of ETSI Complicance statement")) + return etsiObj + } else if statem.Oid.Equal(IdEtsiQcsQcLimitValue) { + etsiObj := EtsiQcLimitValue{etsiBase: etsiBase{isPresent: true}} + numErr := false + alphErr := false + var numeric EtsiMonetaryValueNum + var alphabetic EtsiMonetaryValueAlph + restNum, errNum := asn1.Unmarshal(statem.Any.FullBytes, &numeric) + if len(restNum) != 0 || errNum != nil { + numErr = true + } else { + etsiObj.IsNum = true + etsiObj.Amount = numeric.Amount + etsiObj.Exponent = numeric.Exponent + etsiObj.CurrencyNum = numeric.Iso4217CurrencyCodeNum + + } + if numErr { + restAlph, errAlph := asn1.Unmarshal(statem.Any.FullBytes, &alphabetic) + if len(restAlph) != 0 || errAlph != nil { + alphErr = true + } else { + etsiObj.IsNum = false + etsiObj.Amount = alphabetic.Amount + etsiObj.Exponent = alphabetic.Exponent + etsiObj.CurrencyAlph = alphabetic.Iso4217CurrencyCodeAlph + AppendToStringSemicolonDelim(&etsiObj.errorInfo, + checkAsn1Reencoding(reflect.ValueOf(alphabetic).Interface(), + statem.Any.FullBytes, "error with ASN.1 encoding, possibly a wrong ASN.1 string type was used")) + } + } + if numErr && alphErr { + etsiObj.errorInfo = "error parsing the ETSI Qc Statement statementInfo field" + } + return etsiObj + + } else if statem.Oid.Equal(IdEtsiQcsQcRetentionPeriod) { + etsiObj := EtsiQcRetentionPeriod{etsiBase: etsiBase{isPresent: true}} + rest, err := asn1.Unmarshal(statem.Any.FullBytes, &etsiObj.Period) + + if len(rest) != 0 || err != nil { + etsiObj.errorInfo = "error parsing the statementInfo field" + } + return etsiObj + } else if statem.Oid.Equal(IdEtsiQcsQcSSCD) { + etsiObj := EtsiQcSscd{etsiBase: etsiBase{isPresent: true}} + statemWithoutInfo := qcStatementWithoutInfoField{Oid: statem.Oid} + AppendToStringSemicolonDelim(&etsiObj.errorInfo, checkAsn1Reencoding(reflect.ValueOf(statemWithoutInfo).Interface(), raw.Raw, + "invalid format of ETSI SCSD statement")) + return etsiObj + } else if statem.Oid.Equal(IdEtsiQcsQcEuPDS) { + etsiObj := EtsiQcPds{etsiBase: etsiBase{isPresent: true}} + rest, err := asn1.Unmarshal(statem.Any.FullBytes, &etsiObj.PdsLocations) + if len(rest) != 0 || err != nil { + etsiObj.errorInfo = "error parsing the statementInfo field" + } else { + AppendToStringSemicolonDelim(&etsiObj.errorInfo, + checkAsn1Reencoding(reflect.ValueOf(etsiObj.PdsLocations).Interface(), statem.Any.FullBytes, + "error with ASN.1 encoding, possibly a wrong ASN.1 string type was used")) + } + return etsiObj + } else if statem.Oid.Equal(IdEtsiQcsQcType) { + var qcType Etsi423QcType + qcType.isPresent = true + rest, err := asn1.Unmarshal(statem.Any.FullBytes, &qcType.TypeOids) + if len(rest) != 0 || err != nil { + return etsiBase{errorInfo: "error parsing IdEtsiQcsQcType extension statementInfo field", isPresent: true} + } + return qcType + } else { + return etsiBase{errorInfo: "", isPresent: true} + } + + } + + return etsiBase{errorInfo: "", isPresent: false} + +} diff --git a/vendor/github.com/zmap/zlint/v2/util/rdn.go b/vendor/github.com/zmap/zlint/v2/util/rdn.go new file mode 100644 index 0000000000..c5af921e79 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/rdn.go @@ -0,0 +1,26 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import "encoding/asn1" + +type AttributeTypeAndRawValue struct { + Type asn1.ObjectIdentifier + Value asn1.RawValue +} + +type AttributeTypeAndRawValueSET []AttributeTypeAndRawValue + +type RawRDNSequence []AttributeTypeAndRawValueSET diff --git a/vendor/github.com/zmap/zlint/v2/util/time.go b/vendor/github.com/zmap/zlint/v2/util/time.go new file mode 100644 index 0000000000..b58c56a774 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/util/time.go @@ -0,0 +1,112 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +package util + +import ( + "encoding/asn1" + "time" + + "github.com/zmap/zcrypto/x509" +) + +var ( + ZeroDate = time.Date(0000, time.January, 1, 0, 0, 0, 0, time.UTC) + RFC1035Date = time.Date(1987, time.January, 1, 0, 0, 0, 0, time.UTC) + RFC2459Date = time.Date(1999, time.January, 1, 0, 0, 0, 0, time.UTC) + RFC3280Date = time.Date(2002, time.April, 1, 0, 0, 0, 0, time.UTC) + RFC3490Date = time.Date(2003, time.March, 1, 0, 0, 0, 0, time.UTC) + RFC8399Date = time.Date(2018, time.May, 1, 0, 0, 0, 0, time.UTC) + RFC4325Date = time.Date(2005, time.December, 1, 0, 0, 0, 0, time.UTC) + RFC4630Date = time.Date(2006, time.August, 1, 0, 0, 0, 0, time.UTC) + RFC5280Date = time.Date(2008, time.May, 1, 0, 0, 0, 0, time.UTC) + RFC6818Date = time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC) + CABEffectiveDate = time.Date(2012, time.July, 1, 0, 0, 0, 0, time.UTC) + CABReservedIPDate = time.Date(2016, time.October, 1, 0, 0, 0, 0, time.UTC) + CABGivenNameDate = time.Date(2016, time.September, 7, 0, 0, 0, 0, time.UTC) + CABSerialNumberEntropyDate = time.Date(2016, time.September, 30, 0, 0, 0, 0, time.UTC) + CABV102Date = time.Date(2012, time.June, 8, 0, 0, 0, 0, time.UTC) + CABV113Date = time.Date(2013, time.February, 21, 0, 0, 0, 0, time.UTC) + CABV114Date = time.Date(2013, time.May, 3, 0, 0, 0, 0, time.UTC) + CABV116Date = time.Date(2013, time.July, 29, 0, 0, 0, 0, time.UTC) + CABV130Date = time.Date(2015, time.April, 16, 0, 0, 0, 0, time.UTC) + CABV131Date = time.Date(2015, time.September, 28, 0, 0, 0, 0, time.UTC) + NO_SHA1 = time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC) + NoRSA1024RootDate = time.Date(2011, time.January, 1, 0, 0, 0, 0, time.UTC) + NoRSA1024Date = time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC) + GeneralizedDate = time.Date(2050, time.January, 1, 0, 0, 0, 0, time.UTC) + NoReservedIP = time.Date(2015, time.November, 1, 0, 0, 0, 0, time.UTC) + SubCert39Month = time.Date(2016, time.July, 2, 0, 0, 0, 0, time.UTC) + SubCert825Days = time.Date(2018, time.March, 2, 0, 0, 0, 0, time.UTC) + CABV148Date = time.Date(2017, time.June, 8, 0, 0, 0, 0, time.UTC) + EtsiEn319_412_5_V2_2_1_Date = time.Date(2017, time.November, 1, 0, 0, 0, 0, time.UTC) + OnionOnlyEVDate = time.Date(2015, time.May, 1, 0, 0, 0, 0, time.UTC) + CABV201Date = time.Date(2017, time.July, 28, 0, 0, 0, 0, time.UTC) + AppleCTPolicyDate = time.Date(2018, time.October, 15, 0, 0, 0, 0, time.UTC) + MozillaPolicy22Date = time.Date(2013, time.July, 26, 0, 0, 0, 0, time.UTC) + MozillaPolicy24Date = time.Date(2017, time.February, 28, 0, 0, 0, 0, time.UTC) + MozillaPolicy27Date = time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC) + CABFBRs_1_6_9_Date = time.Date(2020, time.March, 27, 0, 0, 0, 0, time.UTC) + AppleReducedLifetimeDate = time.Date(2020, time.September, 1, 0, 0, 0, 0, time.UTC) +) + +func FindTimeType(firstDate, secondDate asn1.RawValue) (int, int) { + return firstDate.Tag, secondDate.Tag +} + +// TODO(@cpu): This function is a little bit rough around the edges (especially +// after my quick fixes for the ineffassigns) and would be a good candidate for +// clean-up/refactoring. +func GetTimes(cert *x509.Certificate) (asn1.RawValue, asn1.RawValue) { + var outSeq, firstDate, secondDate asn1.RawValue + // Unmarshal into the sequence + _, err := asn1.Unmarshal(cert.RawTBSCertificate, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + // Start unmarshalling the bytes + rest, err := asn1.Unmarshal(outSeq.Bytes, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + // This is here to account for if version is not included + if outSeq.Tag == 0 { + rest, err = asn1.Unmarshal(rest, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + } + rest, err = asn1.Unmarshal(rest, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + rest, err = asn1.Unmarshal(rest, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + _, err = asn1.Unmarshal(rest, &outSeq) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + // Finally at the validity date, load them into a different RawValue + rest, err = asn1.Unmarshal(outSeq.Bytes, &firstDate) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + _, err = asn1.Unmarshal(rest, &secondDate) + if err != nil { + return asn1.RawValue{}, asn1.RawValue{} + } + return firstDate, secondDate +} diff --git a/vendor/github.com/zmap/zlint/v2/zlint.go b/vendor/github.com/zmap/zlint/v2/zlint.go new file mode 100644 index 0000000000..142c10c01e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v2/zlint.go @@ -0,0 +1,62 @@ +/* + * ZLint Copyright 2020 Regents of the University of Michigan + * + * Licensed 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. + */ + +// Used to check parsed info from certificate for compliance + +package zlint + +import ( + "time" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v2/lint" + _ "github.com/zmap/zlint/v2/lints/apple" + _ "github.com/zmap/zlint/v2/lints/cabf_br" + _ "github.com/zmap/zlint/v2/lints/cabf_ev" + _ "github.com/zmap/zlint/v2/lints/community" + _ "github.com/zmap/zlint/v2/lints/etsi" + _ "github.com/zmap/zlint/v2/lints/mozilla" + _ "github.com/zmap/zlint/v2/lints/rfc" +) + +const Version int64 = 3 + +// LintCertificate runs all registered lints on c using default options, +// producing a ResultSet. +// +// Using LintCertificate(c) is equivalent to calling LintCertificateEx(c, nil). +func LintCertificate(c *x509.Certificate) *ResultSet { + // Run all lints from the global registry + return LintCertificateEx(c, nil) +} + +// LintCertificateEx runs lints from the provided registry on c producing +// a ResultSet. Providing an explicit registry allows the caller to filter the +// lints that will be run. (See lint.Registry.Filter()) +// +// If registry is nil then the global registry of all lints is used and this +// function is equivalent to calling LintCertificate(c). +func LintCertificateEx(c *x509.Certificate, registry lint.Registry) *ResultSet { + if c == nil { + return nil + } + if registry == nil { + registry = lint.GlobalRegistry() + } + res := new(ResultSet) + res.execute(c, registry) + res.Version = Version + res.Timestamp = time.Now().Unix() + return res +} diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go new file mode 100644 index 0000000000..a7828345fc --- /dev/null +++ b/vendor/golang.org/x/crypto/ed25519/ed25519.go @@ -0,0 +1,71 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ed25519 implements the Ed25519 signature algorithm. See +// https://ed25519.cr.yp.to/. +// +// These functions are also compatible with the “Ed25519” function defined in +// RFC 8032. However, unlike RFC 8032's formulation, this package's private key +// representation includes a public key suffix to make multiple signing +// operations with the same key more efficient. This package refers to the RFC +// 8032 private key as the “seed”. +// +// Beginning with Go 1.13, the functionality of this package was moved to the +// standard library as crypto/ed25519. This package only acts as a compatibility +// wrapper. +package ed25519 + +import ( + "crypto/ed25519" + "io" +) + +const ( + // PublicKeySize is the size, in bytes, of public keys as used in this package. + PublicKeySize = 32 + // PrivateKeySize is the size, in bytes, of private keys as used in this package. + PrivateKeySize = 64 + // SignatureSize is the size, in bytes, of signatures generated and verified by this package. + SignatureSize = 64 + // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. + SeedSize = 32 +) + +// PublicKey is the type of Ed25519 public keys. +// +// This type is an alias for crypto/ed25519's PublicKey type. +// See the crypto/ed25519 package for the methods on this type. +type PublicKey = ed25519.PublicKey + +// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. +// +// This type is an alias for crypto/ed25519's PrivateKey type. +// See the crypto/ed25519 package for the methods on this type. +type PrivateKey = ed25519.PrivateKey + +// GenerateKey generates a public/private key pair using entropy from rand. +// If rand is nil, crypto/rand.Reader will be used. +func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { + return ed25519.GenerateKey(rand) +} + +// NewKeyFromSeed calculates a private key from a seed. It will panic if +// len(seed) is not SeedSize. This function is provided for interoperability +// with RFC 8032. RFC 8032's private keys correspond to seeds in this +// package. +func NewKeyFromSeed(seed []byte) PrivateKey { + return ed25519.NewKeyFromSeed(seed) +} + +// Sign signs the message with privateKey and returns a signature. It will +// panic if len(privateKey) is not PrivateKeySize. +func Sign(privateKey PrivateKey, message []byte) []byte { + return ed25519.Sign(privateKey, message) +} + +// Verify reports whether sig is a valid signature of message by publicKey. It +// will panic if len(publicKey) is not PublicKeySize. +func Verify(publicKey PublicKey, message, sig []byte) bool { + return ed25519.Verify(publicKey, message, sig) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 33788275e0..d8e5f08bda 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -19,8 +19,8 @@ github.com/bugsnag/panicwrap # github.com/cespare/xxhash/v2 v2.1.2 ## explicit; go 1.11 github.com/cespare/xxhash/v2 -# github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 -## explicit +# github.com/cloudflare/cfssl v1.5.0 +## explicit; go 1.14 github.com/cloudflare/cfssl/auth github.com/cloudflare/cfssl/certdb github.com/cloudflare/cfssl/config @@ -89,9 +89,6 @@ github.com/fsnotify/fsnotify # github.com/go-sql-driver/mysql v1.5.0 ## explicit; go 1.10 github.com/go-sql-driver/mysql -# github.com/gogo/protobuf v1.3.2 -## explicit; go 1.15 -github.com/gogo/protobuf/proto # github.com/golang/protobuf v1.5.2 ## explicit; go 1.9 github.com/golang/protobuf/jsonpb @@ -101,7 +98,7 @@ github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/empty github.com/golang/protobuf/ptypes/timestamp -# github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 +# github.com/google/certificate-transparency-go v1.0.21 ## explicit github.com/google/certificate-transparency-go github.com/google/certificate-transparency-go/asn1 @@ -140,6 +137,9 @@ github.com/jinzhu/gorm github.com/jinzhu/inflection # github.com/jinzhu/now v1.1.4 ## explicit; go 1.12 +# github.com/jmoiron/sqlx v1.2.0 +## explicit +github.com/jmoiron/sqlx/types # github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 ## explicit # github.com/lib/pq v1.9.0 @@ -244,12 +244,35 @@ github.com/stretchr/testify/require # github.com/subosito/gotenv v1.4.1 ## explicit; go 1.18 github.com/subosito/gotenv +# github.com/weppos/publicsuffix-go v0.13.0 +## explicit +github.com/weppos/publicsuffix-go/publicsuffix +# github.com/zmap/zcrypto v0.0.0-20200911161511-43ff0ea04f21 +## explicit; go 1.13 +github.com/zmap/zcrypto/json +github.com/zmap/zcrypto/util +github.com/zmap/zcrypto/x509 +github.com/zmap/zcrypto/x509/ct +github.com/zmap/zcrypto/x509/pkix +# github.com/zmap/zlint/v2 v2.2.1 +## explicit; go 1.14 +github.com/zmap/zlint/v2 +github.com/zmap/zlint/v2/lint +github.com/zmap/zlint/v2/lints/apple +github.com/zmap/zlint/v2/lints/cabf_br +github.com/zmap/zlint/v2/lints/cabf_ev +github.com/zmap/zlint/v2/lints/community +github.com/zmap/zlint/v2/lints/etsi +github.com/zmap/zlint/v2/lints/mozilla +github.com/zmap/zlint/v2/lints/rfc +github.com/zmap/zlint/v2/util # golang.org/x/crypto v0.1.0 ## explicit; go 1.17 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish golang.org/x/crypto/cryptobyte golang.org/x/crypto/cryptobyte/asn1 +golang.org/x/crypto/ed25519 golang.org/x/crypto/ocsp golang.org/x/crypto/pbkdf2 golang.org/x/crypto/pkcs12