├── .github ├── dependabot.yml └── workflows │ ├── go.yml │ ├── gofmt.yml │ └── psl-update.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── cryptobyte ├── NOTICE.md ├── asn1.go ├── asn1 │ └── asn1.go ├── asn1_test.go ├── builder.go ├── cryptobyte_test.go └── string.go ├── ct ├── README.md ├── asn1 │ ├── asn1.go │ ├── asn1_test.go │ ├── common.go │ ├── marshal.go │ └── marshal_test.go ├── client │ ├── logclient.go │ ├── logclient_test.go │ └── main │ │ └── main.go ├── scanner │ └── scanner.go ├── serialization.go ├── signatures.go ├── types.go └── x509 │ ├── cert_pool.go │ ├── pem_decrypt.go │ ├── pem_decrypt_test.go │ ├── pkcs1.go │ ├── pkcs8.go │ ├── pkcs8_test.go │ ├── pkix │ ├── oid_names.go │ └── pkix.go │ ├── root.go │ ├── root_bsd.go │ ├── root_cgo_darwin.go │ ├── root_darwin.go │ ├── root_darwin_arm_gen.go │ ├── root_darwin_armx.go │ ├── root_darwin_test.go │ ├── root_js.go │ ├── root_linux.go │ ├── root_nacl.go │ ├── root_nocgo_darwin.go │ ├── root_plan9.go │ ├── root_solaris.go │ ├── root_unix.go │ ├── root_unix_test.go │ ├── root_windows.go │ ├── sec1.go │ ├── sec1_test.go │ ├── verify.go │ ├── verify_test.go │ ├── x509.go │ └── x509_test.go ├── data └── test │ └── certificates │ ├── certs.go │ ├── dst.go │ ├── fpki.go │ ├── google.go │ └── le.go ├── doc.go ├── dsa ├── dsa.go └── dsa_test.go ├── encoding └── asn1 │ ├── README.md │ ├── asn1.go │ ├── asn1_test.go │ ├── common.go │ ├── marshal.go │ └── marshal_test.go ├── go.mod ├── go.sum ├── internal ├── cfg │ └── cfg.go ├── cpu │ ├── cpu.go │ ├── cpu.s │ ├── cpu_386.go │ ├── cpu_amd64.go │ ├── cpu_arm.go │ ├── cpu_arm64.go │ ├── cpu_arm64.s │ ├── cpu_arm64_android.go │ ├── cpu_arm64_darwin.go │ ├── cpu_arm64_freebsd.go │ ├── cpu_arm64_hwcap.go │ ├── cpu_arm64_linux.go │ ├── cpu_arm64_other.go │ ├── cpu_mips.go │ ├── cpu_mips64x.go │ ├── cpu_mipsle.go │ ├── cpu_no_name.go │ ├── cpu_ppc64x.go │ ├── cpu_ppc64x_aix.go │ ├── cpu_ppc64x_linux.go │ ├── cpu_riscv64.go │ ├── cpu_s390x.go │ ├── cpu_s390x.s │ ├── cpu_s390x_test.go │ ├── cpu_test.go │ ├── cpu_wasm.go │ ├── cpu_x86.go │ ├── cpu_x86.s │ ├── cpu_x86_test.go │ └── export_test.go ├── randutil │ └── randutil.go └── testenv │ ├── testenv.go │ ├── testenv_cgo.go │ ├── testenv_notwin.go │ └── testenv_windows.go ├── json ├── dhe.go ├── dhe_test.go ├── ecdhe.go ├── ecdhe_test.go ├── names.go ├── rsa.go ├── rsa_test.go └── testdata │ ├── test1024dh.pem │ └── test4096.pem ├── setup.py ├── tls ├── alert.go ├── auth.go ├── auth_test.go ├── cipher_suites.go ├── common.go ├── common_string.go ├── conn.go ├── conn_test.go ├── example_test.go ├── generate_cert.go ├── handshake_client.go ├── handshake_client_test.go ├── handshake_client_tls13.go ├── handshake_extensions.go ├── handshake_messages.go ├── handshake_messages_test.go ├── handshake_server.go ├── handshake_server_test.go ├── handshake_server_tls13.go ├── handshake_test.go ├── handshake_unix_test.go ├── key_agreement.go ├── key_schedule.go ├── key_schedule_test.go ├── link_test.go ├── prf.go ├── prf_test.go ├── testdata │ ├── Client-TLSv10-ClientCert-ECDSA-ECDSA │ ├── Client-TLSv10-ClientCert-ECDSA-RSA │ ├── Client-TLSv10-ClientCert-Ed25519 │ ├── Client-TLSv10-ClientCert-RSA-ECDSA │ ├── Client-TLSv10-ClientCert-RSA-RSA │ ├── Client-TLSv10-ECDHE-ECDSA-AES │ ├── Client-TLSv10-ECDHE-RSA-AES │ ├── Client-TLSv10-Ed25519 │ ├── Client-TLSv10-ExportKeyingMaterial │ ├── Client-TLSv10-RSA-RC4 │ ├── Client-TLSv11-ECDHE-ECDSA-AES │ ├── Client-TLSv11-ECDHE-RSA-AES │ ├── Client-TLSv11-Ed25519 │ ├── Client-TLSv11-RSA-RC4 │ ├── Client-TLSv12-AES128-GCM-SHA256 │ ├── Client-TLSv12-AES128-SHA256 │ ├── Client-TLSv12-AES256-GCM-SHA384 │ ├── Client-TLSv12-ALPN │ ├── Client-TLSv12-ALPN-NoMatch │ ├── Client-TLSv12-ClientCert-ECDSA-ECDSA │ ├── Client-TLSv12-ClientCert-ECDSA-RSA │ ├── Client-TLSv12-ClientCert-Ed25519 │ ├── Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 │ ├── Client-TLSv12-ClientCert-RSA-ECDSA │ ├── Client-TLSv12-ClientCert-RSA-RSA │ ├── Client-TLSv12-ClientCert-RSA-RSAPKCS1v15 │ ├── Client-TLSv12-ClientCert-RSA-RSAPSS │ ├── Client-TLSv12-ECDHE-ECDSA-AES │ ├── Client-TLSv12-ECDHE-ECDSA-AES-GCM │ ├── Client-TLSv12-ECDHE-ECDSA-AES128-SHA256 │ ├── Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384 │ ├── Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305 │ ├── Client-TLSv12-ECDHE-RSA-AES │ ├── Client-TLSv12-ECDHE-RSA-AES128-SHA256 │ ├── Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305 │ ├── Client-TLSv12-Ed25519 │ ├── Client-TLSv12-ExportKeyingMaterial │ ├── Client-TLSv12-P256-ECDHE │ ├── Client-TLSv12-RSA-RC4 │ ├── Client-TLSv12-RenegotiateOnce │ ├── Client-TLSv12-RenegotiateTwice │ ├── Client-TLSv12-RenegotiateTwiceRejected │ ├── Client-TLSv12-RenegotiationRejected │ ├── Client-TLSv12-SCT │ ├── Client-TLSv12-X25519-ECDHE │ ├── Client-TLSv13-AES128-SHA256 │ ├── Client-TLSv13-AES256-SHA384 │ ├── Client-TLSv13-ALPN │ ├── Client-TLSv13-CHACHA20-SHA256 │ ├── Client-TLSv13-ClientCert-ECDSA-RSA │ ├── Client-TLSv13-ClientCert-Ed25519 │ ├── Client-TLSv13-ClientCert-RSA-ECDSA │ ├── Client-TLSv13-ClientCert-RSA-RSAPSS │ ├── Client-TLSv13-ECDSA │ ├── Client-TLSv13-Ed25519 │ ├── Client-TLSv13-ExportKeyingMaterial │ ├── Client-TLSv13-HelloRetryRequest │ ├── Client-TLSv13-KeyUpdate │ ├── Client-TLSv13-P256-ECDHE │ ├── Client-TLSv13-X25519-ECDHE │ ├── Server-TLSv10-ECDHE-ECDSA-AES │ ├── Server-TLSv10-ExportKeyingMaterial │ ├── Server-TLSv10-RSA-3DES │ ├── Server-TLSv10-RSA-AES │ ├── Server-TLSv10-RSA-RC4 │ ├── Server-TLSv11-FallbackSCSV │ ├── Server-TLSv11-RSA-RC4 │ ├── Server-TLSv12-ALPN │ ├── Server-TLSv12-ALPN-NoMatch │ ├── Server-TLSv12-CipherSuiteCertPreferenceECDSA │ ├── Server-TLSv12-CipherSuiteCertPreferenceRSA │ ├── Server-TLSv12-ClientAuthRequestedAndECDSAGiven │ ├── Server-TLSv12-ClientAuthRequestedAndEd25519Given │ ├── Server-TLSv12-ClientAuthRequestedAndGiven │ ├── Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given │ ├── Server-TLSv12-ClientAuthRequestedNotGiven │ ├── Server-TLSv12-ECDHE-ECDSA-AES │ ├── Server-TLSv12-Ed25519 │ ├── Server-TLSv12-ExportKeyingMaterial │ ├── Server-TLSv12-IssueTicket │ ├── Server-TLSv12-IssueTicketPreDisable │ ├── Server-TLSv12-P256 │ ├── Server-TLSv12-RSA-3DES │ ├── Server-TLSv12-RSA-AES │ ├── Server-TLSv12-RSA-AES-GCM │ ├── Server-TLSv12-RSA-AES256-GCM-SHA384 │ ├── Server-TLSv12-RSA-RC4 │ ├── Server-TLSv12-RSA-RSAPKCS1v15 │ ├── Server-TLSv12-RSA-RSAPSS │ ├── Server-TLSv12-Resume │ ├── Server-TLSv12-ResumeDisabled │ ├── Server-TLSv12-SNI │ ├── Server-TLSv12-SNI-GetCertificate │ ├── Server-TLSv12-SNI-GetCertificateNotFound │ ├── Server-TLSv12-X25519 │ ├── Server-TLSv13-AES128-SHA256 │ ├── Server-TLSv13-AES256-SHA384 │ ├── Server-TLSv13-ALPN │ ├── Server-TLSv13-ALPN-NoMatch │ ├── Server-TLSv13-CHACHA20-SHA256 │ ├── Server-TLSv13-ClientAuthRequestedAndECDSAGiven │ ├── Server-TLSv13-ClientAuthRequestedAndEd25519Given │ ├── Server-TLSv13-ClientAuthRequestedAndGiven │ ├── Server-TLSv13-ClientAuthRequestedNotGiven │ ├── Server-TLSv13-ECDHE-ECDSA-AES │ ├── Server-TLSv13-Ed25519 │ ├── Server-TLSv13-ExportKeyingMaterial │ ├── Server-TLSv13-HelloRetryRequest │ ├── Server-TLSv13-IssueTicket │ ├── Server-TLSv13-IssueTicketPreDisable │ ├── Server-TLSv13-P256 │ ├── Server-TLSv13-RSA-RSAPSS │ ├── Server-TLSv13-RSA-RSAPSS-TooSmall │ ├── Server-TLSv13-Resume │ ├── Server-TLSv13-Resume-HelloRetryRequest │ ├── Server-TLSv13-ResumeDisabled │ ├── Server-TLSv13-X25519 │ ├── example-cert.pem │ └── example-key.pem ├── ticket.go ├── tls.go ├── tls_handshake.go ├── tls_ka.go ├── tls_names.go ├── tls_test.go └── zcrypto_handshake_test.go ├── util └── isURL.go ├── verifier ├── builtins.go ├── doc.go ├── graph.go ├── graph_test.go ├── procedures.go ├── revocation.go ├── revocation_test.go ├── testdata │ ├── crl-set-6375 │ ├── test.crl │ └── test_onecrl.json ├── verifier.go ├── verifier_test.go ├── walk.go └── walk_test.go ├── x509 ├── README.md ├── cert_pool.go ├── cert_pool_test.go ├── certificate_type.go ├── chain.go ├── crl_parser.go ├── crl_parser_test.go ├── ct │ ├── serialization.go │ ├── serialization_test.go │ └── types.go ├── example.json ├── example_test.go ├── extended_key_usage.go ├── extended_key_usage_gen.go ├── extended_key_usage_schema.sh ├── extensions.go ├── extensions_test.go ├── fingerprint.go ├── fingerprint_test.go ├── generated_certvalidationlevel_string.go ├── json.go ├── json_test.go ├── names.go ├── parse_test.go ├── pem_decrypt.go ├── pem_decrypt_test.go ├── performance_test.go ├── pkcs1.go ├── pkcs8.go ├── pkcs8_test.go ├── pkix │ ├── json.go │ ├── json_test.go │ ├── oid.go │ ├── oid_names.go │ ├── pkix.go │ └── pkix_test.go ├── qc_statements.go ├── revocation │ ├── crl │ │ ├── crl.go │ │ ├── crl_test.go │ │ └── test_crl │ ├── google │ │ ├── google.go │ │ ├── google_test.go │ │ └── testdata │ │ │ ├── APm1SaUzZaPllaSDuZS5yng │ │ │ ├── crl-set-6375 │ │ │ └── test_crlset │ ├── microsoft │ │ ├── microsoft.go │ │ ├── microsoft_test.go │ │ └── test_disallowedcert.sst │ ├── mozilla │ │ ├── mozilla.go │ │ ├── mozilla_test.go │ │ └── testdata │ │ │ ├── records │ │ │ └── test_onecrl.json │ └── ocsp │ │ ├── ocsp.go │ │ └── ocsp_test.go ├── root.go ├── root_darwin.go ├── root_darwin_test.go ├── root_linux.go ├── root_unix.go ├── root_unix_test.go ├── sec1.go ├── sec1_test.go ├── testdata │ ├── .gitignore │ ├── ca.cnf │ ├── dadrian.io.pem │ ├── davidadrian.org.cert │ ├── dsa_pk.cert │ ├── ecdsa_pk.cert │ ├── email-in-subject.pem │ ├── etsi_qc.pem │ ├── gen_zcrypto.sh │ ├── gsa103.enterprisedemo-google.com.cert │ ├── ian.test.cert │ ├── intermediate_ca.cert │ ├── mbernhard.com.cert │ ├── name.constraint.test.cert │ ├── pad.jhalderm.com.cert │ ├── parsecert1.pem │ ├── parsecert10-tag.pem │ ├── parsecert11-ia5.pem │ ├── parsecert12-minlen.pem │ ├── parsecert2.pem │ ├── parsecert3.pem │ ├── parsecert4-time.pem │ ├── parsecert5-printable.pem │ ├── parsecert6-explicittag.pem │ ├── parsecert7-tagmatch.pem │ ├── parsecert8-rsapositive.pem │ ├── parsecert9-intminlen.pem │ ├── qwac.pem │ ├── san.test.cert │ ├── self-signed-invalid-name.pem │ ├── self-signed-invalid-sig.pem │ ├── self-signed-md5-rsa.pem │ ├── self-signed.pem │ ├── unknown_sig_alg.cert │ └── wildcard.cert ├── tor_service_descriptor.go ├── tor_service_descriptor_test.go ├── validation.go ├── verify.go ├── verify_test.go ├── x509.go ├── x509_test.go ├── x509_test_import.go └── zintermediate │ ├── .gitignore │ └── zintermediate.go └── zcrypto_schemas ├── __init__.py └── zcrypto.py /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "gomod" # See documentation for possible values 14 | directory: "/" # Location of package manifests 15 | schedule: 16 | interval: "weekly" 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: 3 | push: 4 | pull_request: 5 | schedule: 6 | # Run every 12 hours, at the 15 minute mark. E.g. 7 | # 2020-11-29 00:15:00 UTC, 2020-11-29 12:15:00 UTC, 2020-11-30 00:15:00 UTC 8 | - cron: '15 */12 * * *' 9 | jobs: 10 | 11 | build: 12 | name: Build and Unit Test 13 | runs-on: ubuntu-latest 14 | steps: 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: ^1.16 20 | 21 | - name: Check out code 22 | uses: actions/checkout@v4 23 | 24 | - name: Build 25 | run: go build -v ./... 26 | 27 | - name: Test 28 | run: go test -v ./... 29 | -------------------------------------------------------------------------------- /.github/workflows/gofmt.yml: -------------------------------------------------------------------------------- 1 | name: Gofmt 2 | on: 3 | push: 4 | pull_request: 5 | schedule: 6 | # Run every 12 hours, at the 15 minute mark. E.g. 7 | # 2020-11-29 00:15:00 UTC, 2020-11-29 12:15:00 UTC, 2020-11-30 00:15:00 UTC 8 | - cron: '15 */12 * * *' 9 | jobs: 10 | 11 | build: 12 | name: Gofmt check 13 | runs-on: ubuntu-latest 14 | steps: 15 | 16 | - name: Check out code 17 | uses: actions/checkout@v4 18 | 19 | - name: Check gofmt 20 | uses: Jerome1337/gofmt-action@v1.0.5 21 | with: 22 | gofmt-path: './' 23 | gofmt-flags: -l -s 24 | -------------------------------------------------------------------------------- /.github/workflows/psl-update.yml: -------------------------------------------------------------------------------- 1 | name: psl-update 2 | on: 3 | schedule: 4 | # Run every hour, at the 15 minute mark. E.g. 5 | # 2020-11-29 00:15:00 UTC, 2020-11-29 01:15:00 UTC, 2020-11-29 02:15:00 UTC 6 | - cron: '15 * * * *' 7 | jobs: 8 | zcrypto-psl-update: 9 | name: Check for publicsuffix-go data updates 10 | runs-on: ubuntu-latest 11 | steps: 12 | 13 | - name: Check out code 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: ^1.16 20 | 21 | - name: Set current date 22 | id: get-date 23 | run: echo "::set-output name=now::$(date +'%Y-%m-%dT%H:%M:%S %Z')" 24 | 25 | - name: Update publicsuffix-go 26 | run: go get -u github.com/weppos/publicsuffix-go@main 27 | 28 | - name: Run go mod tidy 29 | run: go mod tidy 30 | 31 | - name: Build 32 | run: go build -v ./... 33 | 34 | - name: Test 35 | run: go test -v ./... 36 | 37 | - name: Create pull-request 38 | id: cpr 39 | uses: peter-evans/create-pull-request@v7 40 | with: 41 | commit-message: "deps: update publicsuffix-go for ${{ steps.get-date.outputs.now }}" 42 | title: "deps: update weppos/publicsuffix-go for ${{ steps.get-date.outputs.now }}" 43 | body: "ZCrypto dependency update from `go get -u github.com/weppos/publicsuffix-go@master` on ${{ steps.get-date.outputs.now }}." 44 | committer: "GitHub " 45 | author: "GitHub " 46 | labels: psl-update 47 | branch: zcrypto-psl-update 48 | delete-branch: true 49 | 50 | - name: Check outputs 51 | run: | 52 | echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" 53 | echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.idea 3 | *.iml 4 | .project 5 | .pydevproject 6 | 7 | .DS_Store 8 | venv/* 9 | *.test 10 | ct/client/main/main 11 | 12 | *.pyc 13 | zcrypto_schemas.egg-info/* 14 | build/* 15 | dist/* 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | ZCrypto is an open-source project and welcomes contributions. 5 | 6 | Goals 7 | ----- 8 | 9 | The primary goal of ZCrypto is to be able to analyze existing cryptographic systems, rather than to provide cryptographic security to production systems. Please keep this in mind when requesting or developing new features. 10 | 11 | Style 12 | ----- 13 | 14 | ZCrypto attempts to follow Go best practices for coding style and documentation. Please run [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) on your code before submitting any pull requests. Run [gometalinter](https://github.com/alecthomas/gometalinter) and attend to any easy-to-fix lints. We don't expect all code to be lint free (especially if it's a part of an existing package), but new code shouldn't be full of linter warnings. Documentation is automatically generated based on comments and hosted on [godoc](https://godoc.org/github.com/zmap/zcrypto), so pay extra attention to lints about comment quality. 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ZCrypto 2 | ======= 3 | 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/zmap/zcrypto)](https://goreportcard.com/report/github.com/zmap/zcrypto) 5 | [![GoDoc](https://godoc.org/github.com/zmap/zcrypto?status.svg)](https://godoc.org/github.com/zmap/zcrypto) 6 | 7 | ZCrypto contains specialized versions of tls and x509. It is written in Golang and is primarily based on [Golang's TLS library](https://github.com/golang/go/blob/master/src/crypto/tls). 8 | 9 | 10 | ## IMPORTANT! 11 | 12 | ### ![Danger: Experimental](https://camo.githubusercontent.com/275bc882f21b154b5537b9c123a171a30de9e6aa/68747470733a2f2f7261772e6769746875622e636f6d2f63727970746f7370686572652f63727970746f7370686572652f6d61737465722f696d616765732f6578706572696d656e74616c2e706e67) 13 | 14 | ZCrypto is a research library, designed to be used for data collection and analysis, as well as experimenting and prototyping. It should _not_ be used to provide security for production systems. 15 | 16 | 17 | ### zcrypto/tls (formerly known as ZTLS) 18 | A _research_ TLS library based on Golang standard library `crypto/tls` that contains that speaks old TLS versions, export ciphers, logs handshake messages, and is highly configurable. Many scary parts are exposed as public variables. It is primarily used for data collection, and is used by [ZGrab](https://github.com/zmap/zgrab2). Uses `zcrypto/x509`. 19 | 20 | ### zcrypto/x509 21 | 22 | A fork of the Golang stdlib `crypto/x509` that adds the ability to serialize certificates to JSON, and plays nice with CT. 23 | 24 | ### zcrypto/ct 25 | 26 | A fork of the Google Certificate Transparency Golang library, designed to play nice with ZCrypto. 27 | 28 | ## Documentation 29 | 30 | Documentation uses Godoc. See https://godoc.org/github.com/zmap/zcrypto. 31 | -------------------------------------------------------------------------------- /cryptobyte/NOTICE.md: -------------------------------------------------------------------------------- 1 | Forked from golang.org/x/crypto/cryptobyte in order to support 2 | permissive asn1 parsing. -------------------------------------------------------------------------------- /cryptobyte/asn1/asn1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package asn1 contains supporting types for parsing and building ASN.1 6 | // messages with the cryptobyte package. 7 | package asn1 8 | 9 | // Tag represents an ASN.1 identifier octet, consisting of a tag number 10 | // (indicating a type) and class (such as context-specific or constructed). 11 | // 12 | // Methods in the cryptobyte package only support the low-tag-number form, i.e. 13 | // a single identifier octet with bits 7-8 encoding the class and bits 1-6 14 | // encoding the tag number. 15 | type Tag uint8 16 | 17 | const ( 18 | classConstructed = 0x20 19 | classContextSpecific = 0x80 20 | ) 21 | 22 | // Constructed returns t with the constructed class bit set. 23 | func (t Tag) Constructed() Tag { return t | classConstructed } 24 | 25 | // ContextSpecific returns t with the context-specific class bit set. 26 | func (t Tag) ContextSpecific() Tag { return t | classContextSpecific } 27 | 28 | // The following is a list of standard tag and class combinations. 29 | const ( 30 | BOOLEAN = Tag(1) 31 | INTEGER = Tag(2) 32 | BIT_STRING = Tag(3) 33 | OCTET_STRING = Tag(4) 34 | NULL = Tag(5) 35 | OBJECT_IDENTIFIER = Tag(6) 36 | ENUM = Tag(10) 37 | UTF8String = Tag(12) 38 | SEQUENCE = Tag(16 | classConstructed) 39 | SET = Tag(17 | classConstructed) 40 | PrintableString = Tag(19) 41 | T61String = Tag(20) 42 | IA5String = Tag(22) 43 | UTCTime = Tag(23) 44 | GeneralizedTime = Tag(24) 45 | GeneralString = Tag(27) 46 | ) 47 | -------------------------------------------------------------------------------- /ct/README.md: -------------------------------------------------------------------------------- 1 | This is the really early beginnings of a certificate transparency log 2 | client written in Go, along with a log scanner tool. 3 | 4 | You'll need go v1.1 or higher to compile. 5 | 6 | # Installation 7 | 8 | This go code must be imported into your go workspace before you can 9 | use it, which can be done with: 10 | 11 | go get github.com/google/certificate-transparency/go/client 12 | go get github.com/google/certificate-transparency/go/scanner 13 | etc. 14 | 15 | # Building the binaries 16 | 17 | To compile the log scanner run: 18 | 19 | go build github.com/google/certificate-transparency/go/scanner/main/scanner.go 20 | 21 | # Contributing 22 | 23 | When sending pull requests, please ensure that everything's been run 24 | through ```gofmt``` beforehand so we can keep everything nice and 25 | tidy. 26 | -------------------------------------------------------------------------------- /ct/client/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "log" 7 | 8 | "encoding/json" 9 | ct "github.com/zmap/zcrypto/ct" 10 | "github.com/zmap/zcrypto/ct/client" 11 | "github.com/zmap/zcrypto/x509" 12 | ) 13 | 14 | // Processes the given entry in the specified log. 15 | func processEntry(entry ct.LogEntry) (*x509.Certificate, error) { 16 | cert := &x509.Certificate{} 17 | switch entry.Leaf.TimestampedEntry.EntryType { 18 | case ct.X509LogEntryType: 19 | innerCert, err := x509.ParseCertificate(entry.Leaf.TimestampedEntry.X509Entry) 20 | if err != nil { 21 | return nil, err 22 | } 23 | cert = innerCert 24 | case ct.PrecertLogEntryType: 25 | innerCert, err := x509.ParseCertificate(entry.Leaf.TimestampedEntry.PrecertEntry.TBSCertificate) 26 | if err != nil { 27 | return nil, err 28 | } 29 | cert = innerCert 30 | } 31 | return cert, nil 32 | } 33 | 34 | func main() { 35 | var logURI = flag.String("log_uri", "http://ct.googleapis.com/aviator", "CT log base URI") 36 | var indexToParse = flag.Int64("index", 1, "Index to parse") 37 | flag.Parse() 38 | logClient := client.New(*logURI) 39 | entries, err := logClient.GetEntries(*indexToParse, *indexToParse) 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | for _, entry := range entries { 44 | cert, err := processEntry(entry) 45 | if err != nil { 46 | fmt.Printf("%d %s\n", entry.Index, err.Error()) 47 | continue 48 | } 49 | finalJSON, _ := json.Marshal(cert) 50 | fmt.Printf("%d %s\n", entry.Index, string(finalJSON)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ct/x509/cert_pool.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/pem" 9 | ) 10 | 11 | // CertPool is a set of certificates. 12 | type CertPool struct { 13 | bySubjectKeyId map[string][]int 14 | byName map[string][]int 15 | certs []*Certificate 16 | } 17 | 18 | // NewCertPool returns a new, empty CertPool. 19 | func NewCertPool() *CertPool { 20 | return &CertPool{ 21 | make(map[string][]int), 22 | make(map[string][]int), 23 | nil, 24 | } 25 | } 26 | 27 | // findVerifiedParents attempts to find certificates in s which have signed the 28 | // given certificate. If any candidates were rejected then errCert will be set 29 | // to one of them, arbitrarily, and err will contain the reason that it was 30 | // rejected. 31 | func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCert *Certificate, err error) { 32 | if s == nil { 33 | return 34 | } 35 | var candidates []int 36 | 37 | if len(cert.AuthorityKeyId) > 0 { 38 | candidates = s.bySubjectKeyId[string(cert.AuthorityKeyId)] 39 | } 40 | if len(candidates) == 0 { 41 | candidates = s.byName[string(cert.RawIssuer)] 42 | } 43 | 44 | for _, c := range candidates { 45 | if err = cert.CheckSignatureFrom(s.certs[c]); err == nil { 46 | parents = append(parents, c) 47 | } else { 48 | errCert = s.certs[c] 49 | } 50 | } 51 | 52 | return 53 | } 54 | 55 | // AddCert adds a certificate to a pool. 56 | func (s *CertPool) AddCert(cert *Certificate) { 57 | if cert == nil { 58 | panic("adding nil Certificate to CertPool") 59 | } 60 | 61 | // Check that the certificate isn't being added twice. 62 | for _, c := range s.certs { 63 | if c.Equal(cert) { 64 | return 65 | } 66 | } 67 | 68 | n := len(s.certs) 69 | s.certs = append(s.certs, cert) 70 | 71 | if len(cert.SubjectKeyId) > 0 { 72 | keyId := string(cert.SubjectKeyId) 73 | s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n) 74 | } 75 | name := string(cert.RawSubject) 76 | s.byName[name] = append(s.byName[name], n) 77 | } 78 | 79 | // AppendCertsFromPEM attempts to parse a series of PEM encoded certificates. 80 | // It appends any certificates found to s and returns true if any certificates 81 | // were successfully parsed. 82 | // 83 | // On many Linux systems, /etc/ssl/cert.pem will contain the system wide set 84 | // of root CAs in a format suitable for this function. 85 | func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) { 86 | for len(pemCerts) > 0 { 87 | var block *pem.Block 88 | block, pemCerts = pem.Decode(pemCerts) 89 | if block == nil { 90 | break 91 | } 92 | if block.Type != "CERTIFICATE" || len(block.Headers) != 0 { 93 | continue 94 | } 95 | 96 | cert, err := ParseCertificate(block.Bytes) 97 | if err != nil { 98 | continue 99 | } 100 | 101 | s.AddCert(cert) 102 | ok = true 103 | } 104 | 105 | return 106 | } 107 | 108 | // Subjects returns a list of the DER-encoded subjects of 109 | // all of the certificates in the pool. 110 | func (s *CertPool) Subjects() (res [][]byte) { 111 | res = make([][]byte, len(s.certs)) 112 | for i, c := range s.certs { 113 | res[i] = c.RawSubject 114 | } 115 | return 116 | } 117 | -------------------------------------------------------------------------------- /ct/x509/pkcs1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "crypto/rsa" 9 | // START CT CHANGES 10 | "github.com/zmap/zcrypto/ct/asn1" 11 | // END CT CHANGES 12 | "errors" 13 | "math/big" 14 | ) 15 | 16 | // pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key. 17 | type pkcs1PrivateKey struct { 18 | Version int 19 | N *big.Int 20 | E int 21 | D *big.Int 22 | P *big.Int 23 | Q *big.Int 24 | // We ignore these values, if present, because rsa will calculate them. 25 | Dp *big.Int `asn1:"optional"` 26 | Dq *big.Int `asn1:"optional"` 27 | Qinv *big.Int `asn1:"optional"` 28 | 29 | AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"` 30 | } 31 | 32 | type pkcs1AdditionalRSAPrime struct { 33 | Prime *big.Int 34 | 35 | // We ignore these values because rsa will calculate them. 36 | Exp *big.Int 37 | Coeff *big.Int 38 | } 39 | 40 | // ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form. 41 | func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error) { 42 | var priv pkcs1PrivateKey 43 | rest, err := asn1.Unmarshal(der, &priv) 44 | if len(rest) > 0 { 45 | err = asn1.SyntaxError{Msg: "trailing data"} 46 | return 47 | } 48 | if err != nil { 49 | return 50 | } 51 | 52 | if priv.Version > 1 { 53 | return nil, errors.New("x509: unsupported private key version") 54 | } 55 | 56 | if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 { 57 | return nil, errors.New("x509: private key contains zero or negative value") 58 | } 59 | 60 | key = new(rsa.PrivateKey) 61 | key.PublicKey = rsa.PublicKey{ 62 | E: priv.E, 63 | N: priv.N, 64 | } 65 | 66 | key.D = priv.D 67 | key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes)) 68 | key.Primes[0] = priv.P 69 | key.Primes[1] = priv.Q 70 | for i, a := range priv.AdditionalPrimes { 71 | if a.Prime.Sign() <= 0 { 72 | return nil, errors.New("x509: private key contains zero or negative prime") 73 | } 74 | key.Primes[i+2] = a.Prime 75 | // We ignore the other two values because rsa will calculate 76 | // them as needed. 77 | } 78 | 79 | err = key.Validate() 80 | if err != nil { 81 | return nil, err 82 | } 83 | key.Precompute() 84 | 85 | return 86 | } 87 | 88 | // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form. 89 | func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { 90 | key.Precompute() 91 | 92 | version := 0 93 | if len(key.Primes) > 2 { 94 | version = 1 95 | } 96 | 97 | priv := pkcs1PrivateKey{ 98 | Version: version, 99 | N: key.N, 100 | E: key.PublicKey.E, 101 | D: key.D, 102 | P: key.Primes[0], 103 | Q: key.Primes[1], 104 | Dp: key.Precomputed.Dp, 105 | Dq: key.Precomputed.Dq, 106 | Qinv: key.Precomputed.Qinv, 107 | } 108 | 109 | priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues)) 110 | for i, values := range key.Precomputed.CRTValues { 111 | priv.AdditionalPrimes[i].Prime = key.Primes[2+i] 112 | priv.AdditionalPrimes[i].Exp = values.Exp 113 | priv.AdditionalPrimes[i].Coeff = values.Coeff 114 | } 115 | 116 | b, _ := asn1.Marshal(priv) 117 | return b 118 | } 119 | 120 | // rsaPublicKey reflects the ASN.1 structure of a PKCS#1 public key. 121 | type rsaPublicKey struct { 122 | N *big.Int 123 | E int 124 | } 125 | -------------------------------------------------------------------------------- /ct/x509/pkcs8.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | // START CT CHANGES 9 | "github.com/zmap/zcrypto/ct/asn1" 10 | "github.com/zmap/zcrypto/ct/x509/pkix" 11 | // END CT CHANGES 12 | "errors" 13 | "fmt" 14 | ) 15 | 16 | // pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See 17 | // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn 18 | // and RFC5208. 19 | type pkcs8 struct { 20 | Version int 21 | Algo pkix.AlgorithmIdentifier 22 | PrivateKey []byte 23 | // optional attributes omitted. 24 | } 25 | 26 | // ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key. See 27 | // http://www.rsa.com/rsalabs/node.asp?id=2130 and RFC5208. 28 | func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) { 29 | var privKey pkcs8 30 | if _, err := asn1.Unmarshal(der, &privKey); err != nil { 31 | return nil, err 32 | } 33 | switch { 34 | case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA): 35 | key, err = ParsePKCS1PrivateKey(privKey.PrivateKey) 36 | if err != nil { 37 | return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error()) 38 | } 39 | return key, nil 40 | 41 | case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): 42 | bytes := privKey.Algo.Parameters.FullBytes 43 | namedCurveOID := new(asn1.ObjectIdentifier) 44 | if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { 45 | namedCurveOID = nil 46 | } 47 | key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey) 48 | if err != nil { 49 | return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error()) 50 | } 51 | return key, nil 52 | 53 | default: 54 | return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ct/x509/pkcs8_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | var pkcs8RSAPrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031` 13 | 14 | // Generated using: 15 | // 16 | // openssl ecparam -genkey -name secp521r1 | openssl pkcs8 -topk8 -nocrypt 17 | var pkcs8ECPrivateKeyHex = `3081ed020100301006072a8648ce3d020106052b810400230481d53081d20201010441850d81618c5da1aec74c2eed608ba816038506975e6427237c2def150c96a3b13efbfa1f89f1be15cdf4d0ac26422e680e65a0ddd4ad3541ad76165fbf54d6e34ba18189038186000400da97bcedba1eb6d30aeb93c9f9a1454598fa47278df27d6f60ea73eb672d8dc528a9b67885b5b5dcef93c9824f7449ab512ee6a27e76142f56b94b474cfd697e810046c8ca70419365245c1d7d44d0db82c334073835d002232714548abbae6e5700f5ef315ee08b929d8581383dcf2d1c98c2f8a9fccbf79c9579f7b2fd8a90115ac2` 18 | 19 | func TestPKCS8(t *testing.T) { 20 | derBytes, _ := hex.DecodeString(pkcs8RSAPrivateKeyHex) 21 | if _, err := ParsePKCS8PrivateKey(derBytes); err != nil { 22 | t.Errorf("failed to decode PKCS8 with RSA private key: %s", err) 23 | } 24 | 25 | derBytes, _ = hex.DecodeString(pkcs8ECPrivateKeyHex) 26 | if _, err := ParsePKCS8PrivateKey(derBytes); err != nil { 27 | t.Errorf("failed to decode PKCS8 with EC private key: %s", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ct/x509/root.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import "sync" 8 | 9 | var ( 10 | once sync.Once 11 | systemRoots *CertPool 12 | systemRootsErr error 13 | ) 14 | 15 | func systemRootsPool() *CertPool { 16 | once.Do(initSystemRoots) 17 | return systemRoots 18 | } 19 | 20 | func initSystemRoots() { 21 | systemRoots, systemRootsErr = loadSystemRoots() 22 | } 23 | -------------------------------------------------------------------------------- /ct/x509/root_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build dragonfly || freebsd || netbsd || openbsd 6 | // +build dragonfly freebsd netbsd openbsd 7 | 8 | package x509 9 | 10 | // Possible certificate files; stop after finding one. 11 | var certFiles = []string{ 12 | "/usr/local/etc/ssl/cert.pem", // FreeBSD 13 | "/etc/ssl/cert.pem", // OpenBSD 14 | "/usr/local/share/certs/ca-root-nss.crt", // DragonFly 15 | "/etc/openssl/certs/ca-certificates.crt", // NetBSD 16 | } 17 | -------------------------------------------------------------------------------- /ct/x509/root_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "runtime" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func TestSystemRoots(t *testing.T) { 14 | switch runtime.GOARCH { 15 | case "arm", "arm64": 16 | t.Skipf("skipping on %s/%s, no system root", runtime.GOOS, runtime.GOARCH) 17 | } 18 | 19 | switch runtime.GOOS { 20 | case "darwin": 21 | t.Skipf("skipping on %s/%s until cgo part of golang.org/issue/16532 has been implemented.", runtime.GOOS, runtime.GOARCH) 22 | } 23 | 24 | t0 := time.Now() 25 | sysRoots := systemRootsPool() // actual system roots 26 | sysRootsDuration := time.Since(t0) 27 | 28 | t1 := time.Now() 29 | execRoots, err := execSecurityRoots() // non-cgo roots 30 | execSysRootsDuration := time.Since(t1) 31 | 32 | if err != nil { 33 | t.Fatalf("failed to read system roots: %v", err) 34 | } 35 | 36 | t.Logf(" cgo sys roots: %v", sysRootsDuration) 37 | t.Logf("non-cgo sys roots: %v", execSysRootsDuration) 38 | 39 | for _, tt := range []*CertPool{sysRoots, execRoots} { 40 | if tt == nil { 41 | t.Fatal("no system roots") 42 | } 43 | // On Mavericks, there are 212 bundled certs, at least 44 | // there was at one point in time on one machine. 45 | // (Maybe it was a corp laptop with extra certs?) 46 | // Other OS X users report 47 | // 135, 142, 145... Let's try requiring at least 100, 48 | // since this is just a sanity check. 49 | t.Logf("got %d roots", len(tt.certs)) 50 | if want, have := 100, len(tt.certs); have < want { 51 | t.Fatalf("want at least %d system roots, have %d", want, have) 52 | } 53 | } 54 | 55 | // Check that the two cert pools are roughly the same; 56 | // |A∩B| > max(|A|, |B|) / 2 should be a reasonably robust check. 57 | 58 | isect := make(map[string]bool, len(sysRoots.certs)) 59 | for _, c := range sysRoots.certs { 60 | isect[string(c.Raw)] = true 61 | } 62 | 63 | have := 0 64 | for _, c := range execRoots.certs { 65 | if isect[string(c.Raw)] { 66 | have++ 67 | } 68 | } 69 | 70 | var want int 71 | if nsys, nexec := len(sysRoots.certs), len(execRoots.certs); nsys > nexec { 72 | want = nsys / 2 73 | } else { 74 | want = nexec / 2 75 | } 76 | 77 | if have < want { 78 | t.Errorf("insufficient overlap between cgo and non-cgo roots; want at least %d, have %d", want, have) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ct/x509/root_js.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build js && wasm 6 | // +build js,wasm 7 | 8 | package x509 9 | 10 | // Possible certificate files; stop after finding one. 11 | var certFiles = []string{} 12 | 13 | func loadSystemRoots() (*CertPool, error) { 14 | return NewCertPool(), nil 15 | } 16 | 17 | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 18 | return nil, nil 19 | } 20 | -------------------------------------------------------------------------------- /ct/x509/root_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | // Possible certificate files; stop after finding one. 8 | var certFiles = []string{ 9 | "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. 10 | "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 11 | "/etc/ssl/ca-bundle.pem", // OpenSUSE 12 | "/etc/pki/tls/cacert.pem", // OpenELEC 13 | "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 14 | } 15 | -------------------------------------------------------------------------------- /ct/x509/root_nacl.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | // Possible certificate files; stop after finding one. 8 | var certFiles = []string{} 9 | -------------------------------------------------------------------------------- /ct/x509/root_nocgo_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Use non-cgo on Darwin to prevent duplicate symbols on cgo 6 | 7 | //go:build !arm && !arm64 && !ios 8 | // +build !arm,!arm64,!ios 9 | 10 | package x509 11 | 12 | func loadSystemRoots() (*CertPool, error) { 13 | return execSecurityRoots() 14 | } 15 | -------------------------------------------------------------------------------- /ct/x509/root_plan9.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build plan9 6 | // +build plan9 7 | 8 | package x509 9 | 10 | import ( 11 | "io/ioutil" 12 | "os" 13 | ) 14 | 15 | // Possible certificate files; stop after finding one. 16 | var certFiles = []string{ 17 | "/sys/lib/tls/ca.pem", 18 | } 19 | 20 | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 21 | return nil, nil 22 | } 23 | 24 | func loadSystemRoots() (*CertPool, error) { 25 | roots := NewCertPool() 26 | var bestErr error 27 | for _, file := range certFiles { 28 | data, err := ioutil.ReadFile(file) 29 | if err == nil { 30 | roots.AppendCertsFromPEM(data) 31 | return roots, nil 32 | } 33 | if bestErr == nil || (os.IsNotExist(bestErr) && !os.IsNotExist(err)) { 34 | bestErr = err 35 | } 36 | } 37 | return nil, bestErr 38 | } 39 | -------------------------------------------------------------------------------- /ct/x509/root_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | // Possible certificate files; stop after finding one. 8 | var certFiles = []string{ 9 | "/etc/certs/ca-certificates.crt", // Solaris 11.2+ 10 | "/etc/ssl/certs/ca-certificates.crt", // Joyent SmartOS 11 | "/etc/ssl/cacert.pem", // OmniOS 12 | } 13 | -------------------------------------------------------------------------------- /ct/x509/root_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build dragonfly || freebsd || linux || nacl || netbsd || openbsd || solaris 6 | // +build dragonfly freebsd linux nacl netbsd openbsd solaris 7 | 8 | package x509 9 | 10 | import ( 11 | "io/ioutil" 12 | "os" 13 | ) 14 | 15 | // Possible directories with certificate files; stop after successfully 16 | // reading at least one file from a directory. 17 | var certDirectories = []string{ 18 | "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 19 | "/system/etc/security/cacerts", // Android 20 | "/usr/local/share/certs", // FreeBSD 21 | "/etc/pki/tls/certs", // Fedora/RHEL 22 | "/etc/openssl/certs", // NetBSD 23 | } 24 | 25 | const ( 26 | // certFileEnv is the environment variable which identifies where to locate 27 | // the SSL certificate file. If set this overrides the system default. 28 | certFileEnv = "SSL_CERT_FILE" 29 | 30 | // certDirEnv is the environment variable which identifies which directory 31 | // to check for SSL certificate files. If set this overrides the system default. 32 | certDirEnv = "SSL_CERT_DIR" 33 | ) 34 | 35 | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 36 | return nil, nil 37 | } 38 | 39 | func loadSystemRoots() (*CertPool, error) { 40 | roots := NewCertPool() 41 | 42 | files := certFiles 43 | if f := os.Getenv(certFileEnv); f != "" { 44 | files = []string{f} 45 | } 46 | 47 | var firstErr error 48 | for _, file := range files { 49 | data, err := ioutil.ReadFile(file) 50 | if err == nil { 51 | roots.AppendCertsFromPEM(data) 52 | break 53 | } 54 | if firstErr == nil && !os.IsNotExist(err) { 55 | firstErr = err 56 | } 57 | } 58 | 59 | dirs := certDirectories 60 | if d := os.Getenv(certDirEnv); d != "" { 61 | dirs = []string{d} 62 | } 63 | 64 | for _, directory := range dirs { 65 | fis, err := ioutil.ReadDir(directory) 66 | if err != nil { 67 | if firstErr == nil && !os.IsNotExist(err) { 68 | firstErr = err 69 | } 70 | continue 71 | } 72 | rootsAdded := false 73 | for _, fi := range fis { 74 | data, err := ioutil.ReadFile(directory + "/" + fi.Name()) 75 | if err == nil && roots.AppendCertsFromPEM(data) { 76 | rootsAdded = true 77 | } 78 | } 79 | if rootsAdded { 80 | return roots, nil 81 | } 82 | } 83 | 84 | if len(roots.certs) > 0 { 85 | return roots, nil 86 | } 87 | 88 | return nil, firstErr 89 | } 90 | -------------------------------------------------------------------------------- /ct/x509/root_unix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris 6 | // +build dragonfly freebsd linux netbsd openbsd solaris 7 | 8 | package x509 9 | 10 | //import ( 11 | // "fmt" 12 | // "os" 13 | // "testing" 14 | //) 15 | // 16 | //const ( 17 | // testDir = "testdata" 18 | // testDirCN = "test-dir" 19 | // testFile = "test-file.crt" 20 | // testFileCN = "test-file" 21 | // testMissing = "missing" 22 | //) 23 | // 24 | //func TestEnvVars(t *testing.T) { 25 | // testCases := []struct { 26 | // name string 27 | // fileEnv string 28 | // dirEnv string 29 | // files []string 30 | // dirs []string 31 | // cns []string 32 | // }{ 33 | // { 34 | // // Environment variables override the default locations preventing fall through. 35 | // name: "override-defaults", 36 | // fileEnv: testMissing, 37 | // dirEnv: testMissing, 38 | // files: []string{testFile}, 39 | // dirs: []string{testDir}, 40 | // cns: nil, 41 | // }, 42 | // { 43 | // // File environment overrides default file locations. 44 | // name: "file", 45 | // fileEnv: testFile, 46 | // dirEnv: "", 47 | // files: nil, 48 | // dirs: nil, 49 | // cns: []string{testFileCN}, 50 | // }, 51 | // { 52 | // // Directory environment overrides default directory locations. 53 | // name: "dir", 54 | // fileEnv: "", 55 | // dirEnv: testDir, 56 | // files: nil, 57 | // dirs: nil, 58 | // cns: []string{testDirCN}, 59 | // }, 60 | // { 61 | // // File & directory environment overrides both default locations. 62 | // name: "file+dir", 63 | // fileEnv: testFile, 64 | // dirEnv: testDir, 65 | // files: nil, 66 | // dirs: nil, 67 | // cns: []string{testFileCN, testDirCN}, 68 | // }, 69 | // { 70 | // // Environment variable empty / unset uses default locations. 71 | // name: "empty-fall-through", 72 | // fileEnv: "", 73 | // dirEnv: "", 74 | // files: []string{testFile}, 75 | // dirs: []string{testDir}, 76 | // cns: []string{testFileCN, testDirCN}, 77 | // }, 78 | // } 79 | // 80 | // // Save old settings so we can restore before the test ends. 81 | // origCertFiles, origCertDirectories := certFiles, certDirectories 82 | // origFile, origDir := os.Getenv(certFileEnv), os.Getenv(certDirEnv) 83 | // defer func() { 84 | // certFiles = origCertFiles 85 | // certDirectories = origCertDirectories 86 | // os.Setenv(certFileEnv, origFile) 87 | // os.Setenv(certDirEnv, origDir) 88 | // }() 89 | // 90 | // for _, tc := range testCases { 91 | // t.Run(tc.name, func(t *testing.T) { 92 | // if err := os.Setenv(certFileEnv, tc.fileEnv); err != nil { 93 | // t.Fatalf("setenv %q failed: %v", certFileEnv, err) 94 | // } 95 | // if err := os.Setenv(certDirEnv, tc.dirEnv); err != nil { 96 | // t.Fatalf("setenv %q failed: %v", certDirEnv, err) 97 | // } 98 | // 99 | // certFiles, certDirectories = tc.files, tc.dirs 100 | // 101 | // r, err := loadSystemRoots() 102 | // if err != nil { 103 | // t.Fatal("unexpected failure:", err) 104 | // } 105 | // 106 | // if r == nil { 107 | // if tc.cns == nil { 108 | // // Expected nil 109 | // return 110 | // } 111 | // t.Fatal("nil roots") 112 | // } 113 | // 114 | // // Verify that the returned certs match, otherwise report where the mismatch is. 115 | // for i, cn := range tc.cns { 116 | // if i >= len(r.certs) { 117 | // t.Errorf("missing cert %v @ %v", cn, i) 118 | // } else if r.certs[i].Subject.CommonName != cn { 119 | // fmt.Printf("%#v\n", r.certs[0].Subject) 120 | // t.Errorf("unexpected cert common name %q, want %q", r.certs[i].Subject.CommonName, cn) 121 | // } 122 | // } 123 | // if len(r.certs) > len(tc.cns) { 124 | // t.Errorf("got %v certs, which is more than %v wanted", len(r.certs), len(tc.cns)) 125 | // } 126 | // }) 127 | // } 128 | //} 129 | -------------------------------------------------------------------------------- /ct/x509/sec1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "crypto/ecdsa" 9 | "crypto/elliptic" 10 | 11 | // START CT CHANGES 12 | "github.com/zmap/zcrypto/ct/asn1" 13 | // START CT CHANGES 14 | "errors" 15 | "fmt" 16 | "math/big" 17 | ) 18 | 19 | const ecPrivKeyVersion = 1 20 | 21 | // ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. 22 | // References: 23 | // 24 | // RFC5915 25 | // SEC1 - http://www.secg.org/download/aid-780/sec1-v2.pdf 26 | // 27 | // Per RFC5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in 28 | // most cases it is not. 29 | type ecPrivateKey struct { 30 | Version int 31 | PrivateKey []byte 32 | NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 33 | PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 34 | } 35 | 36 | // ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 37 | func ParseECPrivateKey(der []byte) (key *ecdsa.PrivateKey, err error) { 38 | return parseECPrivateKey(nil, der) 39 | } 40 | 41 | // MarshalECPrivateKey marshals an EC private key into ASN.1, DER format. 42 | func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) { 43 | oid, ok := oidFromNamedCurve(key.Curve) 44 | if !ok { 45 | return nil, errors.New("x509: unknown elliptic curve") 46 | } 47 | return asn1.Marshal(ecPrivateKey{ 48 | Version: 1, 49 | PrivateKey: key.D.Bytes(), 50 | NamedCurveOID: oid, 51 | PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)}, 52 | }) 53 | } 54 | 55 | // parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure. 56 | // The OID for the named curve may be provided from another source (such as 57 | // the PKCS8 container) - if it is provided then use this instead of the OID 58 | // that may exist in the EC private key structure. 59 | func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) { 60 | var privKey ecPrivateKey 61 | if _, err := asn1.Unmarshal(der, &privKey); err != nil { 62 | return nil, errors.New("x509: failed to parse EC private key: " + err.Error()) 63 | } 64 | if privKey.Version != ecPrivKeyVersion { 65 | return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version) 66 | } 67 | 68 | var curve elliptic.Curve 69 | if namedCurveOID != nil { 70 | curve = namedCurveFromOID(*namedCurveOID) 71 | } else { 72 | curve = namedCurveFromOID(privKey.NamedCurveOID) 73 | } 74 | if curve == nil { 75 | return nil, errors.New("x509: unknown elliptic curve") 76 | } 77 | 78 | k := new(big.Int).SetBytes(privKey.PrivateKey) 79 | if k.Cmp(curve.Params().N) >= 0 { 80 | return nil, errors.New("x509: invalid elliptic curve private key value") 81 | } 82 | priv := new(ecdsa.PrivateKey) 83 | priv.Curve = curve 84 | priv.D = k 85 | priv.X, priv.Y = curve.ScalarBaseMult(privKey.PrivateKey) 86 | 87 | return priv, nil 88 | } 89 | -------------------------------------------------------------------------------- /ct/x509/sec1_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | // Generated using: 14 | // 15 | // openssl ecparam -genkey -name secp384r1 -outform PEM 16 | var ecPrivateKeyHex = `3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50` 17 | 18 | func TestParseECPrivateKey(t *testing.T) { 19 | derBytes, _ := hex.DecodeString(ecPrivateKeyHex) 20 | key, err := ParseECPrivateKey(derBytes) 21 | if err != nil { 22 | t.Errorf("failed to decode EC private key: %s", err) 23 | } 24 | serialized, err := MarshalECPrivateKey(key) 25 | if err != nil { 26 | t.Fatalf("failed to encode EC private key: %s", err) 27 | } 28 | if !bytes.Equal(serialized, derBytes) { 29 | t.Fatalf("serialized key differs: got %x, want %x", serialized, derBytes) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZCrypto Copyright 2019 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | // ZCrypto is a research and data collection cryptography library, designed to 16 | // be used for measuring and analyzing cryptographic deployments on the 17 | // Internet. It is largely centered around the WebPKI. 18 | // 19 | // ZCrypto contains forks of the Golang X.509 and TLS libraries that speak old 20 | // TLS versions, deprecated ciphers. ZCrypto provides more lenient and open 21 | // access to X.509 certificates and TLS handshake state than its standard 22 | // library counterparts. 23 | // 24 | // ZCrypto also contains a custom X.509 chain builder, designed for bulk chain 25 | // building across large sets of certificates. 26 | package zcrypto 27 | -------------------------------------------------------------------------------- /encoding/asn1/README.md: -------------------------------------------------------------------------------- 1 | Forked from standard "encoding/asn1" to allow more permissive decoding -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/zmap/zcrypto 2 | 3 | require ( 4 | github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d 5 | github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 6 | github.com/sirupsen/logrus v1.9.3 7 | github.com/stretchr/testify v1.10.0 8 | github.com/weppos/publicsuffix-go v0.40.3-0.20250408071509-6074bbe7fd39 9 | github.com/zmap/zcertificate v0.0.1 10 | golang.org/x/crypto v0.37.0 11 | golang.org/x/net v0.39.0 12 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 13 | ) 14 | 15 | require ( 16 | github.com/davecgh/go-spew v1.1.1 // indirect 17 | github.com/kr/pretty v0.1.0 // indirect 18 | github.com/kr/text v0.1.0 // indirect 19 | github.com/pmezard/go-difflib v1.0.0 // indirect 20 | golang.org/x/sys v0.32.0 // indirect 21 | golang.org/x/text v0.24.0 // indirect 22 | gopkg.in/yaml.v3 v3.0.1 // indirect 23 | ) 24 | 25 | go 1.23.0 26 | 27 | toolchain go1.23.7 28 | -------------------------------------------------------------------------------- /internal/cfg/cfg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package cfg holds configuration shared by the Go command and internal/testenv. 6 | // Definitions that don't need to be exposed outside of cmd/go should be in 7 | // cmd/go/internal/cfg instead of this package. 8 | package cfg 9 | 10 | // KnownEnv is a list of environment variables that affect the operation 11 | // of the Go command. 12 | const KnownEnv = ` 13 | AR 14 | CC 15 | CGO_CFLAGS 16 | CGO_CFLAGS_ALLOW 17 | CGO_CFLAGS_DISALLOW 18 | CGO_CPPFLAGS 19 | CGO_CPPFLAGS_ALLOW 20 | CGO_CPPFLAGS_DISALLOW 21 | CGO_CXXFLAGS 22 | CGO_CXXFLAGS_ALLOW 23 | CGO_CXXFLAGS_DISALLOW 24 | CGO_ENABLED 25 | CGO_FFLAGS 26 | CGO_FFLAGS_ALLOW 27 | CGO_FFLAGS_DISALLOW 28 | CGO_LDFLAGS 29 | CGO_LDFLAGS_ALLOW 30 | CGO_LDFLAGS_DISALLOW 31 | CXX 32 | FC 33 | GCCGO 34 | GO111MODULE 35 | GO386 36 | GOARCH 37 | GOARM 38 | GOBIN 39 | GOCACHE 40 | GOENV 41 | GOEXE 42 | GOFLAGS 43 | GOGCCFLAGS 44 | GOHOSTARCH 45 | GOHOSTOS 46 | GOINSECURE 47 | GOMIPS 48 | GOMIPS64 49 | GOMODCACHE 50 | GONOPROXY 51 | GONOSUMDB 52 | GOOS 53 | GOPATH 54 | GOPPC64 55 | GOPRIVATE 56 | GOPROXY 57 | GOROOT 58 | GOSUMDB 59 | GOTMPDIR 60 | GOTOOLDIR 61 | GOVCS 62 | GOWASM 63 | GO_EXTLINK_ENABLED 64 | PKG_CONFIG 65 | ` 66 | -------------------------------------------------------------------------------- /internal/cpu/cpu.s: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This assembly file exists to allow internal/cpu to call 6 | // non-exported runtime functions that use "go:linkname". -------------------------------------------------------------------------------- /internal/cpu/cpu_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const GOARCH = "386" 8 | -------------------------------------------------------------------------------- /internal/cpu/cpu_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const GOARCH = "amd64" 8 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 32 8 | 9 | // arm doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. 10 | // These are initialized by archauxv() and should not be changed after they are 11 | // initialized. 12 | var HWCap uint 13 | var HWCap2 uint 14 | 15 | // HWCAP/HWCAP2 bits. These are exposed by Linux and FreeBSD. 16 | const ( 17 | hwcap_VFPv4 = 1 << 16 18 | hwcap_IDIVA = 1 << 17 19 | ) 20 | 21 | func doinit() { 22 | options = []option{ 23 | {Name: "vfpv4", Feature: &ARM.HasVFPv4}, 24 | {Name: "idiva", Feature: &ARM.HasIDIVA}, 25 | } 26 | 27 | // HWCAP feature bits 28 | ARM.HasVFPv4 = isSet(HWCap, hwcap_VFPv4) 29 | ARM.HasIDIVA = isSet(HWCap, hwcap_IDIVA) 30 | } 31 | 32 | func isSet(hwc uint, value uint) bool { 33 | return hwc&value != 0 34 | } 35 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 64 8 | 9 | func doinit() { 10 | options = []option{ 11 | {Name: "aes", Feature: &ARM64.HasAES}, 12 | {Name: "pmull", Feature: &ARM64.HasPMULL}, 13 | {Name: "sha1", Feature: &ARM64.HasSHA1}, 14 | {Name: "sha2", Feature: &ARM64.HasSHA2}, 15 | {Name: "crc32", Feature: &ARM64.HasCRC32}, 16 | {Name: "atomics", Feature: &ARM64.HasATOMICS}, 17 | {Name: "cpuid", Feature: &ARM64.HasCPUID}, 18 | {Name: "isNeoverseN1", Feature: &ARM64.IsNeoverseN1}, 19 | {Name: "isZeus", Feature: &ARM64.IsZeus}, 20 | } 21 | 22 | // arm64 uses different ways to detect CPU features at runtime depending on the operating system. 23 | osInit() 24 | } 25 | 26 | func getisar0() uint64 27 | 28 | func getMIDR() uint64 29 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | #include "textflag.h" 6 | 7 | // func getisar0() uint64 8 | TEXT ·getisar0(SB),NOSPLIT,$0 9 | // get Instruction Set Attributes 0 into R0 10 | MRS ID_AA64ISAR0_EL1, R0 11 | MOVD R0, ret+0(FP) 12 | RET 13 | 14 | // func getMIDR() uint64 15 | TEXT ·getMIDR(SB), NOSPLIT, $0-8 16 | MRS MIDR_EL1, R0 17 | MOVD R0, ret+0(FP) 18 | RET 19 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_android.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 6 | // +build arm64 7 | 8 | package cpu 9 | 10 | func osInit() { 11 | hwcapInit("android") 12 | } 13 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 && darwin && !ios 6 | // +build arm64,darwin,!ios 7 | 8 | package cpu 9 | 10 | func osInit() { 11 | ARM64.HasATOMICS = sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00")) 12 | ARM64.HasCRC32 = sysctlEnabled([]byte("hw.optional.armv8_crc32\x00")) 13 | 14 | // There are no hw.optional sysctl values for the below features on Mac OS 11.0 15 | // to detect their supported state dynamically. Assume the CPU features that 16 | // Apple Silicon M1 supports to be available as a minimal set of features 17 | // to all Go programs running on darwin/arm64. 18 | ARM64.HasAES = true 19 | ARM64.HasPMULL = true 20 | ARM64.HasSHA1 = true 21 | ARM64.HasSHA2 = true 22 | } 23 | 24 | //go:noescape 25 | func getsysctlbyname(name []byte) (int32, int32) 26 | 27 | func sysctlEnabled(name []byte) bool { 28 | ret, value := getsysctlbyname(name) 29 | if ret < 0 { 30 | return false 31 | } 32 | return value > 0 33 | } 34 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_freebsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 6 | // +build arm64 7 | 8 | package cpu 9 | 10 | func osInit() { 11 | // Retrieve info from system register ID_AA64ISAR0_EL1. 12 | isar0 := getisar0() 13 | 14 | // ID_AA64ISAR0_EL1 15 | switch extractBits(isar0, 4, 7) { 16 | case 1: 17 | ARM64.HasAES = true 18 | case 2: 19 | ARM64.HasAES = true 20 | ARM64.HasPMULL = true 21 | } 22 | 23 | switch extractBits(isar0, 8, 11) { 24 | case 1: 25 | ARM64.HasSHA1 = true 26 | } 27 | 28 | switch extractBits(isar0, 12, 15) { 29 | case 1, 2: 30 | ARM64.HasSHA2 = true 31 | } 32 | 33 | switch extractBits(isar0, 16, 19) { 34 | case 1: 35 | ARM64.HasCRC32 = true 36 | } 37 | 38 | switch extractBits(isar0, 20, 23) { 39 | case 2: 40 | ARM64.HasATOMICS = true 41 | } 42 | } 43 | 44 | func extractBits(data uint64, start, end uint) uint { 45 | return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) 46 | } 47 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_hwcap.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 && linux 6 | // +build arm64,linux 7 | 8 | package cpu 9 | 10 | // HWCap may be initialized by archauxv and 11 | // should not be changed after it was initialized. 12 | var HWCap uint 13 | 14 | // HWCAP bits. These are exposed by Linux. 15 | const ( 16 | hwcap_AES = 1 << 3 17 | hwcap_PMULL = 1 << 4 18 | hwcap_SHA1 = 1 << 5 19 | hwcap_SHA2 = 1 << 6 20 | hwcap_CRC32 = 1 << 7 21 | hwcap_ATOMICS = 1 << 8 22 | hwcap_CPUID = 1 << 11 23 | ) 24 | 25 | func hwcapInit(os string) { 26 | // HWCap was populated by the runtime from the auxiliary vector. 27 | // Use HWCap information since reading aarch64 system registers 28 | // is not supported in user space on older linux kernels. 29 | ARM64.HasAES = isSet(HWCap, hwcap_AES) 30 | ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) 31 | ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) 32 | ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) 33 | ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) 34 | ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) 35 | 36 | // The Samsung S9+ kernel reports support for atomics, but not all cores 37 | // actually support them, resulting in SIGILL. See issue #28431. 38 | // TODO(elias.naur): Only disable the optimization on bad chipsets on android. 39 | ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android" 40 | 41 | // Check to see if executing on a NeoverseN1 and in order to do that, 42 | // check the AUXV for the CPUID bit. The getMIDR function executes an 43 | // instruction which would normally be an illegal instruction, but it's 44 | // trapped by the kernel, the value sanitized and then returned. Without 45 | // the CPUID bit the kernel will not trap the instruction and the process 46 | // will be terminated with SIGILL. 47 | if ARM64.HasCPUID { 48 | midr := getMIDR() 49 | part_num := uint16((midr >> 4) & 0xfff) 50 | implementor := byte((midr >> 24) & 0xff) 51 | 52 | if implementor == 'A' && part_num == 0xd0c { 53 | ARM64.IsNeoverseN1 = true 54 | } 55 | if implementor == 'A' && part_num == 0xd40 { 56 | ARM64.IsZeus = true 57 | } 58 | } 59 | } 60 | 61 | func isSet(hwc uint, value uint) bool { 62 | return hwc&value != 0 63 | } 64 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 && linux && !android 6 | // +build arm64,linux,!android 7 | 8 | package cpu 9 | 10 | func osInit() { 11 | hwcapInit("linux") 12 | } 13 | -------------------------------------------------------------------------------- /internal/cpu/cpu_arm64_other.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build arm64 && !linux && !freebsd && !android && (!darwin || ios) 6 | // +build arm64 7 | // +build !linux 8 | // +build !freebsd 9 | // +build !android 10 | // +build !darwin ios 11 | 12 | package cpu 13 | 14 | func osInit() { 15 | // Other operating systems do not support reading HWCap from auxiliary vector, 16 | // reading privileged aarch64 system registers or sysctl in user space to detect 17 | // CPU features at runtime. 18 | } 19 | -------------------------------------------------------------------------------- /internal/cpu/cpu_mips.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 32 8 | 9 | func doinit() { 10 | } 11 | -------------------------------------------------------------------------------- /internal/cpu/cpu_mips64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build mips64 || mips64le 6 | // +build mips64 mips64le 7 | 8 | package cpu 9 | 10 | const CacheLinePadSize = 32 11 | 12 | // This is initialized by archauxv and should not be changed after it is 13 | // initialized. 14 | var HWCap uint 15 | 16 | // HWCAP bits. These are exposed by the Linux kernel 5.4. 17 | const ( 18 | // CPU features 19 | hwcap_MIPS_MSA = 1 << 1 20 | ) 21 | 22 | func doinit() { 23 | options = []option{ 24 | {Name: "msa", Feature: &MIPS64X.HasMSA}, 25 | } 26 | 27 | // HWCAP feature bits 28 | MIPS64X.HasMSA = isSet(HWCap, hwcap_MIPS_MSA) 29 | } 30 | 31 | func isSet(hwc uint, value uint) bool { 32 | return hwc&value != 0 33 | } 34 | -------------------------------------------------------------------------------- /internal/cpu/cpu_mipsle.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 32 8 | 9 | func doinit() { 10 | } 11 | -------------------------------------------------------------------------------- /internal/cpu/cpu_no_name.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !386 && !amd64 6 | // +build !386,!amd64 7 | 8 | package cpu 9 | 10 | // Name returns the CPU name given by the vendor 11 | // if it can be read directly from memory or by CPU instructions. 12 | // If the CPU name can not be determined an empty string is returned. 13 | // 14 | // Implementations that use the Operating System (e.g. sysctl or /sys/) 15 | // to gather CPU information for display should be placed in internal/sysinfo. 16 | func Name() string { 17 | // "A CPU has no name". 18 | return "" 19 | } 20 | -------------------------------------------------------------------------------- /internal/cpu/cpu_ppc64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build ppc64 || ppc64le 6 | // +build ppc64 ppc64le 7 | 8 | package cpu 9 | 10 | const CacheLinePadSize = 128 11 | 12 | func doinit() { 13 | options = []option{ 14 | {Name: "darn", Feature: &PPC64.HasDARN}, 15 | {Name: "scv", Feature: &PPC64.HasSCV}, 16 | {Name: "power9", Feature: &PPC64.IsPOWER9}, 17 | } 18 | 19 | osinit() 20 | } 21 | 22 | func isSet(hwc uint, value uint) bool { 23 | return hwc&value != 0 24 | } 25 | -------------------------------------------------------------------------------- /internal/cpu/cpu_ppc64x_aix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build ppc64 || ppc64le 6 | // +build ppc64 ppc64le 7 | 8 | package cpu 9 | 10 | const ( 11 | // getsystemcfg constants 12 | _SC_IMPL = 2 13 | _IMPL_POWER9 = 0x20000 14 | ) 15 | 16 | func osinit() { 17 | impl := getsystemcfg(_SC_IMPL) 18 | PPC64.IsPOWER9 = isSet(impl, _IMPL_POWER9) 19 | } 20 | 21 | // getsystemcfg is defined in runtime/os2_aix.go 22 | func getsystemcfg(label uint) uint 23 | -------------------------------------------------------------------------------- /internal/cpu/cpu_ppc64x_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build ppc64 || ppc64le 6 | // +build ppc64 ppc64le 7 | 8 | package cpu 9 | 10 | // ppc64 doesn't have a 'cpuid' equivalent, so we rely on HWCAP/HWCAP2. 11 | // These are initialized by archauxv and should not be changed after they are 12 | // initialized. 13 | var HWCap uint 14 | var HWCap2 uint 15 | 16 | // HWCAP bits. These are exposed by Linux. 17 | const ( 18 | // ISA Level 19 | hwcap2_ARCH_3_00 = 0x00800000 20 | 21 | // CPU features 22 | hwcap2_DARN = 0x00200000 23 | hwcap2_SCV = 0x00100000 24 | ) 25 | 26 | func osinit() { 27 | PPC64.IsPOWER9 = isSet(HWCap2, hwcap2_ARCH_3_00) 28 | PPC64.HasDARN = isSet(HWCap2, hwcap2_DARN) 29 | PPC64.HasSCV = isSet(HWCap2, hwcap2_SCV) 30 | } 31 | -------------------------------------------------------------------------------- /internal/cpu/cpu_riscv64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 32 8 | 9 | func doinit() { 10 | } 11 | -------------------------------------------------------------------------------- /internal/cpu/cpu_s390x.s: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | #include "textflag.h" 6 | 7 | // func stfle() facilityList 8 | TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 9 | MOVD $ret+0(FP), R1 10 | MOVD $3, R0 // last doubleword index to store 11 | XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) 12 | WORD $0xb2b01000 // store facility list extended (STFLE) 13 | RET 14 | 15 | // func kmQuery() queryResult 16 | TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 17 | MOVD $0, R0 // set function code to 0 (KM-Query) 18 | MOVD $ret+0(FP), R1 // address of 16-byte return value 19 | WORD $0xB92E0024 // cipher message (KM) 20 | RET 21 | 22 | // func kmcQuery() queryResult 23 | TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 24 | MOVD $0, R0 // set function code to 0 (KMC-Query) 25 | MOVD $ret+0(FP), R1 // address of 16-byte return value 26 | WORD $0xB92F0024 // cipher message with chaining (KMC) 27 | RET 28 | 29 | // func kmctrQuery() queryResult 30 | TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 31 | MOVD $0, R0 // set function code to 0 (KMCTR-Query) 32 | MOVD $ret+0(FP), R1 // address of 16-byte return value 33 | WORD $0xB92D4024 // cipher message with counter (KMCTR) 34 | RET 35 | 36 | // func kmaQuery() queryResult 37 | TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 38 | MOVD $0, R0 // set function code to 0 (KMA-Query) 39 | MOVD $ret+0(FP), R1 // address of 16-byte return value 40 | WORD $0xb9296024 // cipher message with authentication (KMA) 41 | RET 42 | 43 | // func kimdQuery() queryResult 44 | TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 45 | MOVD $0, R0 // set function code to 0 (KIMD-Query) 46 | MOVD $ret+0(FP), R1 // address of 16-byte return value 47 | WORD $0xB93E0024 // compute intermediate message digest (KIMD) 48 | RET 49 | 50 | // func klmdQuery() queryResult 51 | TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 52 | MOVD $0, R0 // set function code to 0 (KLMD-Query) 53 | MOVD $ret+0(FP), R1 // address of 16-byte return value 54 | WORD $0xB93F0024 // compute last message digest (KLMD) 55 | RET 56 | 57 | // func kdsaQuery() queryResult 58 | TEXT ·kdsaQuery(SB), NOSPLIT|NOFRAME, $0-16 59 | MOVD $0, R0 // set function code to 0 (KLMD-Query) 60 | MOVD $ret+0(FP), R1 // address of 16-byte return value 61 | WORD $0xB93A0008 // compute digital signature authentication 62 | RET 63 | 64 | -------------------------------------------------------------------------------- /internal/cpu/cpu_s390x_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu_test 6 | 7 | import ( 8 | "errors" 9 | . "internal/cpu" 10 | "os" 11 | "regexp" 12 | "testing" 13 | ) 14 | 15 | func getFeatureList() ([]string, error) { 16 | cpuinfo, err := os.ReadFile("/proc/cpuinfo") 17 | if err != nil { 18 | return nil, err 19 | } 20 | r := regexp.MustCompile("features\\s*:\\s*(.*)") 21 | b := r.FindSubmatch(cpuinfo) 22 | if len(b) < 2 { 23 | return nil, errors.New("no feature list in /proc/cpuinfo") 24 | } 25 | return regexp.MustCompile("\\s+").Split(string(b[1]), -1), nil 26 | } 27 | 28 | func TestS390XAgainstCPUInfo(t *testing.T) { 29 | // mapping of linux feature strings to S390X fields 30 | mapping := make(map[string]*bool) 31 | for _, option := range Options { 32 | mapping[option.Name] = option.Feature 33 | } 34 | 35 | // these must be true on the machines Go supports 36 | mandatory := make(map[string]bool) 37 | mandatory["zarch"] = false 38 | mandatory["eimm"] = false 39 | mandatory["ldisp"] = false 40 | mandatory["stfle"] = false 41 | 42 | features, err := getFeatureList() 43 | if err != nil { 44 | t.Error(err) 45 | } 46 | for _, feature := range features { 47 | if _, ok := mandatory[feature]; ok { 48 | mandatory[feature] = true 49 | } 50 | if flag, ok := mapping[feature]; ok { 51 | if !*flag { 52 | t.Errorf("feature '%v' not detected", feature) 53 | } 54 | } else { 55 | t.Logf("no entry for '%v'", feature) 56 | } 57 | } 58 | for k, v := range mandatory { 59 | if !v { 60 | t.Errorf("mandatory feature '%v' not detected", k) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /internal/cpu/cpu_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu_test 6 | 7 | import ( 8 | "os" 9 | "os/exec" 10 | "runtime" 11 | "strings" 12 | "testing" 13 | 14 | . "github.com/zmap/zcrypto/internal/cpu" 15 | "github.com/zmap/zcrypto/internal/testenv" 16 | ) 17 | 18 | func TestMinimalFeatures(t *testing.T) { 19 | // TODO: maybe do MustSupportFeatureDectection(t) ? 20 | if runtime.GOARCH == "arm64" { 21 | switch runtime.GOOS { 22 | case "linux", "android", "darwin": 23 | default: 24 | t.Skipf("%s/%s is not supported", runtime.GOOS, runtime.GOARCH) 25 | } 26 | } 27 | 28 | for _, o := range Options { 29 | if o.Required && !*o.Feature { 30 | t.Errorf("%v expected true, got false", o.Name) 31 | } 32 | } 33 | } 34 | 35 | func MustHaveDebugOptionsSupport(t *testing.T) { 36 | if !DebugOptions { 37 | t.Skipf("skipping test: cpu feature options not supported by OS") 38 | } 39 | } 40 | 41 | func MustSupportFeatureDectection(t *testing.T) { 42 | // TODO: add platforms that do not have CPU feature detection support. 43 | } 44 | 45 | func runDebugOptionsTest(t *testing.T, test string, options string) { 46 | MustHaveDebugOptionsSupport(t) 47 | 48 | testenv.MustHaveExec(t) 49 | 50 | env := "GODEBUG=" + options 51 | 52 | cmd := exec.Command(os.Args[0], "-test.run="+test) 53 | cmd.Env = append(cmd.Env, env) 54 | 55 | output, err := cmd.CombinedOutput() 56 | lines := strings.Fields(string(output)) 57 | lastline := lines[len(lines)-1] 58 | 59 | got := strings.TrimSpace(lastline) 60 | want := "PASS" 61 | if err != nil || got != want { 62 | t.Fatalf("%s with %s: want %s, got %v", test, env, want, got) 63 | } 64 | } 65 | 66 | func TestDisableAllCapabilities(t *testing.T) { 67 | MustSupportFeatureDectection(t) 68 | runDebugOptionsTest(t, "TestAllCapabilitiesDisabled", "cpu.all=off") 69 | } 70 | 71 | func TestAllCapabilitiesDisabled(t *testing.T) { 72 | MustHaveDebugOptionsSupport(t) 73 | 74 | if os.Getenv("GODEBUG") != "cpu.all=off" { 75 | t.Skipf("skipping test: GODEBUG=cpu.all=off not set") 76 | } 77 | 78 | for _, o := range Options { 79 | want := o.Required 80 | if got := *o.Feature; got != want { 81 | t.Errorf("%v: expected %v, got %v", o.Name, want, got) 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /internal/cpu/cpu_wasm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const CacheLinePadSize = 64 8 | 9 | func doinit() { 10 | } 11 | -------------------------------------------------------------------------------- /internal/cpu/cpu_x86.s: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 6 | 7 | #include "textflag.h" 8 | 9 | // func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) 10 | TEXT ·cpuid(SB), NOSPLIT, $0-24 11 | MOVL eaxArg+0(FP), AX 12 | MOVL ecxArg+4(FP), CX 13 | CPUID 14 | MOVL AX, eax+8(FP) 15 | MOVL BX, ebx+12(FP) 16 | MOVL CX, ecx+16(FP) 17 | MOVL DX, edx+20(FP) 18 | RET 19 | 20 | // func xgetbv() (eax, edx uint32) 21 | TEXT ·xgetbv(SB),NOSPLIT,$0-8 22 | MOVL $0, CX 23 | XGETBV 24 | MOVL AX, eax+0(FP) 25 | MOVL DX, edx+4(FP) 26 | RET 27 | -------------------------------------------------------------------------------- /internal/cpu/cpu_x86_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build 386 || amd64 6 | // +build 386 amd64 7 | 8 | package cpu_test 9 | 10 | import ( 11 | "os" 12 | "runtime" 13 | "testing" 14 | 15 | . "github.com/zmap/zcrypto/internal/cpu" 16 | ) 17 | 18 | func TestX86ifAVX2hasAVX(t *testing.T) { 19 | if X86.HasAVX2 && !X86.HasAVX { 20 | t.Fatalf("HasAVX expected true when HasAVX2 is true, got false") 21 | } 22 | } 23 | 24 | func TestDisableSSE2(t *testing.T) { 25 | runDebugOptionsTest(t, "TestSSE2DebugOption", "cpu.sse2=off") 26 | } 27 | 28 | func TestSSE2DebugOption(t *testing.T) { 29 | MustHaveDebugOptionsSupport(t) 30 | 31 | if os.Getenv("GODEBUG") != "cpu.sse2=off" { 32 | t.Skipf("skipping test: GODEBUG=cpu.sse2=off not set") 33 | } 34 | 35 | want := runtime.GOARCH != "386" // SSE2 can only be disabled on 386. 36 | if got := X86.HasSSE2; got != want { 37 | t.Errorf("X86.HasSSE2 on %s expected %v, got %v", runtime.GOARCH, want, got) 38 | } 39 | } 40 | 41 | func TestDisableSSE3(t *testing.T) { 42 | runDebugOptionsTest(t, "TestSSE3DebugOption", "cpu.sse3=off") 43 | } 44 | 45 | func TestSSE3DebugOption(t *testing.T) { 46 | MustHaveDebugOptionsSupport(t) 47 | 48 | if os.Getenv("GODEBUG") != "cpu.sse3=off" { 49 | t.Skipf("skipping test: GODEBUG=cpu.sse3=off not set") 50 | } 51 | 52 | want := false 53 | if got := X86.HasSSE3; got != want { 54 | t.Errorf("X86.HasSSE3 expected %v, got %v", want, got) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /internal/cpu/export_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | var ( 8 | Options = options 9 | ) 10 | -------------------------------------------------------------------------------- /internal/randutil/randutil.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package randutil contains internal randomness utilities for various 6 | // crypto packages. 7 | package randutil 8 | 9 | import ( 10 | "io" 11 | "sync" 12 | ) 13 | 14 | var ( 15 | closedChanOnce sync.Once 16 | closedChan chan struct{} 17 | ) 18 | 19 | // MaybeReadByte reads a single byte from r with ~50% probability. This is used 20 | // to ensure that callers do not depend on non-guaranteed behaviour, e.g. 21 | // assuming that rsa.GenerateKey is deterministic w.r.t. a given random stream. 22 | // 23 | // This does not affect tests that pass a stream of fixed bytes as the random 24 | // source (e.g. a zeroReader). 25 | func MaybeReadByte(r io.Reader) { 26 | closedChanOnce.Do(func() { 27 | closedChan = make(chan struct{}) 28 | close(closedChan) 29 | }) 30 | 31 | select { 32 | case <-closedChan: 33 | return 34 | case <-closedChan: 35 | var buf [1]byte 36 | r.Read(buf[:]) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /internal/testenv/testenv_cgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build cgo 6 | // +build cgo 7 | 8 | package testenv 9 | 10 | func init() { 11 | haveCGO = true 12 | } 13 | -------------------------------------------------------------------------------- /internal/testenv/testenv_notwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !windows 6 | // +build !windows 7 | 8 | package testenv 9 | 10 | import ( 11 | "runtime" 12 | ) 13 | 14 | func hasSymlink() (ok bool, reason string) { 15 | switch runtime.GOOS { 16 | case "android", "plan9": 17 | return false, "" 18 | } 19 | 20 | return true, "" 21 | } 22 | -------------------------------------------------------------------------------- /internal/testenv/testenv_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package testenv 6 | 7 | import ( 8 | "os" 9 | "path/filepath" 10 | "sync" 11 | "syscall" 12 | ) 13 | 14 | var symlinkOnce sync.Once 15 | var winSymlinkErr error 16 | 17 | func initWinHasSymlink() { 18 | tmpdir, err := os.MkdirTemp("", "symtest") 19 | if err != nil { 20 | panic("failed to create temp directory: " + err.Error()) 21 | } 22 | defer os.RemoveAll(tmpdir) 23 | 24 | err = os.Symlink("target", filepath.Join(tmpdir, "symlink")) 25 | if err != nil { 26 | err = err.(*os.LinkError).Err 27 | switch err { 28 | case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD: 29 | winSymlinkErr = err 30 | } 31 | } 32 | } 33 | 34 | func hasSymlink() (ok bool, reason string) { 35 | symlinkOnce.Do(initWinHasSymlink) 36 | 37 | switch winSymlinkErr { 38 | case nil: 39 | return true, "" 40 | case syscall.EWINDOWS: 41 | return false, ": symlinks are not supported on your version of Windows" 42 | case syscall.ERROR_PRIVILEGE_NOT_HELD: 43 | return false, ": you don't have enough privileges to create symlinks" 44 | } 45 | 46 | return false, "" 47 | } 48 | -------------------------------------------------------------------------------- /json/dhe_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZGrab Copyright 2015 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package json 16 | 17 | import ( 18 | "encoding/json" 19 | "math/big" 20 | "testing" 21 | 22 | . "gopkg.in/check.v1" 23 | ) 24 | 25 | func TestDHE(t *testing.T) { TestingT(t) } 26 | 27 | // from testdata/test1024dh.pem 28 | var test1024Prime = []byte{0x00, 0xAE, 0x6A, 0xFA, 0xE1, 0x1D, 0x60, 0x76, 0x64, 0x56, 0x17, 0x01, 0x55, 0x14, 0xF0, 0x38, 0x71, 0xA0, 0x9E, 0xA2, 0x0C, 0x02, 0x03, 0x0E, 0x35, 0xC7, 0xD4, 0x2D, 0x32, 0x6A, 0x61, 0x24, 0x72, 0xDE, 0x64, 0x53, 0xB7, 0xEA, 0xB4, 0x89, 0x51, 0xF9, 0x2E, 0x24, 0x6D, 0x1B, 0x18, 0xC4, 0xAA, 0xB5, 0x5C, 0x0C, 0x90, 0xEC, 0xF9, 0xA0, 0x3D, 0xD8, 0x09, 0xEF, 0x85, 0x6E, 0x74, 0xC3, 0xC2, 0x13, 0x42, 0x17, 0xAA, 0x68, 0x79, 0xFD, 0x9C, 0xB5, 0xED, 0x6E, 0x3A, 0x31, 0xE7, 0x86, 0xCA, 0x08, 0xBC, 0xE6, 0xE7, 0x65, 0xCB, 0xB2, 0x08, 0xEA, 0x8C, 0x21, 0x3C, 0xE6, 0x0E, 0x66, 0xDD, 0x5E, 0x7D, 0x04, 0x57, 0xD8, 0xE4, 0xB3, 0x0B, 0xEF, 0x40, 0x71, 0x0C, 0xA1, 0xE2, 0x12, 0x75, 0x80, 0x92, 0x85, 0x22, 0x6E, 0xCF, 0x37, 0x43, 0x48, 0x27, 0x4C, 0x21, 0x22, 0xE6, 0xC7, 0xE3} 29 | var testGenerator = []byte{0x02} 30 | 31 | type DHESuite struct { 32 | prime1024 *cryptoParameter 33 | generator *cryptoParameter 34 | param1024 *DHParams 35 | } 36 | 37 | var _ = Suite(&DHESuite{}) 38 | 39 | func (s *DHESuite) SetUpTest(c *C) { 40 | s.prime1024 = new(cryptoParameter) 41 | s.prime1024.Int = new(big.Int) 42 | s.prime1024.SetBytes(test1024Prime) 43 | s.generator = new(cryptoParameter) 44 | s.generator.Int = new(big.Int) 45 | s.generator.SetBytes(testGenerator) 46 | s.param1024 = new(DHParams) 47 | s.param1024.Prime = s.prime1024.Int 48 | s.param1024.Generator = s.generator.Int 49 | } 50 | 51 | func (s *DHESuite) TestEncodeDecodeCryptoParameter(c *C) { 52 | b, err := json.Marshal(s.prime1024) 53 | c.Assert(err, IsNil) 54 | c.Assert(b, NotNil) 55 | var dec cryptoParameter 56 | err = json.Unmarshal(b, &dec) 57 | c.Assert(err, IsNil) 58 | cmp := dec.Cmp(s.prime1024.Int) 59 | c.Check(cmp, Equals, 0) 60 | } 61 | 62 | func (s *DHESuite) TestEncodeDecodeDHParams(c *C) { 63 | b, err := json.Marshal(s.param1024) 64 | c.Assert(err, IsNil) 65 | c.Assert(b, NotNil) 66 | var dec DHParams 67 | err = json.Unmarshal(b, &dec) 68 | c.Assert(err, IsNil) 69 | c.Check(dec.Prime.Cmp(s.param1024.Prime), Equals, 0) 70 | c.Check(dec.Generator.Cmp(s.param1024.Generator), Equals, 0) 71 | } 72 | -------------------------------------------------------------------------------- /json/ecdhe.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZGrab Copyright 2015 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package json 16 | 17 | import ( 18 | "crypto/elliptic" 19 | "encoding/json" 20 | "math/big" 21 | ) 22 | 23 | // TLSCurveID is the type of a TLS identifier for an elliptic curve. See 24 | // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 25 | type TLSCurveID uint16 26 | 27 | // ECDHPrivateParams are the TLS key exchange parameters for ECDH keys. 28 | type ECDHPrivateParams struct { 29 | Value []byte `json:"value,omitempty"` 30 | Length int `json:"length,omitempty"` 31 | } 32 | 33 | // ECDHParams stores elliptic-curve Diffie-Hellman paramters.At any point in 34 | // time, it is unlikely that both ServerPrivate and ClientPrivate will be non-nil. 35 | type ECDHParams struct { 36 | TLSCurveID TLSCurveID `json:"curve_id,omitempty"` 37 | Curve elliptic.Curve `json:"-"` 38 | ServerPublic *ECPoint `json:"server_public,omitempty"` 39 | ServerPrivate *ECDHPrivateParams `json:"server_private,omitempty"` 40 | ClientPublic *ECPoint `json:"client_public,omitempty"` 41 | ClientPrivate *ECDHPrivateParams `json:"client_private,omitempty"` 42 | } 43 | 44 | // ECPoint represents an elliptic curve point and serializes nicely to JSON 45 | type ECPoint struct { 46 | X *big.Int 47 | Y *big.Int 48 | } 49 | 50 | // MarshalJSON implements the json.Marshler interface 51 | func (p *ECPoint) MarshalJSON() ([]byte, error) { 52 | var y *cryptoParameter 53 | if p.Y != nil { // Not present for x25519 54 | y = &cryptoParameter{Int: p.Y} 55 | } 56 | 57 | aux := struct { 58 | X *cryptoParameter `json:"x"` 59 | Y *cryptoParameter `json:"y,omitempty"` 60 | }{ 61 | X: &cryptoParameter{Int: p.X}, 62 | Y: y, 63 | } 64 | return json.Marshal(&aux) 65 | } 66 | 67 | // UnmarshalJSON implements the json.Unmarshler interface 68 | func (p *ECPoint) UnmarshalJSON(b []byte) error { 69 | aux := struct { 70 | X *cryptoParameter `json:"x"` 71 | Y *cryptoParameter `json:"y"` 72 | }{} 73 | if err := json.Unmarshal(b, &aux); err != nil { 74 | return err 75 | } 76 | p.X = aux.X.Int 77 | p.Y = aux.Y.Int 78 | return nil 79 | } 80 | 81 | // Description returns the description field for the given ID. See 82 | // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 83 | func (c *TLSCurveID) Description() string { 84 | if desc, ok := ecIDToName[*c]; ok { 85 | return desc 86 | } 87 | return "unknown" 88 | } 89 | 90 | // MarshalJSON implements the json.Marshaler interface 91 | func (c *TLSCurveID) MarshalJSON() ([]byte, error) { 92 | aux := struct { 93 | Name string `json:"name"` 94 | ID uint16 `json:"id"` 95 | }{ 96 | Name: c.Description(), 97 | ID: uint16(*c), 98 | } 99 | return json.Marshal(&aux) 100 | } 101 | 102 | // UnmarshalJSON implements the json.Unmarshaler interface 103 | func (c *TLSCurveID) UnmarshalJSON(b []byte) error { 104 | aux := struct { 105 | ID uint16 `json:"id"` 106 | }{} 107 | if err := json.Unmarshal(b, &aux); err != nil { 108 | return err 109 | } 110 | *c = TLSCurveID(aux.ID) 111 | return nil 112 | } 113 | -------------------------------------------------------------------------------- /json/ecdhe_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZGrab Copyright 2015 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package json 16 | 17 | import ( 18 | "crypto/rand" 19 | "encoding/json" 20 | "math/big" 21 | "testing" 22 | 23 | . "gopkg.in/check.v1" 24 | ) 25 | 26 | func TestECDHE(t *testing.T) { TestingT(t) } 27 | 28 | type ECDHESuite struct{} 29 | 30 | var _ = Suite(&ECDHESuite{}) 31 | 32 | func (s *ECDHESuite) TestEncodeDecodeCurveID(c *C) { 33 | for curve := range ecIDToName { 34 | out, errEnc := json.Marshal(&curve) 35 | c.Assert(errEnc, IsNil) 36 | var back TLSCurveID 37 | errDec := json.Unmarshal(out, &back) 38 | c.Assert(errDec, IsNil) 39 | c.Check(back, Equals, curve) 40 | } 41 | } 42 | 43 | func (s *ECDHESuite) TestEncodeDecodeECPoint(c *C) { 44 | max := new(big.Int) 45 | max.Exp(big.NewInt(2), big.NewInt(255), nil) 46 | max.Sub(max, big.NewInt(19)) 47 | x, errX := rand.Int(rand.Reader, max) 48 | y, errY := rand.Int(rand.Reader, max) 49 | c.Assert(errX, IsNil) 50 | c.Assert(errY, IsNil) 51 | p := ECPoint{ 52 | X: x, 53 | Y: y, 54 | } 55 | out, errEnc := json.Marshal(&p) 56 | c.Assert(errEnc, IsNil) 57 | c.Check(len(out), Not(Equals), 0) 58 | var back ECPoint 59 | errDec := json.Unmarshal(out, &back) 60 | c.Assert(errDec, IsNil) 61 | } 62 | 63 | func (s *ECDHESuite) TestCurveIDDescription(c *C) { 64 | for curve, name := range ecIDToName { 65 | c.Check(curve.Description(), Equals, name) 66 | } 67 | unk := TLSCurveID(6500) 68 | c.Check(unk.Description(), Equals, "unknown") 69 | } 70 | 71 | func (s *ECDHESuite) TestEncodeDecodeECParam(c *C) { 72 | ecp := new(ECDHParams) 73 | out, errEnc := json.Marshal(&ecp) 74 | c.Assert(errEnc, IsNil) 75 | c.Check(len(out), Not(Equals), 0) 76 | back := new(ECDHParams) 77 | errDec := json.Unmarshal(out, back) 78 | c.Assert(errDec, IsNil) 79 | c.Check(back, DeepEquals, ecp) 80 | } 81 | -------------------------------------------------------------------------------- /json/rsa.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZGrab Copyright 2015 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package json 16 | 17 | import ( 18 | "crypto/rsa" 19 | "encoding/json" 20 | "fmt" 21 | "math/big" 22 | ) 23 | 24 | // RSAPublicKey provides JSON methods for the standard rsa.PublicKey. 25 | type RSAPublicKey struct { 26 | *rsa.PublicKey 27 | } 28 | 29 | type auxRSAPublicKey struct { 30 | Exponent int `json:"exponent"` 31 | Modulus []byte `json:"modulus"` 32 | Length int `json:"length"` 33 | } 34 | 35 | // RSAClientParams are the TLS key exchange parameters for RSA keys. 36 | type RSAClientParams struct { 37 | Length uint16 `json:"length,omitempty"` 38 | EncryptedPMS []byte `json:"encrypted_pre_master_secret,omitempty"` 39 | } 40 | 41 | // MarshalJSON implements the json.Marshal interface 42 | func (rp *RSAPublicKey) MarshalJSON() ([]byte, error) { 43 | var aux auxRSAPublicKey 44 | if rp.PublicKey != nil { 45 | aux.Exponent = rp.E 46 | aux.Modulus = rp.N.Bytes() 47 | aux.Length = len(aux.Modulus) * 8 48 | } 49 | return json.Marshal(&aux) 50 | } 51 | 52 | // UnmarshalJSON implements the json.Unmarshal interface 53 | func (rp *RSAPublicKey) UnmarshalJSON(b []byte) error { 54 | var aux auxRSAPublicKey 55 | if err := json.Unmarshal(b, &aux); err != nil { 56 | return err 57 | } 58 | if rp.PublicKey == nil { 59 | rp.PublicKey = new(rsa.PublicKey) 60 | } 61 | rp.E = aux.Exponent 62 | rp.N = big.NewInt(0).SetBytes(aux.Modulus) 63 | if len(aux.Modulus)*8 != aux.Length { 64 | return fmt.Errorf("mismatched length (got %d, field specified %d)", len(aux.Modulus), aux.Length) 65 | } 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /json/testdata/test1024dh.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN DH PARAMETERS----- 2 | MIGHAoGBAK5q+uEdYHZkVhcBVRTwOHGgnqIMAgMONcfULTJqYSRy3mRTt+q0iVH5 3 | LiRtGxjEqrVcDJDs+aA92AnvhW50w8ITQheqaHn9nLXtbjox54bKCLzm52XLsgjq 4 | jCE85g5m3V59BFfY5LML70BxDKHiEnWAkoUibs83Q0gnTCEi5sfjAgEC 5 | -----END DH PARAMETERS----- 6 | -------------------------------------------------------------------------------- /json/testdata/test4096.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIJKQIBAAKCAgEA1AzgOVeqNjGJONDeNv/fA9eYpdkhmKSUvisiW5r/lHXqfi4T 3 | WYMuNC7wOxSDj6uEUXSmD+lpIYrsjR/Pc4iqdfSNVtLqvkmy5hbBTZoteFn66TLz 4 | WaeV+0Q9iMfOCOnkrZM/REnvBgoWyflb6x90y2gzzLEqjKYYQ8ma0jZ+n0UE5u1+ 5 | Akh6jO6EFAjsPEn86Wj+5UFNbRvP5h3JyksJ47VzK/Sl7wUrKUnI5ucMuuRP6Q+q 6 | UvulAYWLAyIXz9UPUun+rokojxM0Xz7S/D4nhjfSFf42nPYYjwnEH5NXznNw+vYF 7 | jKhw4Aj0/af6CIBG1/dr9jvfpD6s0Y1dqYX+xkFXJUjfJtVM77K4GqpOnxKA/B0O 8 | RWW/d5+OHp29j6hv1iJwhz2S+IV1jPrmOVY7UU2uaUQZXqU21WBh5Isvr7JVwVnw 9 | MqbMkhkl7ZEVT0N/tw48QjHKXsrAXN64lVwI3xXjBTq8qVfxb6a7phRD3mLUkaxz 10 | ek0JvPbQt6nubgDkmhQ5ML68M2ZK0z/IEnN1YnUO2ut3um1PL0RY2Ini3+SJa8BP 11 | 8LPuRGXPpKYaDxoIw/WwIxA78sKCK3OnGDGShlk2Zfjx0CmPawU/zVYw0ggSSU0g 12 | w7WMSFwCrgwJR73l6ecMJ8cVzsc/hyIg6G2Nim5z8QSfVaL2thBCPuJwmH8CAwEA 13 | AQKCAgEAjsoY1yQ8HwAeWh7z8+862ph8VvmukN4Ktz/OhAcMoYkBnXQjXXxjSYpu 14 | BCqdKMqjcEJvbHmNbKPjBGjuRes6dfF2l4exwO9Zw2yBQGNYyRk2R4AitDWQXkGm 15 | eguppwDxFxz3VmG+zb9PdzQt/FcTS8FgWC7Y6xsRbdw9H97IRzGvyl0UJC9wLqSS 16 | VfdoNHTSFM66DeB6ZcV7qoZWkp0TDL3rzyaP8jL1zHi+CxZ80QDa+qKs2/JOO4cU 17 | g8iaZj4fcoLVF+yOXkHdW2Gvq2GjNdMy6dJkLi/de7xkz6plT0UXSDcQp5XpZEND 18 | zecmDEFs8xLOJWJOB4iY0QczkesEEny0MyXs2YgALDrFkttqR4V05TB/0UPt9vmX 19 | Nm8pCZGfozWmCaPVB7HgWTbyyGa7Hokyq+2H6wtDy3quD3aPzy4A1W2BKlCDCUFG 20 | oW/k4pK40JN4F2MWXFpYYn8QW7m7NQhLjrNgzIJ/op/4rdX8MI1vxuYAU/Kbfs+W 21 | 0I/4WnJBbtYN6RSveN7bEt5z4A5ZhWbURLTW/tum7BhjPisJ9ir47jOeLCv1pL+l 22 | tO4iwcLy1IqFFRwSBXpRe0wxWDwTA2ZlV6iQrWKnBMKDs6Segnv51ELsvSjRZNZ9 23 | nY28ippWzCt7zkFrIKvyhHNOCARknAls1fJsFNC3VaCWNLUz16ECggEBAOqhOWq3 24 | ffSokFS5caMTx5EDWmu1FzE8cKoJDVevwdHAv3riiItp8zmtbzNjjnVE2Qt0GEP1 25 | woQD4E/JDFmoFaZX7ggEko7Lfsabv+x6ITyL0N5a0JlyOpFt61khpHGR3BN7SsaP 26 | 80KbUMoLF/oMBdrkQfc7N/yGLY+4K3tYAtqj/tn+HXw64+vKOitHkkNx2lETPvWF 27 | v+0R7wIBbWOpJJZJJJAsOFMw/+iCDaHURkCtK8Zp/EVlq0z886sOSxorYLrgJ+1i 28 | Dacjxpe2X3i2OeL95LsFQ8qwDWRLcs0KoGeg10G0+00jfMyuZMWCmuFuidSfT+t3 29 | /KamPMy7IhNBDg8CggEBAOddLJCLZ1hxt7ch+Pn5Vpr1yzIsyZh4xwwVkWniJ120 30 | aimq7CDDJ1ScRcNnRIw22MLE29yQIUbk8TvFJS33YwU+tkLjBg7pgfqR0duhue+R 31 | J4Jq/W5KBnv+Uc4/Mp3RXjzGvdGW8amrsGdFi/sx2bGAFcIRRXtwJdxGxi/BCRHk 32 | UbK2GyDPap/4gpwvzp7QSzYotUxo10ekG8INaEU7Cp25FjshTW54nY4SJQYefWL/ 33 | lViSqXIDQZelunrg24n/nAqulwUjVFeqWQZIo0ukogba54oRPkDxTR6OVy5kWPMx 34 | mKI4Qx8u6/yaGaHoTx9rhQkWRS5rb/PcjtIHM2PQPpECggEAVtMqqC8W0T6/ilrF 35 | jo93PlZ7U3hECNhQ6NtIsLY9hx1IvnSuCsk+VI21pNKmmQbNOsvPXvbG8Ituqpe/ 36 | lj35JQFM+HKYuXbchyqDr0LSodErjd0VbHM08TQ371ffvpc3VY4+cZQ7dN582weX 37 | 69QfJo1pS9ACO9R7b7+7d31uMPKXEJxU1PAF/+9p7zIhEgxDudTha4H/L/9+7sMQ 38 | c9zXyTVv7louzbpIOQZHfSdMiAqNNHNsA1JIPcktcpNrf1emCAGDRPkQDFXU27eF 39 | ROpKKZHC3uJn382eZwr0hKP2D+MZRRtwE2+aczPl3qEiJ2H8Z049COnx+Mlznl9x 40 | kKZ2SQKCAQAm6D9PS3IkqHL5pAfnmaubwYvbMzbvohfvC0153eM62dUkjq7Iz6i0 41 | jNcahio73hlTn6FNlRtTfbqnj36yHTEUt7gUxXLGXTRTe+QrqCXJiMJ5Jx7ZRi+S 42 | +HCvW2darNPJKq7PKTAYlVvD8ikZJAf01pJSIW9q07A6O9imPTMWRCwM/pzPRrIq 43 | lrL4Kv33LRYI1I2wfMz/KjTUzEZlpgkh/vcjGHWaB0SPmLOLNONnG4306C0AlFWa 44 | d+9FLL0eltKZ5URWQ9uyJl50NRDo7pWky3k2ebHbX/jVE6DLl2px8zw0w3teKhjb 45 | UNrQpG1x3jXwEkOuC7k27DdEUJuuxF1RAoIBAQDDObyAVl7JQvCvEKjsayPfHmyQ 46 | /Jav29/SrIEWH3DZu4/aXa5bwaSe4thWlMHp1aidpia18D2y9gABimPNBKZADTMs 47 | GSyXwm5kO4oCAH1MuV6LaFjTNH6P5y8v1Ul17cphIgcWjaKoz4DTQzYaD6I6EZxE 48 | tADHJlMYezlr64shcmjyP/He+x7J1cwF3j+c2ffXmn4EzcU9NDvgYs0YMRsRuoD/ 49 | uEK1DukCPPb3CRS4flgdIsTWvjQeLXbgYlB+v94L9OKJm4MEpApBXIy6+26JxeBf 50 | KOc8qq/4qn1Xi9WiJif6chcn2Vglj585f/ugAO3ZshsGNXeFoqa0awl64ZJY 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup, find_packages 3 | 4 | here = os.path.abspath(os.path.dirname(__file__)) 5 | 6 | setup( 7 | name="zcrypto_schemas", 8 | version="0.0.1", 9 | description="ZSchema definitions for zcrypto's JSON output.", 10 | classifiers=[ 11 | "Programming Language :: Python", 12 | "Natural Language :: English" 13 | ], 14 | author="ZMap Team", 15 | author_email="team@zmap.io", 16 | url="https://github.com/zmap/zcrypto", 17 | keywords="zmap censys zcrypto internet-wide scanning", 18 | packages=find_packages(), 19 | zip_safe=False 20 | ) 21 | -------------------------------------------------------------------------------- /tls/common_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=SignatureScheme,ClientAuthType -output=common_string.go"; DO NOT EDIT. 2 | 3 | package tls 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[PKCS1WithSHA256-1025] 12 | _ = x[PKCS1WithSHA384-1281] 13 | _ = x[PKCS1WithSHA512-1537] 14 | _ = x[PSSWithSHA256-2052] 15 | _ = x[PSSWithSHA384-2053] 16 | _ = x[PSSWithSHA512-2054] 17 | _ = x[ECDSAWithP256AndSHA256-1027] 18 | _ = x[ECDSAWithP384AndSHA384-1283] 19 | _ = x[ECDSAWithP521AndSHA512-1539] 20 | _ = x[Ed25519-2055] 21 | _ = x[EdDSAWithEd25519-2055] 22 | _ = x[EdDSAWithEd448-2056] 23 | _ = x[PKCS1WithSHA1-513] 24 | _ = x[ECDSAWithSHA1-515] 25 | } 26 | 27 | const ( 28 | _SignatureScheme_name_0 = "PKCS1WithSHA1" 29 | _SignatureScheme_name_1 = "ECDSAWithSHA1" 30 | _SignatureScheme_name_2 = "PKCS1WithSHA256" 31 | _SignatureScheme_name_3 = "ECDSAWithP256AndSHA256" 32 | _SignatureScheme_name_4 = "PKCS1WithSHA384" 33 | _SignatureScheme_name_5 = "ECDSAWithP384AndSHA384" 34 | _SignatureScheme_name_6 = "PKCS1WithSHA512" 35 | _SignatureScheme_name_7 = "ECDSAWithP521AndSHA512" 36 | _SignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519EdDSAWithEd448" 37 | ) 38 | 39 | var ( 40 | _SignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46, 60} 41 | ) 42 | 43 | func (i SignatureScheme) String() string { 44 | switch { 45 | case i == 513: 46 | return _SignatureScheme_name_0 47 | case i == 515: 48 | return _SignatureScheme_name_1 49 | case i == 1025: 50 | return _SignatureScheme_name_2 51 | case i == 1027: 52 | return _SignatureScheme_name_3 53 | case i == 1281: 54 | return _SignatureScheme_name_4 55 | case i == 1283: 56 | return _SignatureScheme_name_5 57 | case i == 1537: 58 | return _SignatureScheme_name_6 59 | case i == 1539: 60 | return _SignatureScheme_name_7 61 | case 2052 <= i && i <= 2056: 62 | i -= 2052 63 | return _SignatureScheme_name_8[_SignatureScheme_index_8[i]:_SignatureScheme_index_8[i+1]] 64 | default: 65 | return "SignatureScheme(" + strconv.FormatInt(int64(i), 10) + ")" 66 | } 67 | } 68 | func _() { 69 | // An "invalid array index" compiler error signifies that the constant values have changed. 70 | // Re-run the stringer command to generate them again. 71 | var x [1]struct{} 72 | _ = x[NoClientCert-0] 73 | _ = x[RequestClientCert-1] 74 | _ = x[RequireAnyClientCert-2] 75 | _ = x[VerifyClientCertIfGiven-3] 76 | _ = x[RequireAndVerifyClientCert-4] 77 | } 78 | 79 | const _ClientAuthType_name = "NoClientCertRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert" 80 | 81 | var _ClientAuthType_index = [...]uint8{0, 12, 29, 49, 72, 98} 82 | 83 | func (i ClientAuthType) String() string { 84 | if i < 0 || i >= ClientAuthType(len(_ClientAuthType_index)-1) { 85 | return "ClientAuthType(" + strconv.FormatInt(int64(i), 10) + ")" 86 | } 87 | return _ClientAuthType_name[_ClientAuthType_index[i]:_ClientAuthType_index[i+1]] 88 | } 89 | -------------------------------------------------------------------------------- /tls/handshake_unix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris 6 | // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris 7 | 8 | package tls 9 | 10 | import ( 11 | "errors" 12 | "syscall" 13 | ) 14 | 15 | func init() { 16 | isConnRefused = func(err error) bool { 17 | return errors.Is(err, syscall.ECONNREFUSED) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tls/link_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tls 6 | 7 | import ( 8 | "bytes" 9 | "os" 10 | "os/exec" 11 | "path/filepath" 12 | "testing" 13 | 14 | "github.com/zmap/zcrypto/internal/testenv" 15 | ) 16 | 17 | // Tests that the linker is able to remove references to the Client or Server if unused. 18 | func TestLinkerGC(t *testing.T) { 19 | if testing.Short() { 20 | t.Skip("skipping in short mode") 21 | } 22 | t.Parallel() 23 | goBin := testenv.GoToolPath(t) 24 | testenv.MustHaveGoBuild(t) 25 | 26 | tests := []struct { 27 | name string 28 | program string 29 | want []string 30 | bad []string 31 | }{ 32 | { 33 | name: "empty_import", 34 | program: `package main 35 | import _ "crypto/tls" 36 | func main() {} 37 | `, 38 | bad: []string{ 39 | "tls.(*Conn)", 40 | "type.crypto/tls.clientHandshakeState", 41 | "type.crypto/tls.serverHandshakeState", 42 | }, 43 | }, 44 | { 45 | name: "client_and_server", 46 | program: `package main 47 | import "crypto/tls" 48 | func main() { 49 | tls.Dial("", "", nil) 50 | tls.Server(nil, nil) 51 | } 52 | `, 53 | want: []string{ 54 | "crypto/tls.(*Conn).clientHandshake", 55 | "crypto/tls.(*Conn).serverHandshake", 56 | }, 57 | }, 58 | { 59 | name: "only_client", 60 | program: `package main 61 | import "crypto/tls" 62 | func main() { tls.Dial("", "", nil) } 63 | `, 64 | want: []string{ 65 | "crypto/tls.(*Conn).clientHandshake", 66 | }, 67 | bad: []string{ 68 | "crypto/tls.(*Conn).serverHandshake", 69 | }, 70 | }, 71 | // TODO: add only_server like func main() { tls.Server(nil, nil) } 72 | // That currently brings in the client via Conn.handleRenegotiation. 73 | 74 | } 75 | tmpDir := t.TempDir() 76 | goFile := filepath.Join(tmpDir, "x.go") 77 | exeFile := filepath.Join(tmpDir, "x.exe") 78 | for _, tt := range tests { 79 | t.Run(tt.name, func(t *testing.T) { 80 | if err := os.WriteFile(goFile, []byte(tt.program), 0644); err != nil { 81 | t.Fatal(err) 82 | } 83 | os.Remove(exeFile) 84 | cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go") 85 | cmd.Dir = tmpDir 86 | if out, err := cmd.CombinedOutput(); err != nil { 87 | t.Fatalf("compile: %v, %s", err, out) 88 | } 89 | 90 | cmd = exec.Command(goBin, "tool", "nm", "x.exe") 91 | cmd.Dir = tmpDir 92 | nm, err := cmd.CombinedOutput() 93 | if err != nil { 94 | t.Fatalf("nm: %v, %s", err, nm) 95 | } 96 | for _, sym := range tt.want { 97 | if !bytes.Contains(nm, []byte(sym)) { 98 | t.Errorf("expected symbol %q not found", sym) 99 | } 100 | } 101 | for _, sym := range tt.bad { 102 | if bytes.Contains(nm, []byte(sym)) { 103 | t.Errorf("unexpected symbol %q found", sym) 104 | } 105 | } 106 | }) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tls/testdata/Client-TLSv10-Ed25519: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/tls/testdata/Client-TLSv10-Ed25519 -------------------------------------------------------------------------------- /tls/testdata/Client-TLSv11-Ed25519: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/tls/testdata/Client-TLSv11-Ed25519 -------------------------------------------------------------------------------- /tls/testdata/Server-TLSv11-FallbackSCSV: -------------------------------------------------------------------------------- 1 | >>> Flow 1 (client to server) 2 | 00000000 16 03 01 00 77 01 00 00 73 03 02 0a 6b c9 55 9d |....w...s...k.U.| 3 | 00000010 bf 4e 61 b2 0a c7 c6 96 9f eb 90 91 87 ca d3 d3 |.Na.............| 4 | 00000020 62 dc b6 b4 db ea 41 fe 43 3e a3 00 00 14 c0 0a |b.....A.C>......| 5 | 00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..| 6 | 00000040 56 00 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 |V....6.........1| 7 | 00000050 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........| 8 | 00000060 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................| 9 | 00000070 00 23 00 00 00 16 00 00 00 17 00 00 |.#..........| 10 | >>> Flow 2 (server to client) 11 | 00000000 15 03 02 00 02 02 56 |......V| 12 | -------------------------------------------------------------------------------- /tls/testdata/Server-TLSv12-Resume: -------------------------------------------------------------------------------- 1 | >>> Flow 1 (client to server) 2 | 00000000 16 03 01 01 12 01 00 01 0e 03 03 90 27 78 df 71 |............'x.q| 3 | 00000010 d3 0e ce 1d de ec d2 1b 70 e0 89 da 98 a9 45 3e |........p.....E>| 4 | 00000020 9c ee 93 90 8f 61 d0 a3 b4 a4 5a 20 9d cd d4 81 |.....a....Z ....| 5 | 00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...| 6 | 00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 04 00 2f |.ks.ES.....w.../| 7 | 00000050 00 ff 01 00 00 c1 00 23 00 81 50 46 ad c1 db a8 |.......#..PF....| 8 | 00000060 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 00 |8.{+....B>......| 9 | 00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q| 10 | 00000080 ed 14 ef 68 ca 42 c5 4c 75 5e a5 6f d2 49 61 e4 |...h.B.Lu^.o.Ia.| 11 | 00000090 fb 83 46 7c 4c ab f9 c6 d1 3c 9e 5b 8d d8 bc c0 |..F|L....<.[....| 12 | 000000a0 a5 2d 84 db 24 dd a0 16 60 1d 87 a0 52 88 25 6c |.-..$...`...R.%l| 13 | 000000b0 c6 8e 5b 71 0f 74 c3 48 49 38 16 92 8c de 77 bd |..[q.t.HI8....w.| 14 | 000000c0 8a 2b 45 4d 58 86 40 b1 d6 0f 99 de 27 41 b2 41 |.+EMX.@.....'A.A| 15 | 000000d0 27 aa fe 26 e9 24 91 2a 00 ff 08 00 16 00 00 00 |'..&.$.*........| 16 | 000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........| 17 | 000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................| 18 | 00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................| 19 | 00000110 02 04 02 05 02 06 02 |.......| 20 | >>> Flow 2 (server to client) 21 | 00000000 16 03 03 00 51 02 00 00 4d 03 03 00 00 00 00 00 |....Q...M.......| 22 | 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 23 | 00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 9d cd d4 81 |...DOWNGRD. ....| 24 | 00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...| 25 | 00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 2f 00 00 |.ks.ES.....w./..| 26 | 00000050 05 ff 01 00 01 00 14 03 03 00 01 01 16 03 03 00 |................| 27 | 00000060 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............| 28 | 00000070 00 57 8e 5f 0a f6 3f 3b 43 f1 33 bc ef 5e c6 8d |.W._..?;C.3..^..| 29 | 00000080 86 92 58 58 71 51 e8 54 57 96 5f bd 36 3a 9f d3 |..XXqQ.TW._.6:..| 30 | 00000090 e9 27 01 bf fb 6a 05 57 de 2d db b2 79 38 72 95 |.'...j.W.-..y8r.| 31 | 000000a0 fd |.| 32 | >>> Flow 3 (client to server) 33 | 00000000 14 03 03 00 01 01 16 03 03 00 40 6d 3c 76 31 a4 |..........@m.5v...K.| 35 | 00000020 01 f8 a8 83 0c eb 58 f7 d6 93 c6 b6 40 0e c8 24 |......X.....@..$| 36 | 00000030 46 58 0c 79 4a c6 b4 15 65 1e 9c bd ff 51 4d d0 |FX.yJ...e....QM.| 37 | 00000040 44 66 fe c0 98 d5 26 11 98 cf 52 |Df....&...R| 38 | >>> Flow 4 (server to client) 39 | 00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........| 40 | 00000010 00 00 00 00 00 4e 8e bd e5 c8 d4 1a 14 00 f1 ed |.....N..........| 41 | 00000020 c4 88 b3 5c 92 b9 ad 8a 68 d4 f3 85 1b 02 25 aa |...\....h.....%.| 42 | 00000030 a0 65 49 08 0d 2a b4 0a 64 eb ea ab 06 73 08 ca |.eI..*..d....s..| 43 | 00000040 62 c9 56 45 a9 15 03 03 00 30 00 00 00 00 00 00 |b.VE.....0......| 44 | 00000050 00 00 00 00 00 00 00 00 00 00 60 51 ae 81 79 6d |..........`Q..ym| 45 | 00000060 91 95 02 42 30 3f c4 3c 2b fc 74 47 a7 a9 17 22 |...B0?.<+.tG..."| 46 | 00000070 88 26 6d 18 b9 8f ad 43 e3 b0 |.&m....C..| 47 | -------------------------------------------------------------------------------- /tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall: -------------------------------------------------------------------------------- 1 | >>> Flow 1 (client to server) 2 | 00000000 16 03 01 00 b0 01 00 00 ac 03 03 15 df ef fb ff |................| 3 | 00000010 00 89 4d bf 59 d2 30 f1 f3 e7 20 24 c6 06 ba a4 |..M.Y.0... $....| 4 | 00000020 28 b4 ba 3d 00 f2 18 9b 98 a3 f2 20 7e d9 d0 58 |(..=....... ~..X| 5 | 00000030 50 25 90 2d f0 af 72 66 fb f8 54 33 6e d4 2b f0 |P%.-..rf..T3n.+.| 6 | 00000040 0f 1a ea dc 9e 08 34 ed 68 a8 d8 bd 00 04 13 03 |......4.h.......| 7 | 00000050 00 ff 01 00 00 5f 00 0b 00 04 03 00 01 02 00 0a |....._..........| 8 | 00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................| 9 | 00000070 00 00 00 17 00 00 00 0d 00 04 00 02 08 06 00 2b |...............+| 10 | 00000080 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.| 11 | 00000090 24 00 1d 00 20 6e 42 98 d4 04 32 d1 21 0f 64 c9 |$... nB...2.!.d.| 12 | 000000a0 b7 f2 b2 52 6f 2b b7 b1 95 4b 57 85 7b 69 d9 63 |...Ro+...KW.{i.c| 13 | 000000b0 19 48 d2 1c 1e |.H...| 14 | >>> Flow 2 (server to client) 15 | 00000000 15 03 03 00 02 02 28 |......(| 16 | -------------------------------------------------------------------------------- /tls/testdata/example-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw 3 | DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow 4 | EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d 5 | 7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B 6 | 5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr 7 | BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1 8 | NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l 9 | Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc 10 | 6MF9+Yw1Yy0t 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /tls/testdata/example-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49 3 | AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q 4 | EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /util/isURL.go: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2014 Alex Saskevich 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | */ 24 | 25 | package util 26 | 27 | import ( 28 | "net/url" 29 | "regexp" 30 | "strings" 31 | "unicode/utf8" 32 | ) 33 | 34 | const ( 35 | maxURLRuneCount = 2083 36 | minURLRuneCount = 3 37 | 38 | 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]))` 39 | URLSchema = `((ftp|tcp|udp|wss?|https?):\/\/)` 40 | URLUsername = `(\S+(:\S*)?@)` 41 | URLPath = `((\/|\?|#)[^\s]*)` 42 | URLPort = `(:(\d{1,5}))` 43 | 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]))` 44 | URLSubdomain = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))` 45 | ) 46 | 47 | var ( 48 | 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 + `?$` 49 | rxURL = regexp.MustCompile(URL) 50 | ) 51 | 52 | // IsURL check if the string is an URL. 53 | // This function is (graciously) adopted from 54 | // https://github.com/asaskevich/govalidator to avoid needing a full dependency on 55 | // `govalidator` for the one `IsURL` function. 56 | func IsURL(str string) bool { 57 | if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") { 58 | return false 59 | } 60 | strTemp := str 61 | if strings.Contains(str, ":") && !strings.Contains(str, "://") { 62 | // support no indicated urlscheme but with colon for port number 63 | // http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString 64 | strTemp = "http://" + str 65 | } 66 | u, err := url.Parse(strTemp) 67 | if err != nil { 68 | return false 69 | } 70 | if strings.HasPrefix(u.Host, ".") { 71 | return false 72 | } 73 | if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) { 74 | return false 75 | } 76 | return rxURL.MatchString(str) 77 | } 78 | -------------------------------------------------------------------------------- /verifier/builtins.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZCrypto Copyright 2017 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package verifier 16 | 17 | // NewNSS returns a new verifier mimicking NSS. 18 | func NewNSS(pki *Graph) (nss *Verifier) { 19 | nss = NewVerifier(pki, &VerifyProcedureNSS{}) 20 | return 21 | } 22 | 23 | // NewMicrosoft returns a new verifier mimicking Microsoft SChannel. 24 | func NewMicrosoft(pki *Graph) (microsoft *Verifier) { 25 | microsoft = NewVerifier(pki, &VerifyProcedureMicrosoft{}) 26 | return 27 | } 28 | 29 | // NewApple returns a new verifier mimicking Apple SecureTransport. 30 | func NewApple(pki *Graph) (apple *Verifier) { 31 | apple = NewVerifier(pki, &VerifyProcedureApple{}) 32 | return 33 | } 34 | 35 | // NewJava returns a new verifier mimicking javax.net.ssl. 36 | func NewJava(pki *Graph) (java *Verifier) { 37 | java = NewVerifier(pki, &VerifyProcedureJava{}) 38 | return 39 | } 40 | 41 | // NewGoogleCTPrimary returns a new verifier mimicking the behavior of the 42 | // primary Google CT logs (e.g. Pilot). 43 | func NewGoogleCTPrimary(pki *Graph) (gct *Verifier) { 44 | gct = NewVerifier(pki, &VerifyProcedureGoogleCTPrimary{}) 45 | return 46 | } 47 | -------------------------------------------------------------------------------- /verifier/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZCrypto Copyright 2017 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | // Package verifier performs detailed certificate validation mimicking the 16 | // behavior of popular browsers and root stores. 17 | // 18 | // It includes a Graph structure than can be used to model the PKI. It 19 | // implements a multigraph in which edges are certificates, and nodes are 20 | // (spki, subject) tuples. The head/source of the edge is the issuer, and the 21 | // tail/destination is the subject. Verifiers walk this graph to perform 22 | // certificate validation. 23 | 24 | package verifier 25 | -------------------------------------------------------------------------------- /verifier/procedures.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZCrypto Copyright 2017 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package verifier 16 | 17 | // TODO: Implement these as the VerifyProcedure interface expands. 18 | 19 | // VerifyProcedureNSS implements the VerifyProcedure interface for NSS. 20 | type VerifyProcedureNSS struct{} 21 | 22 | // VerifyProcedureMicrosoft implements the VerifyProcedure interface for 23 | // Microsoft. 24 | type VerifyProcedureMicrosoft struct{} 25 | 26 | // VerifyProcedureApple implements the VerifyProcedure interface for Apple. 27 | type VerifyProcedureApple struct{} 28 | 29 | // VerifyProcedureJava implements the VerifyProcedure interface for Java. 30 | type VerifyProcedureJava struct{} 31 | 32 | // VerifyProcedureGoogleCTPrimary implements the VerifyProcedure interface for 33 | // the primary Google CT servers. 34 | type VerifyProcedureGoogleCTPrimary struct{} 35 | -------------------------------------------------------------------------------- /verifier/testdata/crl-set-6375: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/verifier/testdata/crl-set-6375 -------------------------------------------------------------------------------- /verifier/testdata/test.crl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/verifier/testdata/test.crl -------------------------------------------------------------------------------- /verifier/walk_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * ZCrypto Copyright 2017 Regents of the University of Michigan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy 6 | * of the License at http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 11 | * implied. See the License for the specific language governing 12 | * permissions and limitations under the License. 13 | */ 14 | 15 | package verifier 16 | 17 | import "testing" 18 | 19 | func TestWalk(t *testing.T) { 20 | type empty struct{} 21 | 22 | for _, test := range verifyTests { 23 | g := NewGraph() 24 | test.parseSelf() 25 | 26 | // Add the presented chain 27 | // TODO 28 | 29 | for _, c := range test.parsedIntermediates() { 30 | g.AddCert(c) 31 | } 32 | for _, c := range test.parsedRoots() { 33 | g.AddRoot(c) 34 | } 35 | 36 | // See what chains we got 37 | actualChains := g.WalkChains(test.parsedLeaf()) 38 | if err := test.compareChains(test.unionAllExpected(), actualChains); err != nil { 39 | t.Errorf("%s: %s", test.Name, err) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /x509/README.md: -------------------------------------------------------------------------------- 1 | Originally based on the go/crypto/x509 standard library, 2 | this package has now diverged enough that it is no longer 3 | updated with direct correspondence to new go releases. 4 | 5 | Approximately supports all the features of 6 | github.com/golang/go/crypto/x509 package at: 7 | branch: release-branch.go1.10 8 | revision: dea961ebd9f871b39b3bdaab32f952037f28cd71 9 | -------------------------------------------------------------------------------- /x509/certificate_type.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import "encoding/json" 8 | 9 | // TODO: Automatically generate this file from a CSV 10 | 11 | // CertificateType represents whether a certificate is a root, intermediate, or 12 | // leaf. 13 | type CertificateType int 14 | 15 | // CertificateType constants. Values should not be considered significant aside 16 | // from CertificateTypeUnknown is the zero value. 17 | const ( 18 | CertificateTypeUnknown CertificateType = 0 19 | CertificateTypeLeaf CertificateType = 1 20 | CertificateTypeIntermediate CertificateType = 2 21 | CertificateTypeRoot CertificateType = 3 22 | ) 23 | 24 | const ( 25 | certificateTypeStringLeaf = "leaf" 26 | certificateTypeStringIntermediate = "intermediate" 27 | certificateTypeStringRoot = "root" 28 | certificateTypeStringUnknown = "unknown" 29 | ) 30 | 31 | // MarshalJSON implements the json.Marshaler interface. Any unknown integer 32 | // value is considered the same as CertificateTypeUnknown. 33 | func (t CertificateType) MarshalJSON() ([]byte, error) { 34 | switch t { 35 | case CertificateTypeLeaf: 36 | return json.Marshal(certificateTypeStringLeaf) 37 | case CertificateTypeIntermediate: 38 | return json.Marshal(certificateTypeStringIntermediate) 39 | case CertificateTypeRoot: 40 | return json.Marshal(certificateTypeStringRoot) 41 | default: 42 | return json.Marshal(certificateTypeStringUnknown) 43 | } 44 | } 45 | 46 | // UnmarshalJSON implements the json.Unmarshaler interface. Any unknown string 47 | // is considered the same CertificateTypeUnknown. 48 | func (t *CertificateType) UnmarshalJSON(b []byte) error { 49 | var certificateTypeString string 50 | if err := json.Unmarshal(b, &certificateTypeString); err != nil { 51 | return err 52 | } 53 | switch certificateTypeString { 54 | case certificateTypeStringLeaf: 55 | *t = CertificateTypeLeaf 56 | case certificateTypeStringIntermediate: 57 | *t = CertificateTypeIntermediate 58 | case certificateTypeStringRoot: 59 | *t = CertificateTypeRoot 60 | default: 61 | *t = CertificateTypeUnknown 62 | } 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /x509/chain.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "bytes" 9 | "strings" 10 | ) 11 | 12 | // CertificateChain is a slice of certificates. The 0'th element is the leaf, 13 | // and the last element is a root. Successive elements have a child-parent 14 | // relationship. 15 | type CertificateChain []*Certificate 16 | 17 | // Range runs a function on each element of chain. It can modify each 18 | // certificate in place. 19 | func (chain CertificateChain) Range(f func(int, *Certificate)) { 20 | for i, c := range chain { 21 | f(i, c) 22 | } 23 | } 24 | 25 | // SubjectAndKeyInChain returns true if the given SubjectAndKey is found in any 26 | // certificate in the chain. 27 | func (chain CertificateChain) SubjectAndKeyInChain(sk *SubjectAndKey) bool { 28 | for _, cert := range chain { 29 | if bytes.Equal(sk.RawSubject, cert.RawSubject) && bytes.Equal(sk.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) { 30 | return true 31 | } 32 | } 33 | return false 34 | } 35 | 36 | // CertificateSubjectAndKeyInChain returns true if the SubjectAndKey from c is 37 | // found in any certificate in the chain. 38 | func (chain CertificateChain) CertificateSubjectAndKeyInChain(c *Certificate) bool { 39 | for _, cert := range chain { 40 | if bytes.Equal(c.RawSubject, cert.RawSubject) && bytes.Equal(c.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) { 41 | return true 42 | } 43 | } 44 | return false 45 | } 46 | 47 | // CertificateInChain returns true if c is in the chain. 48 | func (chain CertificateChain) CertificateInChain(c *Certificate) bool { 49 | for _, cert := range chain { 50 | if bytes.Equal(c.Raw, cert.Raw) { 51 | return true 52 | } 53 | } 54 | return false 55 | } 56 | 57 | func (chain CertificateChain) AppendToFreshChain(c *Certificate) CertificateChain { 58 | n := make([]*Certificate, len(chain)+1) 59 | copy(n, chain) 60 | n[len(chain)] = c 61 | return n 62 | } 63 | 64 | func (chain CertificateChain) chainID() string { 65 | var parts []string 66 | for _, c := range chain { 67 | parts = append(parts, string(c.FingerprintSHA256)) 68 | } 69 | return strings.Join(parts, "") 70 | } 71 | -------------------------------------------------------------------------------- /x509/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "domain": null, 3 | "certificate": { 4 | "version": 3, 5 | "serial_number": 123893, 6 | "signature_algorithm": { 7 | "id": 123, 8 | "name": "SHA1" 9 | }, 10 | "issuer": { 11 | "common_name": "Starfield CA", 12 | "attributes": [ 13 | { "organization": "Startfield" }, 14 | { "location": "Scottsdale" }, 15 | { "state": "Arizona" }, 16 | { "country": "US" } 17 | ] 18 | }, 19 | "validity": { 20 | "start": "20140102", 21 | "end": "20150102", 22 | "length" :8760 23 | }, 24 | "subject": { 25 | "common_name": "*.tools.ieft.org", 26 | "attributes": [ 27 | { "organization_unit": "Domain Control Validated" } 28 | ] 29 | }, 30 | "subject_key_info": { 31 | "algorithm": { 32 | "id": 234, 33 | "name": "RSA" 34 | }, 35 | "key": { 36 | "modulus": "base64encodedmodulus", 37 | "exponent": 65537 38 | } 39 | }, 40 | "extensions": [ 41 | { 42 | "id": 345, 43 | "name": "Certificate Basic Constraints", 44 | "is_ca": false 45 | }, 46 | { 47 | "id": 456, 48 | "name": "Alt Names", 49 | "alt_names": [ 50 | "*.tools.ietf.org", 51 | "tools.ietf.org" 52 | ] 53 | } 54 | ] 55 | }, 56 | "signature_algorithm": { 57 | "id": 123, 58 | "name": "SHA1" 59 | }, 60 | "signature": { 61 | "value": "base64encodedsignature", 62 | "is_valid": true, 63 | "matches_domain": null 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /x509/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509_test 6 | 7 | import ( 8 | "encoding/pem" 9 | 10 | "github.com/zmap/zcrypto/x509" 11 | ) 12 | 13 | func Example_x509_ParseCertificate() { 14 | // Verifying with a custom list of root certificates. 15 | 16 | const rootPEM = ` 17 | -----BEGIN CERTIFICATE----- 18 | MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT 19 | MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i 20 | YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG 21 | EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy 22 | bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 23 | AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP 24 | VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv 25 | h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE 26 | ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ 27 | EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC 28 | DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7 29 | qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD 30 | VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g 31 | K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI 32 | KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n 33 | ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB 34 | BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY 35 | /iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/ 36 | zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza 37 | HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto 38 | WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6 39 | yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx 40 | -----END CERTIFICATE-----` 41 | 42 | const certPEM = ` 43 | -----BEGIN CERTIFICATE----- 44 | MIIDujCCAqKgAwIBAgIIE31FZVaPXTUwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE 45 | BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl 46 | cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMTI5MTMyNzQzWhcNMTQwNTI5MDAwMDAw 47 | WjBpMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN 48 | TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEYMBYGA1UEAwwPbWFp 49 | bC5nb29nbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfRrObuSW5T7q 50 | 5CnSEqefEmtH4CCv6+5EckuriNr1CjfVvqzwfAhopXkLrq45EQm8vkmf7W96XJhC 51 | 7ZM0dYi1/qOCAU8wggFLMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAa 52 | BgNVHREEEzARgg9tYWlsLmdvb2dsZS5jb20wCwYDVR0PBAQDAgeAMGgGCCsGAQUF 53 | BwEBBFwwWjArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcy 54 | LmNydDArBggrBgEFBQcwAYYfaHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20vb2Nz 55 | cDAdBgNVHQ4EFgQUiJxtimAuTfwb+aUtBn5UYKreKvMwDAYDVR0TAQH/BAIwADAf 56 | BgNVHSMEGDAWgBRK3QYWG7z2aLV29YG2u2IaulqBLzAXBgNVHSAEEDAOMAwGCisG 57 | AQQB1nkCBQEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUuY29t 58 | L0dJQUcyLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAH6RYHxHdcGpMpFE3oxDoFnP+ 59 | gtuBCHan2yE2GRbJ2Cw8Lw0MmuKqHlf9RSeYfd3BXeKkj1qO6TVKwCh+0HdZk283 60 | TZZyzmEOyclm3UGFYe82P/iDFt+CeQ3NpmBg+GoaVCuWAARJN/KfglbLyyYygcQq 61 | 0SgeDh8dRKUiaW3HQSoYvTvdTuqzwK4CXsr3b5/dAOY8uMuG/IAR3FgwTbZ1dtoW 62 | RvOTa8hYiU6A475WuZKyEHcwnGYe57u2I2KbMgcKjPniocj4QzgYsVAVKW3IwaOh 63 | yE+vPxsiUkvQHdO2fojCkY8jg70jxM+gu59tPDNbw3Uh/2Ij310FgTHsnGQMyA== 64 | -----END CERTIFICATE-----` 65 | 66 | // First, create the set of root certificates. For this example we only 67 | // have one. It's also possible to omit this in order to use the 68 | // default root set of the current operating system. 69 | roots := x509.NewCertPool() 70 | ok := roots.AppendCertsFromPEM([]byte(rootPEM)) 71 | if !ok { 72 | panic("failed to parse root certificate") 73 | } 74 | 75 | block, _ := pem.Decode([]byte(certPEM)) 76 | if block == nil { 77 | panic("failed to parse certificate PEM") 78 | } 79 | _, err := x509.ParseCertificate(block.Bytes) 80 | if err != nil { 81 | panic("failed to parse certificate: " + err.Error()) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /x509/extended_key_usage_schema.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # TODO: This should really be generated by Go code as a subrecord, but 5 | # importing in Python is hard. This is quick and dirty. 6 | 7 | FIELDS=$(\ 8 | cat extended_key_usage.go |\ 9 | grep json |\ 10 | cut -d ':' -f 2 |\ 11 | sed 's|,omitempty||g' |\ 12 | tr -d '`') 13 | echo "extended_key_usage = SubRecord({" 14 | for f in $FIELDS; do 15 | if [ $f == "\"unknown\"" ]; then 16 | echo " $f: ListOf(OID())" 17 | else 18 | echo " $f: Boolean()," 19 | fi 20 | done 21 | echo "})" 22 | -------------------------------------------------------------------------------- /x509/fingerprint.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "bytes" 9 | "crypto/md5" 10 | "crypto/sha1" 11 | "crypto/sha256" 12 | "crypto/sha512" 13 | "encoding/hex" 14 | "encoding/json" 15 | ) 16 | 17 | // CertificateFingerprint represents a digest/fingerprint of some data. It can 18 | // easily be encoded to hex and JSON (as a hex string). 19 | type CertificateFingerprint []byte 20 | 21 | // MD5Fingerprint creates a fingerprint of data using the MD5 hash algorithm. 22 | func MD5Fingerprint(data []byte) CertificateFingerprint { 23 | sum := md5.Sum(data) 24 | return sum[:] 25 | } 26 | 27 | // SHA1Fingerprint creates a fingerprint of data using the SHA1 hash algorithm. 28 | func SHA1Fingerprint(data []byte) CertificateFingerprint { 29 | sum := sha1.Sum(data) 30 | return sum[:] 31 | } 32 | 33 | // SHA256Fingerprint creates a fingerprint of data using the SHA256 hash 34 | // algorithm. 35 | func SHA256Fingerprint(data []byte) CertificateFingerprint { 36 | sum := sha256.Sum256(data) 37 | return sum[:] 38 | } 39 | 40 | // SHA512Fingerprint creates a fingerprint of data using the SHA256 hash 41 | // algorithm. 42 | func SHA512Fingerprint(data []byte) CertificateFingerprint { 43 | sum := sha512.Sum512(data) 44 | return sum[:] 45 | } 46 | 47 | // Equal returns true if the fingerprints are bytewise-equal. 48 | func (f CertificateFingerprint) Equal(other CertificateFingerprint) bool { 49 | return bytes.Equal(f, other) 50 | } 51 | 52 | // Hex returns the given fingerprint encoded as a hex string. 53 | func (f CertificateFingerprint) Hex() string { 54 | return hex.EncodeToString(f) 55 | } 56 | 57 | // MarshalJSON implements the json.Marshaler interface, and marshals the 58 | // fingerprint as a hex string. 59 | func (f *CertificateFingerprint) MarshalJSON() ([]byte, error) { 60 | return json.Marshal(f.Hex()) 61 | } 62 | -------------------------------------------------------------------------------- /x509/fingerprint_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/json" 9 | "testing" 10 | ) 11 | 12 | var randomData = []byte("somerandomdata") 13 | 14 | type fpJSONTestStruct struct { 15 | FP CertificateFingerprint `json:"fp"` 16 | } 17 | 18 | func TestMD5Fingerprint(t *testing.T) { 19 | fingerprint := MD5Fingerprint(randomData) 20 | 21 | if fingerprint.Hex() != "5698ed1e3d65a854fc702393fb2049b4" { 22 | t.Fatal("invalid fingerprint:", fingerprint.Hex()) 23 | } 24 | s := fpJSONTestStruct{ 25 | FP: fingerprint, 26 | } 27 | b, _ := json.Marshal(&s) 28 | if `{"fp":"5698ed1e3d65a854fc702393fb2049b4"}` != string(b) { 29 | t.Fatalf("invalid json: %s", b) 30 | } 31 | } 32 | 33 | func TestSHA1Fingerprint(t *testing.T) { 34 | fingerprint := SHA1Fingerprint(randomData) 35 | 36 | if fingerprint.Hex() != "26f30f9a9ff52d1cfbd18c4ca4d54a898b05ce0d" { 37 | t.Fatal("invalid fingerprint:", fingerprint.Hex()) 38 | } 39 | s := fpJSONTestStruct{ 40 | FP: fingerprint, 41 | } 42 | b, _ := json.Marshal(&s) 43 | if `{"fp":"26f30f9a9ff52d1cfbd18c4ca4d54a898b05ce0d"}` != string(b) { 44 | t.Fatalf("invalid json: %s", b) 45 | } 46 | } 47 | 48 | func TestSHA256Fingerprint(t *testing.T) { 49 | fingerprint := SHA256Fingerprint(randomData) 50 | 51 | if fingerprint.Hex() != "dbdffb426fe23336753b7ccc6ced25bafea6616c92e8922a3d857d95cf30d4f0" { 52 | t.Fatal("invalid fingerprint:", fingerprint.Hex()) 53 | } 54 | s := fpJSONTestStruct{ 55 | FP: fingerprint, 56 | } 57 | b, _ := json.Marshal(&s) 58 | if `{"fp":"dbdffb426fe23336753b7ccc6ced25bafea6616c92e8922a3d857d95cf30d4f0"}` != string(b) { 59 | t.Fatalf("invalid json: %s", b) 60 | } 61 | } 62 | 63 | func TestSHA512Fingerprint(t *testing.T) { 64 | fingerprint := SHA512Fingerprint(randomData) 65 | 66 | if fingerprint.Hex() != "4e8a382161e2ee2fe460cbf99a2df371a7ce3b2587a637a6c3cec91fa2920ab969b40e4c9ec12ef12405e175d0b09baf35a46c4349e658def41b6d296bad3fd2" { 67 | t.Fatal("invalid fingerprint:", fingerprint.Hex()) 68 | } 69 | s := fpJSONTestStruct{ 70 | FP: fingerprint, 71 | } 72 | b, _ := json.Marshal(&s) 73 | if `{"fp":"4e8a382161e2ee2fe460cbf99a2df371a7ce3b2587a637a6c3cec91fa2920ab969b40e4c9ec12ef12405e175d0b09baf35a46c4349e658def41b6d296bad3fd2"}` != string(b) { 74 | t.Fatalf("invalid json: %s", b) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /x509/generated_certvalidationlevel_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go"; DO NOT EDIT. 2 | 3 | package x509 4 | 5 | import "strconv" 6 | 7 | const _CertValidationLevel_name = "UnknownValidationLevelDVOVEV" 8 | 9 | var _CertValidationLevel_index = [...]uint8{0, 22, 24, 26, 28} 10 | 11 | func (i CertValidationLevel) String() string { 12 | if i < 0 || i >= CertValidationLevel(len(_CertValidationLevel_index)-1) { 13 | return "CertValidationLevel(" + strconv.FormatInt(int64(i), 10) + ")" 14 | } 15 | return _CertValidationLevel_name[_CertValidationLevel_index[i]:_CertValidationLevel_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /x509/names.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | func (p PublicKeyAlgorithm) String() string { 8 | if p >= total_key_algorithms || p < 0 { 9 | p = UnknownPublicKeyAlgorithm 10 | } 11 | return keyAlgorithmNames[p] 12 | } 13 | 14 | func (c *Certificate) SignatureAlgorithmName() string { 15 | switch c.SignatureAlgorithm { 16 | case UnknownSignatureAlgorithm: 17 | return c.SignatureAlgorithmOID.String() 18 | default: 19 | return c.SignatureAlgorithm.String() 20 | } 21 | } 22 | 23 | func (c *Certificate) PublicKeyAlgorithmName() string { 24 | switch c.PublicKeyAlgorithm { 25 | case UnknownPublicKeyAlgorithm: 26 | return c.PublicKeyAlgorithmOID.String() 27 | default: 28 | return c.PublicKeyAlgorithm.String() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /x509/parse_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/pem" 9 | "io/ioutil" 10 | "testing" 11 | ) 12 | 13 | const testdataPrefix = "testdata/" 14 | 15 | func TestDetectSelfSigned(t *testing.T) { 16 | tests := []struct { 17 | Filename string 18 | Expected bool 19 | }{ 20 | { 21 | Filename: "self-signed.pem", 22 | Expected: true, 23 | }, 24 | { 25 | Filename: "self-signed-invalid-sig.pem", 26 | Expected: false, 27 | }, 28 | { 29 | Filename: "self-signed-invalid-name.pem", 30 | Expected: false, 31 | }, 32 | { 33 | Filename: "dadrian.io.pem", 34 | Expected: false, 35 | }, 36 | { 37 | Filename: "self-signed-md5-rsa.pem", 38 | Expected: true, 39 | }, 40 | } 41 | for _, test := range tests { 42 | path := testdataPrefix + test.Filename 43 | b, err := ioutil.ReadFile(path) 44 | if err != nil { 45 | t.Fatalf("could not open %s: %s", test.Filename, err) 46 | } 47 | p, _ := pem.Decode(b) 48 | if p == nil { 49 | t.Fatalf("bad pem %s", test.Filename) 50 | } 51 | c, err := ParseCertificate(p.Bytes) 52 | if err != nil { 53 | t.Fatalf("could not parse %s: %s", test.Filename, err) 54 | } 55 | if c.SelfSigned != test.Expected { 56 | t.Errorf("expected %s to have SelfSigned = %t", test.Filename, test.Expected) 57 | t.Fail() 58 | } 59 | } 60 | } 61 | 62 | func TestParseEmailInDN(t *testing.T) { 63 | const expectedEmail = "ca-winshuttle@dfn.de" 64 | b, err := ioutil.ReadFile(testdataPrefix + "email-in-subject.pem") 65 | if err != nil { 66 | t.Fatalf("could not open file: %s", err) 67 | } 68 | p, _ := pem.Decode(b) 69 | if p == nil { 70 | t.Fatalf("bad pem") 71 | } 72 | c, err := ParseCertificate(p.Bytes) 73 | if err != nil { 74 | t.Fatalf("could not parse: %s", err) 75 | } 76 | if len(c.Subject.EmailAddress) != 1 { 77 | t.Error("did not parse email address") 78 | } 79 | if email := c.Subject.EmailAddress[0]; email != expectedEmail { 80 | t.Errorf("mismatched email address, expected %s, got %s", expectedEmail, email) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /x509/performance_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/json" 9 | "encoding/pem" 10 | "io/ioutil" 11 | "testing" 12 | ) 13 | 14 | func BenchmarkParse(b *testing.B) { 15 | fileBytes, _ := ioutil.ReadFile("testdata/davidadrian.org.cert") 16 | p, _ := pem.Decode(fileBytes) 17 | for i := 0; i < b.N; i++ { 18 | ParseCertificate(p.Bytes) 19 | } 20 | } 21 | 22 | func BenchmarkEncode(b *testing.B) { 23 | fileBytes, _ := ioutil.ReadFile("testdata/davidadrian.org.cert") 24 | p, _ := pem.Decode(fileBytes) 25 | c, _ := ParseCertificate(p.Bytes) 26 | for i := 0; i < b.N; i++ { 27 | json.Marshal(c) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /x509/pkcs1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "crypto/rsa" 9 | "errors" 10 | "math/big" 11 | 12 | "github.com/zmap/zcrypto/encoding/asn1" 13 | ) 14 | 15 | // pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key. 16 | type pkcs1PrivateKey struct { 17 | Version int 18 | N *big.Int 19 | E int 20 | D *big.Int 21 | P *big.Int 22 | Q *big.Int 23 | // We ignore these values, if present, because rsa will calculate them. 24 | Dp *big.Int `asn1:"optional"` 25 | Dq *big.Int `asn1:"optional"` 26 | Qinv *big.Int `asn1:"optional"` 27 | 28 | AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"` 29 | } 30 | 31 | type pkcs1AdditionalRSAPrime struct { 32 | Prime *big.Int 33 | 34 | // We ignore these values because rsa will calculate them. 35 | Exp *big.Int 36 | Coeff *big.Int 37 | } 38 | 39 | // pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key. 40 | type pkcs1PublicKey struct { 41 | N *big.Int 42 | E int 43 | } 44 | 45 | // ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form. 46 | func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) { 47 | var priv pkcs1PrivateKey 48 | rest, err := asn1.Unmarshal(der, &priv) 49 | if len(rest) > 0 { 50 | return nil, asn1.SyntaxError{Msg: "trailing data"} 51 | } 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | if priv.Version > 1 { 57 | return nil, errors.New("x509: unsupported private key version") 58 | } 59 | 60 | if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 { 61 | return nil, errors.New("x509: private key contains zero or negative value") 62 | } 63 | 64 | key := new(rsa.PrivateKey) 65 | key.PublicKey = rsa.PublicKey{ 66 | E: priv.E, 67 | N: priv.N, 68 | } 69 | 70 | key.D = priv.D 71 | key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes)) 72 | key.Primes[0] = priv.P 73 | key.Primes[1] = priv.Q 74 | for i, a := range priv.AdditionalPrimes { 75 | if a.Prime.Sign() <= 0 { 76 | return nil, errors.New("x509: private key contains zero or negative prime") 77 | } 78 | key.Primes[i+2] = a.Prime 79 | // We ignore the other two values because rsa will calculate 80 | // them as needed. 81 | } 82 | 83 | err = key.Validate() 84 | if err != nil { 85 | return nil, err 86 | } 87 | key.Precompute() 88 | 89 | return key, nil 90 | } 91 | 92 | // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form. 93 | func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { 94 | key.Precompute() 95 | 96 | version := 0 97 | if len(key.Primes) > 2 { 98 | version = 1 99 | } 100 | 101 | priv := pkcs1PrivateKey{ 102 | Version: version, 103 | N: key.N, 104 | E: key.PublicKey.E, 105 | D: key.D, 106 | P: key.Primes[0], 107 | Q: key.Primes[1], 108 | Dp: key.Precomputed.Dp, 109 | Dq: key.Precomputed.Dq, 110 | Qinv: key.Precomputed.Qinv, 111 | } 112 | 113 | priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues)) 114 | for i, values := range key.Precomputed.CRTValues { 115 | priv.AdditionalPrimes[i].Prime = key.Primes[2+i] 116 | priv.AdditionalPrimes[i].Exp = values.Exp 117 | priv.AdditionalPrimes[i].Coeff = values.Coeff 118 | } 119 | 120 | b, _ := asn1.Marshal(priv) 121 | return b 122 | } 123 | -------------------------------------------------------------------------------- /x509/pkcs8_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "encoding/hex" 9 | "testing" 10 | ) 11 | 12 | var pkcs8RSAPrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031` 13 | 14 | // Generated using: 15 | // 16 | // openssl ecparam -genkey -name secp521r1 | openssl pkcs8 -topk8 -nocrypt 17 | var pkcs8ECPrivateKeyHex = `3081ed020100301006072a8648ce3d020106052b810400230481d53081d20201010441850d81618c5da1aec74c2eed608ba816038506975e6427237c2def150c96a3b13efbfa1f89f1be15cdf4d0ac26422e680e65a0ddd4ad3541ad76165fbf54d6e34ba18189038186000400da97bcedba1eb6d30aeb93c9f9a1454598fa47278df27d6f60ea73eb672d8dc528a9b67885b5b5dcef93c9824f7449ab512ee6a27e76142f56b94b474cfd697e810046c8ca70419365245c1d7d44d0db82c334073835d002232714548abbae6e5700f5ef315ee08b929d8581383dcf2d1c98c2f8a9fccbf79c9579f7b2fd8a90115ac2` 18 | 19 | func TestPKCS8(t *testing.T) { 20 | derBytes, _ := hex.DecodeString(pkcs8RSAPrivateKeyHex) 21 | if _, err := ParsePKCS8PrivateKey(derBytes); err != nil { 22 | t.Errorf("failed to decode PKCS8 with RSA private key: %s", err) 23 | } 24 | 25 | derBytes, _ = hex.DecodeString(pkcs8ECPrivateKeyHex) 26 | if _, err := ParsePKCS8PrivateKey(derBytes); err != nil { 27 | t.Errorf("failed to decode PKCS8 with EC private key: %s", err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /x509/pkix/oid.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package pkix 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | "strconv" 11 | "strings" 12 | 13 | "github.com/zmap/zcrypto/encoding/asn1" 14 | ) 15 | 16 | // AuxOID behaves similar to asn1.ObjectIdentifier, except encodes to JSON as a 17 | // string in dot notation. It is a type synonym for []int, and can be converted 18 | // to an asn1.ObjectIdentifier by going through []int and back. 19 | type AuxOID []int 20 | 21 | // AsSlice returns a slice over the inner-representation 22 | func (aux *AuxOID) AsSlice() []int { 23 | return *aux 24 | } 25 | 26 | // CopyAsSlice returns a copy of the inter-representation as a slice 27 | func (aux *AuxOID) CopyAsSlice() []int { 28 | out := make([]int, len(*aux)) 29 | copy(out, *aux) 30 | return out 31 | } 32 | 33 | // Equal tests (deep) equality of two AuxOIDs 34 | func (aux *AuxOID) Equal(other *AuxOID) bool { 35 | var a []int = *aux 36 | var b []int = *other 37 | if len(a) != len(b) { 38 | return false 39 | } 40 | for idx := range a { 41 | if a[idx] != b[idx] { 42 | return false 43 | } 44 | } 45 | return true 46 | } 47 | 48 | // MarshalJSON implements the json.Marshaler interface 49 | func (aux *AuxOID) MarshalJSON() ([]byte, error) { 50 | var oid asn1.ObjectIdentifier 51 | oid = []int(*aux) 52 | return json.Marshal(oid.String()) 53 | } 54 | 55 | // UnmarshalJSON implements the json.Unmarshaler interface 56 | func (aux *AuxOID) UnmarshalJSON(b []byte) error { 57 | var s string 58 | if err := json.Unmarshal(b, &s); err != nil { 59 | return err 60 | } 61 | parts := strings.Split(s, ".") 62 | if len(parts) < 1 { 63 | return fmt.Errorf("Invalid OID string %s", s) 64 | } 65 | slice := make([]int, len(parts)) 66 | for idx := range parts { 67 | n, err := strconv.Atoi(parts[idx]) 68 | if err != nil || n < 0 { 69 | return fmt.Errorf("Invalid OID integer %s", parts[idx]) 70 | } 71 | slice[idx] = n 72 | } 73 | *aux = slice 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /x509/pkix/pkix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package pkix 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestNameString(t *testing.T) { 14 | tests := []struct { 15 | name Name 16 | expected string 17 | legacy string 18 | }{ 19 | { 20 | name: Name{}, 21 | expected: "", 22 | legacy: "", 23 | }, 24 | { 25 | name: Name{ 26 | SerialNumber: "12345", 27 | CommonName: "common", 28 | Country: []string{"US", "RU"}, 29 | Organization: []string{"University of Michigan"}, 30 | OrganizationalUnit: []string{"0x21"}, 31 | Locality: []string{"Ann Arbor"}, 32 | Province: []string{"Michigan"}, 33 | StreetAddress: []string{"2260 Hayward St"}, 34 | PostalCode: []string{"48109"}, 35 | DomainComponent: nil, 36 | ExtraNames: []AttributeTypeAndValue{{Type: oidCommonName, Value: "name"}, {Type: oidSerialNumber, Value: "67890"}}, 37 | }, 38 | expected: "serialNumber=67890, CN=name, serialNumber=12345, C=US, C=RU, postalCode=48109, ST=Michigan, L=Ann Arbor, street=2260 Hayward St, O=University of Michigan, OU=0x21, CN=common", 39 | legacy: "CN=common, OU=0x21, O=University of Michigan, street=2260 Hayward St, L=Ann Arbor, ST=Michigan, postalCode=48109, C=US, C=RU, serialNumber=12345, CN=name, serialNumber=67890", 40 | }, 41 | { 42 | name: Name{ 43 | SerialNumber: "12345", 44 | CommonName: "common", 45 | PostalCode: []string{"48109"}, 46 | OriginalRDNS: RDNSequence{ 47 | []AttributeTypeAndValue{ 48 | {Type: oidPostalCode, Value: "48109"}, 49 | {Type: oidSerialNumber, Value: "12345"}, 50 | {Type: oidCommonName, Value: "common"}, 51 | {Type: oidGivenName, Value: "given"}, 52 | {Type: oidDomainComponent, Value: "domain"}, 53 | {Type: oidDNEmailAddress, Value: "user@dn.com"}, 54 | {Type: oidJurisdictionLocality, Value: "Locality"}, 55 | {Type: oidJurisdictionProvince, Value: "Prov"}, 56 | {Type: oidJurisdictionCountry, Value: "Canada"}, 57 | {Type: oidOrganizationID, Value: "QWACS"}, 58 | }, 59 | }, 60 | }, 61 | expected: "postalCode=48109, serialNumber=12345, CN=common, GN=given, DC=domain, emailAddress=user@dn.com, jurisdictionLocality=Locality, jurisdictionStateOrProvince=Prov, jurisdictionCountry=Canada, organizationIdentifier=QWACS", 62 | legacy: "postalCode=48109, serialNumber=12345, CN=common, GN=given, DC=domain, emailAddress=user@dn.com, jurisdictionLocality=Locality, jurisdictionStateOrProvince=Prov, jurisdictionCountry=Canada, organizationIdentifier=QWACS", 63 | }, 64 | } 65 | for _, test := range tests { 66 | s := test.name.String() 67 | assert.Equal(t, test.expected, s) 68 | } 69 | LegacyNameString = true 70 | for _, test := range tests { 71 | s := test.name.String() 72 | assert.Equal(t, test.legacy, s) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /x509/revocation/crl/test_crl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/x509/revocation/crl/test_crl -------------------------------------------------------------------------------- /x509/revocation/google/testdata/APm1SaUzZaPllaSDuZS5yng: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/x509/revocation/google/testdata/APm1SaUzZaPllaSDuZS5yng -------------------------------------------------------------------------------- /x509/revocation/google/testdata/crl-set-6375: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/x509/revocation/google/testdata/crl-set-6375 -------------------------------------------------------------------------------- /x509/revocation/google/testdata/test_crlset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/x509/revocation/google/testdata/test_crlset -------------------------------------------------------------------------------- /x509/revocation/microsoft/microsoft_test.go: -------------------------------------------------------------------------------- 1 | package microsoft_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | 8 | "github.com/zmap/zcrypto/x509" 9 | "github.com/zmap/zcrypto/x509/revocation/microsoft" 10 | ) 11 | 12 | // obtained from http://ctldl.windowsupdate.com/msdownload/update/v3/static/trustedr/en/disallowedcert.sst 13 | const disallowed_cert_location = `./test_disallowedcert.sst` 14 | 15 | const revoked_intermediate = ` 16 | -----BEGIN CERTIFICATE----- 17 | MIIEiDCCA3CgAwIBAgIEATFpsDANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJO 18 | TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSowKAYDVQQDEyFTdGFh 19 | dCBkZXIgTmVkZXJsYW5kZW4gT3ZlcmhlaWQgQ0EwHhcNMDcwNzA1MDg0MjA3WhcN 20 | MTUwNzI3MDgzOTQ2WjBfMQswCQYDVQQGEwJOTDEXMBUGA1UEChMORGlnaU5vdGFy 21 | IEIuVi4xNzA1BgNVBAMTLkRpZ2lOb3RhciBQS0lvdmVyaGVpZCBDQSBPdmVyaGVp 22 | ZCBlbiBCZWRyaWp2ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDc 23 | vdKnTmoKuzuiheF/AK2+tDBomAfNoHrElM9x+Yo35FPrV3bMi+Zs/u6HVcg+uwQ5 24 | AKeAeKxbT370vbhUuHE7BzFJOZNUfCA7eSuPu2GQfbGs5h+QLp1FAalkLU3DL7nn 25 | UNVOKlyrdnY3Rtd57EKZ96LspIlw3Dgrh6aqJOadkiQbvvb91C8ZF3rmMgeUVAVT 26 | Q+lsvK9Hy7zL/b07RBKB8WtLu+20z6slTxjSzAL8o0+1QjPLWc0J3NNQ/aB2jKx+ 27 | ZopC9q0ckvO2+xRG603XLzDgbe5bNr5EdLcgBVeFTegAGaL2DOauocBC36esgl3H 28 | aLcY5olLmmv6znn58yynAgMBAAGjggFQMIIBTDBIBgNVHSAEQTA/MD0GBFUdIAAw 29 | NTAzBggrBgEFBQcCARYnaHR0cDovL3d3dy5kaWdpbm90YXIubmwvY3BzL3BraW92 30 | ZXJoZWlkMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIGABgNVHSME 31 | eTB3gBQLhtYPd6NosftkCcOIblwEHFfpPaFZpFcwVTELMAkGA1UEBhMCTkwxHjAc 32 | BgNVBAoTFVN0YWF0IGRlciBOZWRlcmxhbmRlbjEmMCQGA1UEAxMdU3RhYXQgZGVy 33 | IE5lZGVybGFuZGVuIFJvb3QgQ0GCBACYmnkwPQYDVR0fBDYwNDAyoDCgLoYsaHR0 34 | cDovL2NybC5wa2lvdmVyaGVpZC5ubC9Eb21PdkxhdGVzdENSTC5jcmwwHQYDVR0O 35 | BBYEFEwIyY128ZjHPt881y91DbF2eZfMMA0GCSqGSIb3DQEBBQUAA4IBAQAMlIca 36 | v03jheLu19hjeQ5Q38aEW9K72fUxCho1l3TfFPoqDz7toOMI9tVOW6+mriXiRWsi 37 | D7dUKH6S3o0UbNEc5W50BJy37zRERd/Jgx0ZH8Apad+J1T/CsFNt5U4X5HNhIxMm 38 | cUP9TFnLw98iqiEr2b+VERqKpOKrp11Lbyn1UtHk0hWxi/7wA8+nfemZhzizDXMU 39 | 5HIs4c71rQZIZPrTKbmi2Lv01QulQERDjqC/zlqlUkxk0xcxYczopIro5Ij76eUv 40 | BjMzm5RmZrGrUDqhCYF0U1onuabSJc/Tw6f/ltAv6uAejVLpGBwgCkegllYOQJBR 41 | RKwa/fHuhR/3Qlpl 42 | -----END CERTIFICATE----- 43 | ` 44 | 45 | func parseCertPEM(t *testing.T) (revoked *x509.Certificate) { 46 | certPool := x509.NewCertPool() 47 | ok := certPool.AppendCertsFromPEM([]byte(revoked_intermediate)) 48 | if !ok { 49 | t.Fail() 50 | } 51 | revoked = certPool.Certificates()[0] 52 | return 53 | } 54 | 55 | func loadRevokedList(t *testing.T) (disallowed *microsoft.DisallowedCerts) { 56 | sstFile, err := os.Open(disallowed_cert_location) 57 | if err != nil { 58 | t.Error(err.Error()) 59 | } 60 | sstBytes, err := ioutil.ReadAll(sstFile) 61 | if err != nil { 62 | t.Error(err.Error()) 63 | } 64 | sstFile.Close() 65 | disallowed, err = microsoft.Parse(sstBytes) 66 | if err != nil { 67 | t.Error(err.Error()) 68 | } 69 | return 70 | } 71 | 72 | func TestParse(t *testing.T) { 73 | loadRevokedList(t) 74 | } 75 | 76 | func TestCheck(t *testing.T) { 77 | disallowed := loadRevokedList(t) 78 | revoked := parseCertPEM(t) 79 | entry := microsoft.Check(disallowed, revoked) 80 | if entry == nil { // this should provide an entry, since cert is revoked and in the provided sst file 81 | t.Fail() 82 | } 83 | if entry.SerialNumber.Cmp(revoked.SerialNumber) != 0 { 84 | t.Fail() 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /x509/revocation/microsoft/test_disallowedcert.sst: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/x509/revocation/microsoft/test_disallowedcert.sst -------------------------------------------------------------------------------- /x509/root.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | // To update the embedded iOS root store, update the -version 8 | // argument to the latest security_certificates version from 9 | // https://opensource.apple.com/source/security_certificates/ 10 | // and run "go generate". See https://golang.org/issue/38843. 11 | //go:generate go run root_ios_gen.go -version 55188.40.9 12 | 13 | import "sync" 14 | 15 | var ( 16 | once sync.Once 17 | systemRoots *CertPool 18 | systemRootsErr error 19 | ) 20 | 21 | func systemRootsPool() *CertPool { 22 | once.Do(initSystemRoots) 23 | return systemRoots 24 | } 25 | 26 | func initSystemRoots() { 27 | systemRoots, systemRootsErr = loadSystemRoots() 28 | if systemRootsErr != nil { 29 | systemRoots = nil 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /x509/root_darwin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !ios 6 | // +build !ios 7 | 8 | package x509 9 | 10 | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 11 | return nil, nil 12 | } 13 | 14 | func loadSystemRoots() (*CertPool, error) { 15 | return nil, nil 16 | } 17 | -------------------------------------------------------------------------------- /x509/root_darwin_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "os" 9 | "os/exec" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | func TestSystemRoots(t *testing.T) { 15 | t0 := time.Now() 16 | sysRoots, err := loadSystemRoots() // actual system roots 17 | sysRootsDuration := time.Since(t0) 18 | 19 | if err != nil { 20 | t.Fatalf("failed to read system roots: %v", err) 21 | } 22 | 23 | t.Logf("loadSystemRoots: %v", sysRootsDuration) 24 | 25 | // There are 174 system roots on Catalina, and 163 on iOS right now, require 26 | // at least 100 to make sure this is not completely broken. 27 | if want, have := 100, sysRoots.len(); have < want { 28 | t.Errorf("want at least %d system roots, have %d", want, have) 29 | } 30 | 31 | if t.Failed() { 32 | cmd := exec.Command("security", "dump-trust-settings") 33 | cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr 34 | cmd.Run() 35 | cmd = exec.Command("security", "dump-trust-settings", "-d") 36 | cmd.Stdout, cmd.Stderr = os.Stderr, os.Stderr 37 | cmd.Run() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /x509/root_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | // Possible certificate files; stop after finding one. 8 | var certFiles = []string{ 9 | "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. 10 | "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 11 | "/etc/ssl/ca-bundle.pem", // OpenSUSE 12 | "/etc/pki/tls/cacert.pem", // OpenELEC 13 | "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 14 | "/etc/ssl/cert.pem", // Alpine Linux 15 | } 16 | 17 | // Possible directories with certificate files; stop after successfully 18 | // reading at least one file from a directory. 19 | var certDirectories = []string{ 20 | "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 21 | "/etc/pki/tls/certs", // Fedora/RHEL 22 | "/system/etc/security/cacerts", // Android 23 | } 24 | -------------------------------------------------------------------------------- /x509/root_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris 6 | // +build aix dragonfly freebsd js,wasm linux netbsd openbsd solaris 7 | 8 | package x509 9 | 10 | import ( 11 | "io/fs" 12 | "os" 13 | "path/filepath" 14 | "strings" 15 | ) 16 | 17 | const ( 18 | // certFileEnv is the environment variable which identifies where to locate 19 | // the SSL certificate file. If set this overrides the system default. 20 | certFileEnv = "SSL_CERT_FILE" 21 | 22 | // certDirEnv is the environment variable which identifies which directory 23 | // to check for SSL certificate files. If set this overrides the system default. 24 | // It is a colon separated list of directories. 25 | // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html. 26 | certDirEnv = "SSL_CERT_DIR" 27 | ) 28 | 29 | func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { 30 | return nil, nil 31 | } 32 | 33 | func loadSystemRoots() (*CertPool, error) { 34 | roots := NewCertPool() 35 | 36 | files := certFiles 37 | if f := os.Getenv(certFileEnv); f != "" { 38 | files = []string{f} 39 | } 40 | 41 | var firstErr error 42 | for _, file := range files { 43 | data, err := os.ReadFile(file) 44 | if err == nil { 45 | roots.AppendCertsFromPEM(data) 46 | break 47 | } 48 | if firstErr == nil && !os.IsNotExist(err) { 49 | firstErr = err 50 | } 51 | } 52 | 53 | dirs := certDirectories 54 | if d := os.Getenv(certDirEnv); d != "" { 55 | // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator. 56 | // See: 57 | // * https://golang.org/issue/35325 58 | // * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html 59 | dirs = strings.Split(d, ":") 60 | } 61 | 62 | for _, directory := range dirs { 63 | fis, err := readUniqueDirectoryEntries(directory) 64 | if err != nil { 65 | if firstErr == nil && !os.IsNotExist(err) { 66 | firstErr = err 67 | } 68 | continue 69 | } 70 | for _, fi := range fis { 71 | data, err := os.ReadFile(directory + "/" + fi.Name()) 72 | if err == nil { 73 | roots.AppendCertsFromPEM(data) 74 | } 75 | } 76 | } 77 | 78 | if roots.Size() > 0 || firstErr == nil { 79 | return roots, nil 80 | } 81 | 82 | return nil, firstErr 83 | } 84 | 85 | // readUniqueDirectoryEntries is like os.ReadDir but omits 86 | // symlinks that point within the directory. 87 | func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) { 88 | files, err := os.ReadDir(dir) 89 | if err != nil { 90 | return nil, err 91 | } 92 | uniq := files[:0] 93 | for _, f := range files { 94 | if !isSameDirSymlink(f, dir) { 95 | uniq = append(uniq, f) 96 | } 97 | } 98 | return uniq, nil 99 | } 100 | 101 | // isSameDirSymlink reports whether fi in dir is a symlink with a 102 | // target not containing a slash. 103 | func isSameDirSymlink(f fs.DirEntry, dir string) bool { 104 | if f.Type()&fs.ModeSymlink == 0 { 105 | return false 106 | } 107 | target, err := os.Readlink(filepath.Join(dir, f.Name())) 108 | return err == nil && !strings.Contains(target, "/") 109 | } 110 | -------------------------------------------------------------------------------- /x509/sec1_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | var ecKeyTests = []struct { 14 | derHex string 15 | shouldReserialize bool 16 | }{ 17 | // Generated using: 18 | // openssl ecparam -genkey -name secp384r1 -outform PEM 19 | {"3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50", true}, 20 | // This key was generated by GnuTLS and has illegal zero-padding of the 21 | // private key. See https://github.com/golang/go/issues/13699. 22 | {"3078020101042100f9f43a04b9bdc3ab01f53be6df80e7a7bc3eaf7b87fc24e630a4a0aa97633645a00a06082a8648ce3d030107a1440342000441a51bc318461b4c39a45048a16d4fc2a935b1ea7fe86e8c1fa219d6f2438f7c7fd62957d3442efb94b6a23eb0ea66dda663dc42f379cda6630b21b7888a5d3d", false}, 23 | // This was generated using an old version of OpenSSL and is missing a 24 | // leading zero byte in the private key that should be present. 25 | {"3081db0201010441607b4f985774ac21e633999794542e09312073480baa69550914d6d43d8414441e61b36650567901da714f94dffb3ce0e2575c31928a0997d51df5c440e983ca17a00706052b81040023a181890381860004001661557afedd7ac8d6b70e038e576558c626eb62edda36d29c3a1310277c11f67a8c6f949e5430a37dcfb95d902c1b5b5379c389873b9dd17be3bdb088a4774a7401072f830fb9a08d93bfa50a03dd3292ea07928724ddb915d831917a338f6b0aecfbc3cf5352c4a1295d356890c41c34116d29eeb93779aab9d9d78e2613437740f6", false}, 26 | } 27 | 28 | func TestParseECPrivateKey(t *testing.T) { 29 | for i, test := range ecKeyTests { 30 | derBytes, _ := hex.DecodeString(test.derHex) 31 | key, err := ParseECPrivateKey(derBytes) 32 | if err != nil { 33 | t.Fatalf("#%d: failed to decode EC private key: %s", i, err) 34 | } 35 | serialized, err := MarshalECPrivateKey(key) 36 | if err != nil { 37 | t.Fatalf("#%d: failed to encode EC private key: %s", i, err) 38 | } 39 | matches := bytes.Equal(serialized, derBytes) 40 | if matches != test.shouldReserialize { 41 | t.Fatalf("#%d: when serializing key: matches=%t, should match=%t: original %x, reserialized %x", i, matches, test.shouldReserialize, serialized, derBytes) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /x509/testdata/.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | -------------------------------------------------------------------------------- /x509/testdata/ca.cnf: -------------------------------------------------------------------------------- 1 | SUBJECT_NAME = req_dn 2 | KEY_SIZE = 2048 3 | 4 | [req] 5 | default_bits = ${ENV::KEY_SIZE} 6 | default_md = sha256 7 | string_mask = utf8only 8 | prompt = no 9 | encrypt_key = no 10 | distinguished_name = ${ENV::SUBJECT_NAME} 11 | req_extensions = req_extensions 12 | 13 | [req_extensions] 14 | subjectAltName = IP:127.0.0.1 15 | 16 | [root_extensions] 17 | basicConstraints = critical, CA:true 18 | subjectKeyIdentifier = hash 19 | authorityKeyIdentifier = keyid:always,issuer 20 | keyUsage = critical, cRLSign, keyCertSign 21 | 22 | [intermediate_extensions] 23 | basicConstraints = critical, CA:true 24 | subjectKeyIdentifier = hash 25 | authorityKeyIdentifier = keyid:always,issuer 26 | keyUsage = critical, cRLSign, keyCertSign 27 | 28 | [leaf_extensions] 29 | basicConstraints = critical, CA:FALSE 30 | subjectKeyIdentifier = hash 31 | authorityKeyIdentifier = keyid,issuer 32 | keyUsage = digitalSignature, keyEncipherment, dataEncipherment 33 | 34 | [root_ca] 35 | new_certs_dir = out 36 | unique_subject = no 37 | database = out/root.index 38 | serial = out/root.serial 39 | default_days = 1825 40 | default_md = sha256 41 | policy = root_ca_policy 42 | email_in_dn = no 43 | 44 | [intermediate_ca] 45 | new_certs_dir = out 46 | unique_subject = no 47 | database = out/intermediate.index 48 | serial = out/intermediate.serial 49 | default_days = 1825 50 | default_md = sha256 51 | policy = intermediate_ca_policy 52 | email_in_dn = no 53 | 54 | [root_ca_policy] 55 | commonName = supplied 56 | 57 | [intermediate_ca_policy] 58 | commonName = supplied 59 | 60 | [root_subject] 61 | C = US 62 | ST = Michigan 63 | L = Ann Arbor 64 | O = ZCrypto 65 | CN = ZCrypto Root Authority 66 | 67 | [intermediate_subject] 68 | C = US 69 | ST = Michigan 70 | L = Ann Arbor 71 | O = ZCrypto 72 | CN = ZCrypto Intermediate Authority 73 | 74 | [leaf_never_valid] 75 | C = US 76 | ST = Michigan 77 | L = Ann Arbor 78 | O = Test 79 | CN = never-valid.example.com 80 | 81 | -------------------------------------------------------------------------------- /x509/testdata/dadrian.io.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIE+DCCA+CgAwIBAgISA4LrXYc6OZI1Nbh/YMDVBE7LMA0GCSqGSIb3DQEBCwUA 3 | MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD 4 | ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNzA0MTMxOTMyMDBaFw0x 5 | NzA3MTIxOTMyMDBaMBUxEzARBgNVBAMTCmRhZHJpYW4uaW8wggEiMA0GCSqGSIb3 6 | DQEBAQUAA4IBDwAwggEKAoIBAQDyomUvbPk7tLIRMxUulZmyL9E639ADDlijKRT8 7 | sJRPU75p5CyxuNI8szGQbt3UYPjAhE/2yxc0h5HMBEoEW2POef6kGZwwKBEv283b 8 | zNkOcuF1srSYBlmI75ya39vyKO76Jpxl1kIA7QHgGuY/8ahLtT8GtMPnYBNH+4uo 9 | KOwRDPpR27zY7EcZluFTPLNpf2op8dvkwZjwwPC9eNQSj/cH0FjzqLPqFmpEzBgk 10 | mfVzLatvcVHV2NQ0QHpb+dTL1tf8UmEpKB3eXECDadhMCHi7ZZhDXPAkGsFUbmqx 11 | fBh8P+nsbEF6eHm5KPad5+41K27n27ZWBIjXmdWRyUxpZzJlAgMBAAGjggILMIIC 12 | BzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC 13 | MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFIQ36PvtTBmz1JFC4fQ/aYKX1yeAMB8G 14 | A1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUFBwEBBGQwYjAv 15 | BggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9yZy8w 16 | LwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5vcmcv 17 | MBUGA1UdEQQOMAyCCmRhZHJpYW4uaW8wgf4GA1UdIASB9jCB8zAIBgZngQwBAgEw 18 | geYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNl 19 | bmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRpZmljYXRlIG1h 20 | eSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBhbmQgb25s 21 | eSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGljeSBmb3Vu 22 | ZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzANBgkqhkiG 23 | 9w0BAQsFAAOCAQEAMdm7dQzo4ptGTGwfXiMaUJbQOVsvWu/EBYDZfEruO1a9PHff 24 | p1/u/8KuEyn5/8HEN1mRJ0/4W3v98DK0kwEG8jZhG9EKvD1rwMwNEEpZxs/T3yJE 25 | 16lCwHHqCo59wDaUHiLI2clSe5K6CuB6d7P+s0KoaYQ/zF7F3+1v1ULWoxy2ugZW 26 | LZW2NE6QHmmEOAt0b7RHaCedgXYbEgMReLnOEbKEW0XK0SWLB0ZirhuaJizWP2hW 27 | XrkMflRNRNHN1qjWGwz6N3xwTgCo77l4TJqIUHKmagLafAUzxFWmFG3Yiqpskl5x 28 | hCSiEEC4VgIfffxA+CwiB84Hf2LUUeYnWQcmAw== 29 | -----END CERTIFICATE----- 30 | -------------------------------------------------------------------------------- /x509/testdata/davidadrian.org.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIHbDCCBlSgAwIBAgIDD6A1MA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ 3 | TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0 4 | YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg 5 | MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTQwNDA3MDI1NzE2 6 | WhcNMTUwNDA4MDExNDI1WjB3MRkwFwYDVQQNExBSZDJ1VVkwWXFGSE1uZnM3MQsw 7 | CQYDVQQGEwJVUzEcMBoGA1UEAxMTd3d3LmRhdmlkYWRyaWFuLm9yZzEvMC0GCSqG 8 | SIb3DQEJARYgZGF2aWRhZHJpYW5AYWRyaWFudGVjaG5vbG9neS5jb20wggIiMA0G 9 | CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCrtiLMb8qVcy4CWv1sjXmvTqWYIOex 10 | AR1GiT+4CNJlpniFGA6SFusOI7IId68zeH1elo24dUboNeWlcq2krZMx5rpBnWid 11 | RB0EAEcAVC7GPM4d6YGq124AyqtNq3Clgm6KIbPBYg5feVuOWwrcCQvy1ZJVTS4i 12 | xBoVAMHb7og0/0veCzAzvdyG/nb2tG00J4HmFNRk0G3zPWQF18VBEkFNsSxGEHk6 13 | ++eW+4o6jwpphc8/oWK8PArUVc0MFWF91ewovtknOe4lTDFk7Mh97sBYXjB/tjba 14 | FS8kWlX0jGnbJSV+BLT7cYq72hbKOh58jLDUzEPtvtK9TMw6qDQr4XPIvb0jzbTM 15 | wC18LWrblxEGLU1nIqP44IGSTf8elyrENpm1nyZuUpZmKfYgaur9YmOaRDN+7b+6 16 | DnvK9PmkDfBpCPfLCt4gZLPqbToJcShfG1EWfLshkNFs9dfpYpt69IG9LmwMgaZY 17 | 3i9g82okpOWAzzBiObLH7QEoAh/nGMhc6ugjkw9km1KBVMwRl4Na7qO3Z+mtokDr 18 | OJ7lCHxC0LfpYjIdS7T7yzJ3ecRPbNZHKB+kaZC28siAaN+nGvhnwkvWoBGe7NG7 19 | bu4W/QAyFvgDIdoW674pRhxW40wNu/dDdzvD3klt+k9nvAesibDHSvjd5MyimrgH 20 | gFdlCRXkkWqbVQIDAQABo4IC6TCCAuUwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gw 21 | EwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0OBBYEFBXLU2k0WFEg1+OHU8chynIg 22 | uC+1MB8GA1UdIwQYMBaAFOtCNNCYsKuf9BtrCPfMZC7vDixFMC8GA1UdEQQoMCaC 23 | E3d3dy5kYXZpZGFkcmlhbi5vcmeCD2RhdmlkYWRyaWFuLm9yZzCCAVYGA1UdIASC 24 | AU0wggFJMAgGBmeBDAECATCCATsGCysGAQQBgbU3AQIDMIIBKjAuBggrBgEFBQcC 25 | ARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjCB9wYIKwYBBQUH 26 | AgIwgeowJxYgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwAwIBARqB 27 | vlRoaXMgY2VydGlmaWNhdGUgd2FzIGlzc3VlZCBhY2NvcmRpbmcgdG8gdGhlIENs 28 | YXNzIDEgVmFsaWRhdGlvbiByZXF1aXJlbWVudHMgb2YgdGhlIFN0YXJ0Q29tIENB 29 | IHBvbGljeSwgcmVsaWFuY2Ugb25seSBmb3IgdGhlIGludGVuZGVkIHB1cnBvc2Ug 30 | aW4gY29tcGxpYW5jZSBvZiB0aGUgcmVseWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4w 31 | NQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1j 32 | cmwuY3JsMIGOBggrBgEFBQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2Nz 33 | cC5zdGFydHNzbC5jb20vc3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKG 34 | Nmh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVy 35 | LmNhLmNydDAjBgNVHRIEHDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJ 36 | KoZIhvcNAQEFBQADggEBAJ9J4Bv3/1yaatK43YEtYI/sdHOo/uXPQILLmchR+qFF 37 | kSG07DXc8oKt29UJEinHEi/84VApqtZz7vhzXtmwUYRgbMugBF3UITbPJxZLggeh 38 | aJt+2mDUNzPO/Kq6Ergd1KOZ1qoxPwOgLu9FEc8aY+TaLp8oi0CjV+x0YEnnE8Kb 39 | Qb+Qmoy0gqrTrnK7L3+5eViSP6v+0rek2aiBvu8LlQrT4Kg6o69VZ9F6A1ISQ8L5 40 | EPS8OVZ2VJ2MBf1JW0oSf3mS60qbiwfXHeUE2Y57te0Pf+f1GG2bzeVHrW4FUkOJ 41 | aYTyjMvZ7Z2hPyIaA0XolBM+0rWH7CnVtSTzjp3zIGA= 42 | -----END CERTIFICATE----- 43 | -------------------------------------------------------------------------------- /x509/testdata/etsi_qc.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFRzCCBC+gAwIBAgIMHv2nPE8W61evcLlPMA0GCSqGSIb3DQEBCwUAMEAxCzAJ 3 | BgNVBAYTAlBLMRQwEgYDVQQKEwtEZXZlbG9wbWVudDEbMBkGA1UEAxMSRGV2ZWxv 4 | cG1lbnQgU3ViIENBMB4XDTE5MDkyNTA5Mzc1N1oXDTI5MTAyNjA5Mzc1N1owgYEx 5 | CzAJBgNVBAYTAlBLMRQwEgYDVQQKEwtEZXZlbG9wbWVudDESMBAGA1UEBRMJNTc4 6 | NjExNjc1MRcwFQYDVQQqEw5NdWhhbW1hZCBCaWxhbDEPMA0GA1UEBBMGQXNocmFm 7 | MR4wHAYDVQQDExVNdWhhbW1hZCBCaWxhbCBBc2hyYWYwggEiMA0GCSqGSIb3DQEB 8 | AQUAA4IBDwAwggEKAoIBAQDYc9WiU28DSpW7Bc9xch2tr9b9U4vPHlHJGMAdQLyy 9 | xgo8snms2NRwAWsgxEEQtXDUH5Kvf/rvVwOyHXacWQ7gp8Kmmu8b2ClXbItk82Gl 10 | Q+rGltdrofpVC/g9g0e5/vmQ8nPKfZ2SHD9EY1+I31v+ozgtLEfOWs576CM3u5Jo 11 | sRy2vXq/uW7rnSVs0Lb1d8b0W5Ep4cAHThagW2B7o/dfC9GQdNW9xSPHRdJEPcVt 12 | y+L9KoplK0Us3fzZen+4DtL6RfR5UcfIiBDITJ06rmUjWZNEKwmfS85dq/ZiBmIc 13 | a+kMzNc/P+P+IAVuUuYZ40VFRAMivBNhQR90aMEY4CVXAgMBAAGjggH9MIIB+TAO 14 | BgNVHQ8BAf8EBAMCBsAwEwYDVR0lBAwwCgYIKwYBBQUHAwQwDAYDVR0TAQH/BAIw 15 | ADAdBgNVHQ4EFgQUXjt/HejVWH7uJrPHkuZawQ5fu50wHwYDVR0jBBgwFoAUMM2D 16 | pzaspTX/IRs3QG6yz18cAy8wUgYIKwYBBQUHAQEERjBEMB8GCCsGAQUFBzABhhNo 17 | dHRwOi8vZGV2LmNvbS9vY3NwMCEGCCsGAQUFBzAChhVodHRwOi8vZGV2LmNvbS9j 18 | YS5jcnQwIQYDVR0RBBowGIEWYmlsYWwuYXNocmFmQGdtYWlsLmNvbTAmBgNVHR8E 19 | HzAdMBugGaAXhhVodHRwOi8vZGV2LmNvbS9jYS5jcmwwQAYDVR0gBDkwNzA1BgQr 20 | BwgJMC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LmRldi5jb20vcmVwb3NpdG9y 21 | eS8wgaIGCCsGAQUFBwEDBIGVMIGSMAgGBgQAjkYBATALBgYEAI5GAQMCAQowFgYG 22 | BACORgECMAwTBEVVUk8CAQoCAQIwCAYGBACORgEEMDAGBgQAjkYBBTAmMCQWHmh0 23 | dHBzOi8vZGV2LmNvbS9wZHMvZW4vcGRzLnBkZhMCZW4wJQYGBACORgEGMBsGBwQA 24 | jkYBBgEGBwQAjkYBBgIGBwQAjkYBBgMwDQYJKoZIhvcNAQELBQADggEBAA8lmEyM 25 | 7xm8yG1G33tJh0jcY6GnLoVlkC4cl/1Hx2eYXWC+6LCL8L1rvNYRohivRKNNu/Vt 26 | GHsSeKqfdGCMxvJIyryu1yGxS5mJwn+/vLFx3Lx/cP2/FtdXE1pgtvsbmIMQlrx5 27 | BsFlaRKWZZA3PmGI4pVFUO8CHIp4KU/fE3pN+kSGfJnDapF1E6wmlrfUWuIe99if 28 | OzElsnYnxDGFIvn0irbcO3Iwc3+kOVxZFmNLkLWNPOxCEZXXs8GvQmQEkrWhFc0O 29 | 1E7Dsy0m5mBEMyivLIjumfkY1fOmVOO7kmdnAvvv0kAbnwENAof7Zzdjt7wAnwN9 30 | EIUG5Vh3vVneLWg= 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /x509/testdata/gsa103.enterprisedemo-google.com.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEmjCCA4KgAwIBAgIIYsOHbtwmjtAwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE 3 | BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl 4 | cm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwOTAyMDg1ODUwWhcNMTYwOTAxMDAwMDAw 5 | WjB6MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN 6 | TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEpMCcGA1UEAwwgZ3Nh 7 | MTAzLmVudGVycHJpc2VkZW1vLWdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA 8 | A4IBDwAwggEKAoIBAQDV92cmrQp24ITw5QYps6wgwcTPnd/MDGWCmmsAenG6OuWM 9 | AJCnYmCQ0fSPlZwXmLtVVIA9GeklZ1TnPgqYGt/rlkzgpAh+TjAb1ZXJA+xlpNN8 10 | fsJMMqCkNvJtSo4fZcwjzmd48kby2AquE0gq+j83NHkDuZlUUlmVqTc1vt2e52zf 11 | lN5p0IKeLiHMEO86mZr8CPa3AyaiKLf8gx85pzBOsBMf5ujkLbXPIiLmWoXT5eJm 12 | eUMPwU4qtJc/Nms2G2AFAOGcLC3U4apmmVEm7xz3WL1mc4Ii/YheE1lacIaWFl2N 13 | 25O0zkaocOttT2MA5vEjgV1Ue8XjBKvsSwgCahQBAgMBAAGjggFTMIIBTzAdBgNV 14 | HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwKwYDVR0RBCQwIoIgZ3NhMTAzLmVu 15 | dGVycHJpc2VkZW1vLWdvb2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUF 16 | BzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzAB 17 | hh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBSFSUQj 18 | X/uEjKxJsQuO7eq6jWm1GTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYb 19 | vPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8E 20 | KTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqG 21 | SIb3DQEBCwUAA4IBAQANoLafRl8LHngGwc+SaNOekJa3tvOw27Dm9Rj6Oo+azWAJ 22 | /BpaLCrwwE2Dab6rjkzsZBlQXlhRuef/k7cmGN8inU9vqN3oNVu+N93/OsWZkgDo 23 | DY4Vmve6zDpiSKS3PLS3s8vsXnUc146U3Mcu+ISpXdoMvdUo3YyI8eXMO0lPBiCq 24 | OqXDxtgEdOPJpapZEI/w6TWzPVbTmxwE4mEAtl2iMfin0sXW9PWtFvDE5QUbJrbJ 25 | T3raJiQVNSpiWe90MwEuLmoQPEfPr378g/aV/Wuxm4nWwkyqZBwxGQIiXXjQmKZa 26 | W7SXUuH3QZHFeO6L+uNu8H72Mj9q1KOXT4GSg9az 27 | -----END CERTIFICATE----- 28 | -------------------------------------------------------------------------------- /x509/testdata/mbernhard.com.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIE/jCCA+agAwIBAgISA1B9GjAr262YdQBv6Vpeq+QeMA0GCSqGSIb3DQEBCwUA 3 | MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD 4 | ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjA0MTgyMTQ4MDBaFw0x 5 | NjA3MTcyMTQ4MDBaMBgxFjAUBgNVBAMTDW1iZXJuaGFyZC5jb20wggEiMA0GCSqG 6 | SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJD5VIULC7mE6ior5hVk8AKSzOkrMfP4+p 7 | L0tfz0g2l7BeBHlvWimpdqHp4rMZjbexUThKog3zus+cQh36XkSXVYFUzdkusty8 8 | aukKJHMfkcXBTsOERkMgy1yC0d2vpzFppF1gmx9NhGiduZKutoqaBtbW7CTx7SWi 9 | z6PSj5MHZjwmlCryJEowO/zOfumWoJphHYT+nHYvK5r1VL5o2+0EthPwYJkpv7ot 10 | pHxE/+EPbljjp41PgnCphlQBNQNxrr1u84Vr+E0t+DI0KBPTIEjmxlAhaV7CvpS0 11 | 3B3qSC9x7yixWbhzLe4cqLmjHkrVbdd+akvYATg63wGmuc2t/20FAgMBAAGjggIO 12 | MIICCjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF 13 | BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKDwsypkNsM7djOue4lY3uy+kpM3 14 | MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUFBwEBBGQw 15 | YjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9y 16 | Zy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5v 17 | cmcvMBgGA1UdEQQRMA+CDW1iZXJuaGFyZC5jb20wgf4GA1UdIASB9jCB8zAIBgZn 18 | gQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRwOi8vY3Bz 19 | LmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRpZmlj 20 | YXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBh 21 | bmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGlj 22 | eSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzAN 23 | BgkqhkiG9w0BAQsFAAOCAQEAi5GmDCmdwoA0ACmT++pb5sJJiLD+EcxSj2lw16fU 24 | 5N3oTjtTvnFcfDL5jXxOmpqNq211H2o1dM5wOjVKBHz5R44v6qg2szWKNs8dxRiz 25 | ls7UjbY7zcAiLcMUwHPP/I7A5YfS+nauW6P9bTf3Rc4LMkxJXLGoMlEHRrA3tE2J 26 | rCdSymFB4/XVfmiawPl3hmtpY6y/5B0I8fmmh6KS4DXFfuCIYVaJ3Z2v/WRWpCYn 27 | 71kR+xWsZgZS2ivRrgKjh5bclAlRIpiFlOmYEVTJIzhW0iTmkFFsne41kOkQW8Ms 28 | vFSxl5yhI7eMzcbGgnvFYKFeaCATzfuMT2njtW5sl2h7TQ== 29 | -----END CERTIFICATE----- 30 | -------------------------------------------------------------------------------- /x509/testdata/pad.jhalderm.com.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIG1zCCBb+gAwIBAgIDAWfJMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ 3 | TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0 4 | YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg 5 | MiBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTMwNTIwMDQzMTM1 6 | WhcNMTUwNTIxMTM0NTQzWjCBtzEZMBcGA1UEDRMQRzU1SHU3NzhWSVkzVHNUNDEL 7 | MAkGA1UEBhMCVVMxFTATBgNVBAgTDFBlbm5zeWx2YW5pYTERMA8GA1UEBxMIUnVz 8 | aGxhbmQxFzAVBgNVBAoTDkpvaG4gSGFsZGVybWFuMRkwFwYDVQQDExB3d3cuamhh 9 | bGRlcm0uY29tMS8wLQYJKoZIhvcNAQkBFiBqaGFsZGVybS5jb21AcHJveHkuZHJl 10 | YW1ob3N0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwksz/2 11 | MAYMNFfTMgRpvfkrLXzVQMs/HJyQ9j8D64STYYPwPirNQYBm3c5pyOKKWUi908tm 12 | bLH8qN0F+jD/T+nIJMxuhMZuWNTprMJ4k+bwIdVhUol0RZ2H1sYY9pVJGNwwFCh4 13 | cLCeqq3HcDbjfPIrST/2g4tvTET/MxS448L3YaM7OaxqcV7HXl1MQkMXrwsmrIJW 14 | Dkv2jaMdUcHWX5cjxeVqlWGqgjXsXpfB75xBvK20pjqBn3gC6Dg6N07MO3NxM+sC 15 | 6ykMEbPsP7h41VgjLbM36gVRWQRRTjbQ+glPmbohnizxRboLkR3l8ryAnjLQgUzC 16 | OJ1ae5E2I808Ut0CAwEAAaOCAxMwggMPMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOo 17 | MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAdBgNVHQ4EFgQU2KmlVBXN 18 | 9yNg/FmWmL8OhXTnmEcwHwYDVR0jBBgwFoAUEdsjRf1UzGpxb4SKA9e+9wEvJoYw 19 | TwYDVR0RBEgwRoIQd3d3LmpoYWxkZXJtLmNvbYIMamhhbGRlcm0uY29tghBwYWQu 20 | amhhbGRlcm0uY29tghIqLnBhZC5qaGFsZGVybS5jb20wggFWBgNVHSAEggFNMIIB 21 | STAIBgZngQwBAgIwggE7BgsrBgEEAYG1NwECAzCCASowLgYIKwYBBQUHAgEWImh0 22 | dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwgfcGCCsGAQUFBwICMIHq 23 | MCcWIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MAMCAQEagb5UaGlz 24 | IGNlcnRpZmljYXRlIHdhcyBpc3N1ZWQgYWNjb3JkaW5nIHRvIHRoZSBDbGFzcyAy 25 | IFZhbGlkYXRpb24gcmVxdWlyZW1lbnRzIG9mIHRoZSBTdGFydENvbSBDQSBwb2xp 26 | Y3ksIHJlbGlhbmNlIG9ubHkgZm9yIHRoZSBpbnRlbmRlZCBwdXJwb3NlIGluIGNv 27 | bXBsaWFuY2Ugb2YgdGhlIHJlbHlpbmcgcGFydHkgb2JsaWdhdGlvbnMuMDUGA1Ud 28 | HwQuMCwwKqAooCaGJGh0dHA6Ly9jcmwuc3RhcnRzc2wuY29tL2NydDItY3JsLmNy 29 | bDCBjgYIKwYBBQUHAQEEgYEwfzA5BggrBgEFBQcwAYYtaHR0cDovL29jc3Auc3Rh 30 | cnRzc2wuY29tL3N1Yi9jbGFzczIvc2VydmVyL2NhMEIGCCsGAQUFBzAChjZodHRw 31 | Oi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0cy9zdWIuY2xhc3MyLnNlcnZlci5jYS5j 32 | cnQwIwYDVR0SBBwwGoYYaHR0cDovL3d3dy5zdGFydHNzbC5jb20vMA0GCSqGSIb3 33 | DQEBBQUAA4IBAQBBwM/z05xQlvVWma9QP7egXLoY2K55cJWPN2P6feeDJJf8z+Av 34 | Z5HQTJHDMm1Fs6vile1ErZyfSd2emDneQaL5FXhuoHSH1U9/HvrIyQ21c25pyCuV 35 | myzOp3YtCxaESk4WRHfsuuTKZyLJel1yZd7QEgY0qlliqrYom3esMVFsXYzfvL9o 36 | b0JwKq3CnHdX7d76FIpCk0j5FEOe/fmTpHOd4jWaxjIUyWJ28bf3CmgKtOEURT3m 37 | zMIvsQL5Nv25lZSgvjo+VHrVuoK1BvhRx0uYGr3aVeiIY4A4jYaGgc7C7X6NkxKr 38 | 2zkDeHbVXRbhDH67HlyqHEbD8OWCmPOns/PM 39 | -----END CERTIFICATE----- 40 | -------------------------------------------------------------------------------- /x509/testdata/parsecert1.pem: -------------------------------------------------------------------------------- 1 | # Issuer: C=US, O=Tridium, CN=Niagara4 2 | # Subject: C=US, O=Tridium, CN=Niagara4 3 | # Validity 4 | # Not Before: Aug 11 16:41:01 2017 GMT 5 | # Not After : Aug 11 16:41:01 2018 GMT 6 | -----BEGIN CERTIFICATE----- 7 | MIIDazCCAlOgAwIBAgIMR68FnReJBhmumfOCMA0GCSqGSIb3DQEBCwUAMDIxETAP 8 | BgNVBAMMCE5pYWdhcmE0MRAwDgYDVQQKDAdUcmlkaXVtMQswCQYDVQQGEwJVUzAe 9 | Fw0xNzA4MTExNjQxMDFaFw0xODA4MTExNjQxMDFaMDIxETAPBgNVBAMMCE5pYWdh 10 | cmE0MRAwDgYDVQQKDAdUcmlkaXVtMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN 11 | AQEBBQADggEPADCCAQoCggEBALmLhvLfz9+dP+xh8HhnuKElwO1ZL+i0LTx5Nslq 12 | h1EAf5UZLyUpYA3LEhb0BEmJd6NQ6ZEIQlcXuf0TvHb9lmnUK6urdYq4oEsoR9UM 13 | 6RUQD6xoiytfWcntL18VxosnhqGnWnM0n7DqVXaCnv8hDuktgGiEDV8MvPkVD96b 14 | UREOc8hbwChbeLV7YIlHh3KPJS7YWbtH4LKm396wHsPjIW2X4QJv5YzF9U8HCH+T 15 | KOd9FfP8PTeA5+NtMOxYJJo2bGWZXyz1Pm79+H/G2HiJMEgGsYYxyp9oT7bcyciI 16 | PFhfvO2yphNjtE7/2dg4fPdxvqVfY67c1mNbaysoeAP5vJsCAwEAAaOBgDB+MB0G 17 | A1UdDgQWBBQkZ/7HAqNpa0mmdWUIa4Qs5os8mTAdBgNVHSUEFjAUBggrBgEFBQcD 18 | AQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQDAgWgMC4GA1UdEgQnMCWgIwYIKwYBBAGg 19 | IwIMF1dpbi03MDRGLTJGQUItRjJGNC04RTY5MA0GCSqGSIb3DQEBCwUAA4IBAQBF 20 | quhb2SW+e4DnqFkA7vdG0gPtTmV3933LzNE8rxlikEXBNF+6Xa1FpI3clUZs8vKT 21 | xvfWfcqZnmLHxrsBJ65Y71TN2YsFhvo9mF4SYZZq/UspAJo/YQ3/j51FBtVW4tkr 22 | bWmoZGM5eX0AJE+Ec8tvUYOGjBRQylb8cGuQGbtjnhlHkw6rveG9irn4QaMjZOa/ 23 | b4G1E/u5JoURoJ3z8ebrCT1okBSUWYQ9htf4rRW8mvJ2fGD8NYZXGEho/65bWTmK 24 | VtmewY+VGC3hp62msnwM9SEv4gSVpElziFGfF1iQsfti2w2z9cjKPYgk0+uw0Hph 25 | YrsAoZZ9c+33OBZJNzwt 26 | -----END CERTIFICATE----- 27 | -------------------------------------------------------------------------------- /x509/testdata/parsecert10-tag.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x02) 2 | # Serial number: 3419394335 (0xcbcfd11f) 3 | # Algorithm ID: SHA256withRSA 4 | # Validity 5 | # Not Before: 13/06/2019 05:32:59 (dd-mm-yyyy hh:mm:ss) (190613053259Z) 6 | # Not After: 13/06/2020 05:32:59 (dd-mm-yyyy hh:mm:ss) (200613053259Z) 7 | # Issuer 8 | # CN = ROOT 9 | # Subject 10 | # CN = ROOT 11 | -----BEGIN CERTIFICATE----- 12 | MIICzDCCAbSgAwIBAgIEy8/RHzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARST09UMB4XDTE5MDYxMzA1MzI1OVoXDTIwMDYxMzA1MzI1OVowDzENMAsGA1UEAwwEUk9PVDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIwjmVUmTniGu0naVjrC8MEZu+jdYkY578a1aIUG8hbBkiRxpVQsllJ6txgFKTETS7lGdGCw8JF1kq2J4xoEcrxKz6hIr9Z77wk0P8sZhWU7Jh9gVLh6MPBhI4FLNfOQLTRN+e4vFeZatr2Ogx8/IIaylQ4q7xNJx4jPD5w2XnnHGE8eg8nt/mX/XkY/cWlT094XQSmddNYCGtZ999/6CogHNe0oWP+7EmDFD59cY7zI8Aa73nV/ABER7sAsUTwAOOcKtaVvx7c7npY1NZQQYShOLhGJn4OoWDQjcCwMOd8zZgVFFH2Fc4vsyv3wH9PZwa0VFYjHvygVbUESsfVeWLUCAwEAAaMwMC4wDgYDVR0PAQH/BAQDAgeAMA 13 | kGA1UdEwQCMAAwEQYDVR0lBAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQAULQfL43WXdHRPyrrTevZ5t92+1hkrREtI4P/C+P5s+dDOsRNJXGxZw1nRCSHSw3Vzwd4zkfCQ/bGUiGv2XTQS3dbAXoCNKeMdAyk1GrO5iIbD0AG1e+g411xYOlwGXyvj/Qi71xyajMz7c2hYngrSdVzLTinQRoi14+iiJe8nGsO25A8eYxMFF9VXMR1R2k06xfpiL1rIJnz75bo1pRhTsELTMN57xwwSQvA9muuZAupI1k+WwruJGyojdvwa1jcxxHbG9zGpCmp+qSHUFWIbyuHtDDgxLvbjJnAzzYY3uDR5bOJgt9vADj/c3H/7qH9YCIq7nBPdNghJpa7HstRJ 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /x509/testdata/parsecert11-ia5.pem: -------------------------------------------------------------------------------- 1 | # Issued To: CN=75320_Gracanica_Tehnièki_Izdvojeni.posta.ba, SERIALNUMBER=FCZ202492UX 2 | # Issued By: CN=75320_Gracanica_Tehnièki_Izdvojeni.posta.ba, SERIALNUMBER=FCZ202492UX 3 | # Serial Number: 02 f2 4 | # Issued On: Wed Mar 04 2020 23:17:46 GMT-0800 (Pacific Standard Time) 5 | # Expires On: Sat Mar 02 2030 23:17:46 GMT-0800 (Pacific Standard Time) 6 | # SHA-256 Fingerprint: a6 f4 0b 16 12 b3 55 46 8a 38 cb 16 0b 02 92 eb ec 0b 32 bf b4 25 d8 f0 8d 54 ea a8 67 69 eb a7 7 | # SHA-1 Fingerprint: c4 0d 57 87 5e bd e8 7e 6e 6b 15 c5 db 46 20 bb b1 1a 28 8f 8 | -----BEGIN CERTIFICATE----- 9 | MIICOTCCAcMCAgLyMA0GCSqGSIb3DQEBBQUAMIGGMTQwMgYDVQQDDCs3NTMyMF9HcmFjYW5pY2FfVGVobmnoa2lfSXpkdm9qZW5pLnBvc3RhLmJhMU4wEgYDVQQFEwtGQ1oyMDI0OTJVWDA4BgkqhkiG9w0BCQIWKzc1MzIwX0dyYWNhbmljYV9UZWhuaehraV9JemR2b2plbmkucG9zdGEuYmEwHhcNMjAwMzA1MDcxNzQ2WhcNMzAwMzAzMDcxNzQ2WjCBhjE0MDIGA1UEAwwrNzUzMjBfR3JhY2FuaWNhX1RlaG5p6GtpX0l6ZHZvamVuaS5wb3N0YS5iYTFOMBIGA1UEBRMLRkNaMjAyNDkyVVgwOAYJKoZIhvcNAQkCFis3NTMyMF9HcmFjYW5pY2FfVGVobmnoa2lfSXpkdm9qZW5pLnBvc3RhLmJhMHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALpYIcxe7z/hXLuIOXir1kYk/OWy0z5n2mwbo2VNSyEDfaMgj6MEZJiGsZYPW0yKK+41cN4+h4b+USycso+cg2Rc/eOsxIxUGnPHXSwY+WMcKgiMrqlB0vQ5Z4xiyROOewIDAQABMA0GCSqGSIb3DQEBBQUAA2EAD5NIrsXYGUVGe22CQFuqRFpiqERHYI3XcpTCGQubU9uGWErx6WdWs3cCoMJbfwQ5G43dcCFPfr0yiXNGMLc52QTGeh1b/+gbp/4lFju7rXobzDOLgotxPDMjAnjqChGS 10 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /x509/testdata/parsecert12-minlen.pem: -------------------------------------------------------------------------------- 1 | # Issued To: L=JESUS MARIA, SERIALNUMBER=20101266819, OU=CCL, O=CAMARA DE COMERCIO DE LIMA, CN=camtradeplus.com.pe, C=PE 2 | # Issued By: C=ES, OU=AC CAMERFIRMA, O=AC Camerfirma S.A., SERIALNUMBER=A82743287, L=Madrid (see current address at https://www.camerfirma.com/address), CN=Camerfirma Corporate Server II - 2015 3 | # Serial Number: 7c 1d ad e5 e7 7b 9d 41 27 4 | # Issued On: Tue Oct 02 2018 07:51:53 GMT-0700 (Pacific Daylight Time) 5 | # Expires On: Wed Oct 02 2019 07:51:53 GMT-0700 (Pacific Daylight Time) 6 | # SHA-256 Fingerprint: 43 4f 47 1d 69 b8 f8 a0 14 5b 71 44 07 0f 44 7b a6 b3 b4 5d ce ef 27 d4 9c d2 f5 d9 6b f3 6e f6 7 | # SHA-1 Fingerprint: b7 30 f9 35 89 b2 f7 b6 92 d4 ae 4c df 96 8b 81 48 3c 23 d8 8 | -----BEGIN CERTIFICATE----- 9 | MIIIUjCCBjqgAwIBAgIJfB2t5ed7nUEnMA0GCSqGSIb3DQEBCwUAMIHTMQswCQYDVQQGEwJFUzEWMBQGA1UECwwNQUMgQ0FNRVJGSVJNQTEbMBkGA1UECgwSQUMgQ2FtZXJmaXJtYSBTLkEuMRIwEAYDVQQFEwlBODI3NDMyODcxSzBJBgNVBAcMQk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCBodHRwczovL3d3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTEuMCwGA1UEAwwlQ2FtZXJmaXJtYSBDb3Jwb3JhdGUgU2VydmVyIElJIC0gMjAxNTAeFw0xODEwMDIxNDUxNTNaFw0xOTEwMDIxNDUxNTNaMIGKMRQwEgYDVQQHDAtKRVNVUyBNQVJJQTEUMBIGA1UEBRMLMjAxMDEyNjY4MTkxDDAKBgNVBAsMA0NDTDEjMCEGA1UECgwaQ0FNQVJBIERFIENPTUVSQ0lPIERFIExJTUExHDAaBgNVBAMME2NhbXRyYWRlcGx1cy5jb20ucGUxCzAJBgNVBAYTAlBFMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmY0/UaE8FDfKEZji44C6+q6NooEtr3u534VueyXUA6k/USL02wBit03CP5TmTr13rhMQ7iLrICrGsHxH8QJCpEigAixSqbk3UADh3BReb125t7LpkLh2DzoFbfWc0XkNRcaUEQqohCIOeTjzImUq+w5RIouDwACoAOs1lwvmwx/Of/sm0yuQil0Ze38VDF5OBwpD5Po6IFCffKVGv7UKBmwPJEPdxLVLBA1IIQQhmMX0u+sf2VmRvdZmdX/WBicuA9bimgACbUFp/ZB3r4cEowpO43+MzSAzYVqQej0vr0wSwW0tEw6DC3m1wh2eFD4WLqwcds8D53r9LIHwp5ckrQIDAQABo4IDbjCCA2owDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBSwXgKytjcAQ2lyzppqJNZZxyjK3TCBiwYKKwYBBAHWeQIEAgR9BIF6AHgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWY1Q7UfAAAEAwBHMEUCIQCvyE//Fgv8RNPTPSC35lFZx5dqwj+FSCYgg0Mv7b0L3AIgD/g81C4yjGv+D0/SsZIp7dyhT2zAbdbJNBTvxov7q1cwgYEGCCsGAQUFBwEBBHUwczBJBggrBgEFBQcwAoY9aHR0cDovL3d3dy5jYW1lcmZpcm1hLmNvbS9jZXJ0cy9jYW1lcmZpcm1hX2NzZXJ2ZXJpaS0yMDE1LmNydDAmBggrBgEFBQcwAYYaaHR0cDovL29jc3AuY2FtZXJmaXJtYS5jb20wgeIGA1UdIwSB2jCB14AUY+nw8FYAaGWwIWwOXNcZCJ0INGWhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiCCGIf8xxIm6E2MIGJBgNVHR8EgYEwfzA9oDugOYY3aHR0cDovL2NybC5jYW1lcmZpcm1hLmNvbS9jYW1lcmZpcm1hX2NzZXJ2ZXJpaS0yMDE1LmNybDA+oDygOoY4aHR0cDovL2NybDEuY2FtZXJmaXJtYS5jb20vY2FtZXJmaXJtYV9jc2VydmVyaWktMjAxNS5jcmwwNwYDVR0RBDAwLoIXd3d3LmNhbXRyYWRlcGx1cy5jb20ucGWCE2NhbXRyYWRlcGx1cy5jb20ucGUwUAYDVR0gBEkwRzA7BgwrBgEEAYGHLgoLAgEwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wCAYGZ4EMAQICMA0GCSqGSIb3DQEBCwUAA4ICAQCs36SOfYfOf1gR6lV6NrUT8Jb6S6+Iz6xkWeqFcYArmumDVVJSSgo7PlviSEbjMZspk5CniYYGQOobMkbpYkxypXZ7oKY1KqxP85buFWXR/2eqtQ0yL69nztjBpL8/XJxzaDSvhNtwjWeJW0FxX/LszNHZCg5KqjFSX4zyZ6cZR3prEl6O0QAz0PYBnzQYx1Zz5JWfjkd9BgIPjV7zFH1UAZzS2l+jB3dVveRJM+fcHAqbJ4vTFhMY2aNL2IZY66aFarN1B+YUY3vbwmJgc0cPls4V2WM/TOiGd+yKItVSU6wb8SJJmm8sOxTKFJMQ8twPDdaCgKZ2a14HaTvplt9mMIN9HjnUV72ANHXORuSgrqOiFTwZs7wT8dUGUcZxTw1dCN6RzlHcnW2urf76+DqLCxMeBQd7D8E74jYcZn68WiGSFHsFncLCpsV1H5idY/x+cEHckUSFo7awVviqQrmQlbOrRjd6NIEUIoWfvrQXAmOfb2ccFqFNFcpDuXghq/9WbwoF+ucuv26QmNA1hSabCAYTp77e0YXSTn72eWSESNBmp3IM9U5KkeLcemUz+CgB6Mq4fJhMM1QPp9qJx8tU84DkL43NIDIRoOpCIidZSradOV/YaMvw3c+NAH0XkQT8Y0QU221rBO7/Lk22BRSlP4rbfRVB+li4Ppjr+s+4wQ== 10 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /x509/testdata/parsecert2.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x02) 2 | # Serial number: 148871297351474 (0x008765cccbbf32) 3 | # Algorithm ID: SHA1withRSA 4 | # Validity 5 | # Not Before: 01/09/2009 16:30:45 (dd-mm-yyyy hh:mm:ss) (090901163045Z) 6 | # Not After: 12/10/2011 22:18:26 (dd-mm-yyyy hh:mm:ss) (111012221826Z) 7 | # Issuer 8 | # C = US 9 | # ST = Arizona 10 | # L = Scottsdale 11 | # O = GoDaddy.com, Inc. 12 | # OU = http:\ 13 | # /certificates.godaddy.com = undefined 14 | # repository = undefined 15 | # CN = Go Daddy Secure Certification Authority 16 | # serialNumber = 07969287 17 | # Subject 18 | # C = US 19 | # ST = PA 20 | # L = Malvern 21 | # O = Farmhaus, LLC 22 | # OU = Retail Up! 23 | # CN = www.yourshoppingnetwork.com 24 | -----BEGIN CERTIFICATE----- 25 | MIIFGjCCBAKgAwIBAgIHAIdlzMu/MjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5NjkyODcwHhcNMDkwOTAxMTYzMDQ1WhcNMTExMDEyMjIxODI2WjB/MQswCQYDVQQGEwJVUzELMAkGA1UECBMCUEExEDAOBgNVBAcTB01hbHZlcm4xFjAUBgNVBAoTDUZhcm1oYXVzLCBMTEMxEzARBgNVBAsTClJldGFpbCBVcCExJDAiBgNVBAMTG3d3dy55b3Vyc2hvcHBpbmduZXR3b3JrLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzG/+xTdR+2pO8cvTiTdxwAkvR7njxV/8uplx7RAJaPY4Xl9eLUWogfdT5EQ1CDE9RjtCrSLxAFKWUctiXa39rvgVuEfKZGJHMPoynNcj+eDkJi4L9wASX23aOjEFX5O5w85byMb4BImywZ/YY40GeRSPuripTGsTZ7pS9Y82hZcCAwEAAaOCAdEwggHNMA8GA1UdEwEB/wQFMAMBAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIFoDAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkczItMC5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcXAjA5MDcGCCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBKBggrBgEFBQcwAoY+aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkX2ludGVybWVkaWF0ZS5jcnQwHwYDVR0jBBgwFoAU/axhMpNsRdbi7oVfmrrndplozOcwPwYDVR0RBDgwNoIbd3d3LnlvdXJzaG9wcGluZ25ldHdvcmsuY29tghd5b3Vyc2hvcHBpbmduZXR3b3JrLmNvbTAdBgNVHQ4EFgQU8sk+zdzAllueNvZ003edosq/EVgwDQYJKoZIhvcNAQEFBQADggEBALwj2eD9YiMdRZOJffS9d1ybLJBmGiLWKu5sVuBnZCpSs74HWbROyNsH++aFt1WTIxR0eXGGNdiYENZTTDCo81YDDsV8yk1Q2NYAg3LaexfuuK3BQz3T6ahk9cfDqS/3KUKWgyJvDOODiXwK1UGcSGfblQiTmarH6WANCkoPcASwJCjXDhvv93G/vKX49b8EauiTDSb5Prwmg98APsQPhmkNfmw45LKzHLCGAxKPvBPpJ2qvZ0QHkvGUDfesqNLsB6k4QeBKqt/4w/oH8X8uB9TMUE7u5aNLk89lqwt7P+3xWi8wCH8dgji+gERU+pSTrSMjB3gM1GO4MqJDQ/D2tHE= 26 | -----END CERTIFICATE----- 27 | -------------------------------------------------------------------------------- /x509/testdata/parsecert3.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x02) 2 | # Serial number: 1 (0x01) 3 | # Algorithm ID: SHA1withRSA 4 | # Validity 5 | # Not Before: 27/09/2019 18:58:32 (dd-mm-yyyy hh:mm:ss) (190927185832Z) 6 | # Not After: 26/09/2021 18:58:32 (dd-mm-yyyy hh:mm:ss) (210926185832Z) 7 | # Issuer 8 | # C = CA;ST 9 | # Subject 10 | # C = CA;ST 11 | -----BEGIN CERTIFICATE----- 12 | MIICRzCCAbCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQGEzdDQTtTVD1PbnRhcmlvO0w9VG9yb250bztPPU1PRkk0NTAwMzhlY2Q1OWM7Q049TU9GSTQ1MDA7MB 13 | 4XDTE5MDkyNzE4NTgzMloXDTIxMDkyNjE4NTgzMlowQjFAMD4GA1UEBhM3Q0E7U1Q9T250YXJpbztMPVRvcm9udG87Tz1NT0ZJNDUwMDM4ZWNkNTljO0NOPU1PRkk0NTAwOzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAjHkHXCYNgHxF5NZTpx6/7gXHvL41SpmaS9PNKs3i 14 | 8JtNbHb+YS2LOdDH2UFVQf9io/h//VimsOUi+CdCodvJJVRF24hLuCqJXYJIYbhNuixaULtw9mJAFatmhUxV15sKXNdUfbgM1o5Hhk/xwJbXGhOci82n5J4kGf+qpkRKu5kCAwEAAaNNMEswCQYDVR0TBAIwADAdBgNVHQ4EFgQUJ7wQBsnIiX2Ihg2JU5asvcxq3G8wHwYDVR0jBB 15 | gwFoAUJ7wQBsnIiX2Ihg2JU5asvcxq3G8wDQYJKoZIhvcNAQEFBQADgYEALOU4RTsyLbdITqiDbhhTH4C4mY3r3JKqrQJdTFjzt/H0Au3elALKjC2rRCBUc2Ey9Tci8EZUBOVBNOpTaX/AU+rkGXCiuNU1iTAOaFi6jpVqR2elP+YIjc85FEJugcy+VDCbaAS2+xsEqd849HHrK/Ma 16 | T+5nlAhO4ENbJxM+0LY= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /x509/testdata/parsecert4-time.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x2) 2 | # Serial Number: 3 | # ec:cb:f5:ab:12:5c:df:48 4 | # Signature Algorithm: md5WithRSAEncryption 5 | # Issuer: 6 | # emailAddress = IA5STRING:patrick.bier@seidel.de 7 | # commonName = PRINTABLESTRING:Seidel GmbH WebAdmin CA 8 | # organizationName = PRINTABLESTRING:Seidel GmbH 9 | # localityName = PRINTABLESTRING:Marburg 10 | # countryName = PRINTABLESTRING:de 11 | # Validity 12 | # Not Before: Aug 20 09:06:08 2008 GMT 13 | # Not After : Jan 5 09:06:05 2036 14 | # Subject: 15 | # commonName = PRINTABLESTRING:firewall 16 | # organizationName = PRINTABLESTRING:Seidel GmbH 17 | # localityName = PRINTABLESTRING:Marburg 18 | # countryName = PRINTABLESTRING:de 19 | -----BEGIN CERTIFICATE----- 20 | MIIDTzCCArigAwIBAgIJAOzL9asSXN9IMA0GCSqGSIb3DQEBBAUAMH4xCzAJBgNV 21 | BAYTAmRlMRAwDgYDVQQHEwdNYXJidXJnMRQwEgYDVQQKEwtTZWlkZWwgR21iSDEg 22 | MB4GA1UEAxMXU2VpZGVsIEdtYkggV2ViQWRtaW4gQ0ExJTAjBgkqhkiG9w0BCQEW 23 | FnBhdHJpY2suYmllckBzZWlkZWwuZGUwIhcNMDgwODIwMDkwNjA4WhcRMzYwMTA1 24 | MDkwNjA1KzAwMDAwSDELMAkGA1UEBhMCZGUxEDAOBgNVBAcTB01hcmJ1cmcxFDAS 25 | BgNVBAoTC1NlaWRlbCBHbWJIMREwDwYDVQQDEwhmaXJld2FsbDCBnzANBgkqhkiG 26 | 9w0BAQEFAAOBjQAwgYkCgYEAs4xjWfbIHNj9hxUCXa2e8qAN+9FVyRNWhC8sD/7g 27 | PWByrApTRAgcPbNPsYFIhb6vopz3duQl0TH0ArHbBDH9VdjxWP8UFkP4QFljW2QI 28 | fQpcZLmloP+RW8lpCJiLD1qfTMQraPDdvXVFBobYxlEl6DiDrGkRBcIyvFt7XBgE 29 | 5V8CAwEAAaOCAQUwggEBMB0GA1UdDgQWBBQKj/cRWvjg3Z6iTd48cKr9sQOkXzCB 30 | sgYDVR0jBIGqMIGngBR7JcZMeKRJqIRrBdcRKFK7LOeexaGBg6SBgDB+MQswCQYD 31 | VQQGEwJkZTEQMA4GA1UEBxMHTWFyYnVyZzEUMBIGA1UEChMLU2VpZGVsIEdtYkgx 32 | IDAeBgNVBAMTF1NlaWRlbCBHbWJIIFdlYkFkbWluIENBMSUwIwYJKoZIhvcNAQkB 33 | FhZwYXRyaWNrLmJpZXJAc2VpZGVsLmRlggkA7Mv1qxJc30cwEwYDVR0RBAwwCoII 34 | ZmlyZXdhbGwwCQYDVR0TBAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEEBQAD 35 | gYEAY4680ef5sSJaNw4ugSMDynWbtyJIUIUPcBnjTCsyPAABpLb5eSnmnFlfkIrz 36 | UFXPQ8DuzRUcAKA6FVH977sSqcrY5I9v5wMiVaDkNtKMqbzbYLeGcNrZfg747u9Q 37 | oTWctPe3TpB8a87Liqmwyqqm4sp5MlRp6gnuCEzIQoBoz9c= 38 | -----END CERTIFICATE----- 39 | 40 | -------------------------------------------------------------------------------- /x509/testdata/parsecert5-printable.pem: -------------------------------------------------------------------------------- 1 | # Data: 2 | # Version: 3 (0x2) 3 | # Serial Number: 4 | # 0c:c2:5d:f3:82:c6:2a:c6:80:e5:60:c2:36:c5:05:2a:2f:88:1b:60 5 | # Signature Algorithm: sha1WithRSAEncryption 6 | # Issuer: 7 | # emailAddress = PRINTABLESTRING:support@avaya.com 8 | # commonName = PRINTABLESTRING:ipoffice-00e00706fd5e.avaya.com 9 | # organizationalUnitName = PRINTABLESTRING:GCS 10 | # organizationName = PRINTABLESTRING:Avaya Inc 11 | # localityName = PRINTABLESTRING:Basking Ridge 12 | # stateOrProvinceName = PRINTABLESTRING:New Jersey 13 | # countryName = PRINTABLESTRING:US 14 | # Validity 15 | # Not Before: Jan 31 21:09:26 2018 GMT 16 | # Not After : Jan 31 21:09:26 2025 GMT 17 | # Subject: 18 | # emailAddress = PRINTABLESTRING:support@avaya.com 19 | # commonName = PRINTABLESTRING:ipoffice-00e00706fd5e.avaya.com 20 | # organizationalUnitName = PRINTABLESTRING:GCS 21 | # organizationName = PRINTABLESTRING:Avaya Inc 22 | # localityName = PRINTABLESTRING:Basking Ridge 23 | # stateOrProvinceName = PRINTABLESTRING:New Jersey 24 | # countryName = PRINTABLESTRING:US 25 | -----BEGIN CERTIFICATE----- 26 | MIIC2TCCAkKgAwIBAgIUDMJd84LGKsaA5WDCNsUFKi+IG2AwDQYJKoZIhvcNAQEF 27 | BQAwgagxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRYwFAYDVQQH 28 | Ew1CYXNraW5nIFJpZGdlMRIwEAYDVQQKEwlBdmF5YSBJbmMxDDAKBgNVBAsTA0dD 29 | UzEoMCYGA1UEAxMfaXBvZmZpY2UtMDBlMDA3MDZmZDVlLmF2YXlhLmNvbTEgMB4G 30 | CSqGSIb3DQEJARMRc3VwcG9ydEBhdmF5YS5jb20wHhcNMTgwMTMxMjEwOTI2WhcN 31 | MjUwMTMxMjEwOTI2WjCBqDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJz 32 | ZXkxFjAUBgNVBAcTDUJhc2tpbmcgUmlkZ2UxEjAQBgNVBAoTCUF2YXlhIEluYzEM 33 | MAoGA1UECxMDR0NTMSgwJgYDVQQDEx9pcG9mZmljZS0wMGUwMDcwNmZkNWUuYXZh 34 | eWEuY29tMSAwHgYJKoZIhvcNAQkBExFzdXBwb3J0QGF2YXlhLmNvbTCBnzANBgkq 35 | hkiG9w0BAQEFAAOBjQAwgYkCgYEAh7NXpuCoPTXEKnCUtOw+x2tijGUll45WJDrz 36 | Ny4PYXU75NQMkkAJ8qrlPkkB72dYcOmpDb4PZNltKDPRO8F7ul2F6Z5FslicnXhl 37 | rKzIiCTwX3GBDQcjhZJYzN/GFsVb8oHmJkpL0ShGlnn6snSx+Db1d7jJIxYnJzPr 38 | 6j4K1zMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCEiAfPHaYsc/6WLCJCzj1V/XVb 39 | vJayw0AJZaMbvD+0ctJ3kJ3Q9mRI+BZNuCmcKKxnqe8yJyvIWkzKNfU3Q7CM0xLL 40 | rrLTMN9AxrphyLGrtO24q6G5T07ijCnzFJVSiLs8E3oXeRe4wzUSFLUNZoVBlSS1 41 | 3K1fUv8rgw5WiFeemQ== 42 | -----END CERTIFICATE----- 43 | -------------------------------------------------------------------------------- /x509/testdata/parsecert6-explicittag.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x2) 2 | # Serial Number: 3 | # 02:00:00:00:00:00:01:ba:27:c9:08:b1:78:85:1e:30 4 | # Signature Algorithm: sha256WithRSAEncryption 5 | # Issuer: 6 | # commonName = UTF8STRING:happy hacker fake CA 7 | # Validity 8 | # Not Before: Jul 13 11:44:00 2015 GMT 9 | # Not After : Oct 11 11:44:00 2015 GMT 10 | # Subject: 11 | # commonName = PRINTABLESTRING:miguillo.suroot.com 12 | # X509v3 Certificate Policies: 13 | # 0...0...g.....07..+..........0(0&..+.........http://cps.letsencrypt.org0....+..........0..0....+..........This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/documents/ 14 | -----BEGIN CERTIFICATE----- 15 | MIIE7DCCA9SgAwIBAgIQAgAAAAAAAbonyQixeIUeMDANBgkqhkiG9w0BAQsFADAf 16 | MR0wGwYDVQQDDBRoYXBweSBoYWNrZXIgZmFrZSBDQTAeFw0xNTA3MTMxMTQ0MDBa 17 | Fw0xNTEwMTExMTQ0MDBaMB4xHDAaBgNVBAMTE21pZ3VpbGxvLnN1cm9vdC5jb20w 18 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDua8On4m3gG8mOtNJ3L78u 19 | oypzJXxKRNMjsBuXExv+k94Hz02mIUDaOVoKJYt3j9O/YMOqKwGnYhYAvN5db7Pz 20 | 66/0NlWqyX3XBdRWakUhndpPu5AMxOev+wreqOfT2IckUcy4zVbbPWuqUvEECjTB 21 | ssPOasPTsxH5lHvEGk0NTcQ72rstmWYuLvopcQg4icURwEv0LzUNtorVSwDxEzVZ 22 | 65yZCX1LxsQFqA6EHGRoz9mr16pOmQpTYHUgzS3KGn9Q5peKHHU+7SL0gxs5r5Pi 23 | MyeuC6HTwbUA+OJewC5VZfXa6NmhektgPX3S3WY+X5XuWjBldXlyOb5kT4bxZBS1 24 | AgMBAAGjggIjMIICHzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH 25 | AwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFM1hElGaP6Sx65/z 26 | szAawcjAs8O7MB8GA1UdIwQYMBaAFPt4TxL5YBWDLJ8XfzQZsy426kGJMG8GCCsG 27 | AQUFBwEBBGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgxLmxldHNl 28 | bmNyeXB0Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgxLmxldHNl 29 | bmNyeXB0Lm9yZy8wHgYDVR0RBBcwFYITbWlndWlsbG8uc3Vyb290LmNvbTCCAQ0G 30 | A1UdIASCAQQwggEAMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUF 31 | BwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBugYLKwYBBAGC3xMBAQEw 32 | gaowgacGCCsGAQUFBwICFoGaVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSBy 33 | ZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3Jk 34 | YW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6 35 | Ly9sZXRzZW5jcnlwdC5vcmcvZG9jdW1lbnRzLzANBgkqhkiG9w0BAQsFAAOCAQEA 36 | mP32KVh/dc1YJ+FAqnNsseeLssHdoxfP2ZlDh6Qjw2Zch9S3K7nfYOVHVd6mg1Cw 37 | Afx3QCmfeya0iZ8P2wqJ5PnDxrKzD9rZ7VWN8touXU1ZtLMLdlatT5mhJ9D/DDRr 38 | 5Y8of6Q4XG/sewtXx/PMoB9+vBuZaZBnogxag/QgtBR9QRgrTWbOE82ONNWkV7dy 39 | us5/lUcKE/Ay3qntDvBi5rC1mAafAbagkfVN/NVnszuVwGQBHLnDpQSeGKbwwQuW 40 | TN/nFJFm9L04XC/URNHxJKD0IueqAXm83UmboOXv/TpU0lv2P0rLttE2TuD4WVoI 41 | LT036AtrsK96/xfG0an8GA== 42 | -----END CERTIFICATE----- 43 | 44 | 45 | -------------------------------------------------------------------------------- /x509/testdata/parsecert7-tagmatch.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x2) 2 | # Serial Number: 3 | # 02:00:00:00:00:00:01:ba:27:c9:08:b1:78:85:1e:30 4 | # Signature Algorithm: sha256WithRSAEncryption 5 | # Issuer: 6 | # commonName = UTF8STRING:happy hacker fake CA 7 | # Validity 8 | # Not Before: Jul 13 11:44:00 2015 GMT 9 | # Not After : Oct 11 11:44:00 2015 GMT 10 | # Subject: 11 | # commonName = PRINTABLESTRING:miguillo.suroot.com 12 | # X509v3 Certificate Policies: 13 | # 0...0...g.....07..+..........0(0&..+.........http://cps.letsencrypt.org0....+..........0..0....+..........This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/documents/ 14 | -----BEGIN CERTIFICATE----- 15 | MIIE7DCCA9SgAwIBAgIQAgAAAAAAAbonyQixeIUeMDANBgkqhkiG9w0BAQsFADAf 16 | MR0wGwYDVQQDDBRoYXBweSBoYWNrZXIgZmFrZSBDQTAeFw0xNTA3MTMxMTQ0MDBa 17 | Fw0xNTEwMTExMTQ0MDBaMB4xHDAaBgNVBAMTE21pZ3VpbGxvLnN1cm9vdC5jb20w 18 | ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDua8On4m3gG8mOtNJ3L78u 19 | oypzJXxKRNMjsBuXExv+k94Hz02mIUDaOVoKJYt3j9O/YMOqKwGnYhYAvN5db7Pz 20 | 66/0NlWqyX3XBdRWakUhndpPu5AMxOev+wreqOfT2IckUcy4zVbbPWuqUvEECjTB 21 | ssPOasPTsxH5lHvEGk0NTcQ72rstmWYuLvopcQg4icURwEv0LzUNtorVSwDxEzVZ 22 | 65yZCX1LxsQFqA6EHGRoz9mr16pOmQpTYHUgzS3KGn9Q5peKHHU+7SL0gxs5r5Pi 23 | MyeuC6HTwbUA+OJewC5VZfXa6NmhektgPX3S3WY+X5XuWjBldXlyOb5kT4bxZBS1 24 | AgMBAAGjggIjMIICHzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUH 25 | AwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFM1hElGaP6Sx65/z 26 | szAawcjAs8O7MB8GA1UdIwQYMBaAFPt4TxL5YBWDLJ8XfzQZsy426kGJMG8GCCsG 27 | AQUFBwEBBGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgxLmxldHNl 28 | bmNyeXB0Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgxLmxldHNl 29 | bmNyeXB0Lm9yZy8wHgYDVR0RBBcwFYITbWlndWlsbG8uc3Vyb290LmNvbTCCAQ0G 30 | A1UdIASCAQQwggEAMAgGBmeBDAECATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUF 31 | BwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBugYLKwYBBAGC3xMBAQEw 32 | gaowgacGCCsGAQUFBwICFoGaVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSBy 33 | ZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3Jk 34 | YW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6 35 | Ly9sZXRzZW5jcnlwdC5vcmcvZG9jdW1lbnRzLzANBgkqhkiG9w0BAQsFAAOCAQEA 36 | mP32KVh/dc1YJ+FAqnNsseeLssHdoxfP2ZlDh6Qjw2Zch9S3K7nfYOVHVd6mg1Cw 37 | Afx3QCmfeya0iZ8P2wqJ5PnDxrKzD9rZ7VWN8touXU1ZtLMLdlatT5mhJ9D/DDRr 38 | 5Y8of6Q4XG/sewtXx/PMoB9+vBuZaZBnogxag/QgtBR9QRgrTWbOE82ONNWkV7dy 39 | us5/lUcKE/Ay3qntDvBi5rC1mAafAbagkfVN/NVnszuVwGQBHLnDpQSeGKbwwQuW 40 | TN/nFJFm9L04XC/URNHxJKD0IueqAXm83UmboOXv/TpU0lv2P0rLttE2TuD4WVoI 41 | LT036AtrsK96/xfG0an8GA== 42 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /x509/testdata/parsecert8-rsapositive.pem: -------------------------------------------------------------------------------- 1 | # Version: 1 (0x0) 2 | # Serial Number: 559975137879229 (0x1fd4b5f2d24bd) 3 | # Signature Algorithm: sha1WithRSAEncryption 4 | # Issuer: 5 | # countryName = PRINTABLESTRING:USA 6 | # organizationalUnitName = PRINTABLESTRING:HID Global 7 | # organizationName = PRINTABLESTRING:HID Engineering 8 | # commonName = PRINTABLESTRING:192.168.1.198 9 | # Validity 10 | # Not Before: Aug 7 09:54:05 2020 GMT 11 | # Not After : Aug 5 09:54:05 2030 GMT 12 | # Subject: 13 | # countryName = PRINTABLESTRING:USA 14 | # organizationalUnitName = PRINTABLESTRING:HID Global 15 | # organizationName = PRINTABLESTRING:HID Engineering 16 | # commonName = PRINTABLESTRING:192.168.1.198 17 | -----BEGIN CERTIFICATE----- 18 | MIICQzCCAa4CBwH9S18tJL0wCwYJKoZIhvcNAQEFMFUxFjAUBgNVBAMTDTE5Mi4x 19 | NjguMS4xOTgxGDAWBgNVBAoTD0hJRCBFbmdpbmVlcmluZzETMBEGA1UECxMKSElE 20 | IEdsb2JhbDEMMAoGA1UEBhMDVVNBMB4XDTIwMDgwNzA5NTQwNVoXDTMwMDgwNTA5 21 | NTQwNVowVTEWMBQGA1UEAxMNMTkyLjE2OC4xLjE5ODEYMBYGA1UEChMPSElEIEVu 22 | Z2luZWVyaW5nMRMwEQYDVQQLEwpISUQgR2xvYmFsMQwwCgYDVQQGEwNVU0EwgZww 23 | CwYJKoZIhvcNAQEBA4GMADCBiAKBgMhrBLpIrs6orqdpDGhCol9XJY3b6izzKJA6 24 | iheSj+5BBlFa1D9DVJKm6pBg6BTaYfYuKbe2i34T/syU0KMeE8iWYlx6DKRRlxnP 25 | gFcwoItmPoYRuVJ6Ogo39sksoeY9Rtj6K0ywS0e+s1qwKUcmoxYBbJwp+Xoln86t 26 | 6AqJs/i9AgMBAAGjKTAnMCUGA1UdHwQeMBwwGqAYoBaGFGh0dHA6Ly9oaWRnbG9i 27 | YWwuY29tMAsGCSqGSIb3DQEBBQOBgQB8WYtFk8YvcqBvpyVj1/LgVNKP7yu6K9si 28 | JsrohFD7n4GsVRdaNLm4SvGQeefDNNYhVxYSue+S20bfo8oxd+h7o1ELn8kawL3b 29 | vcg0XXLaeyMbZ6xuJ9tnHs8rZDhFXLdNsXvHcC1+/cWccOjB86svtb485SHJvEjx 30 | 2N1FOyLuBw== 31 | -----END CERTIFICATE----- 32 | -------------------------------------------------------------------------------- /x509/testdata/parsecert9-intminlen.pem: -------------------------------------------------------------------------------- 1 | # Version: 3 (0x02) 2 | # Serial number: 4291913739 (0xffd1680b) 3 | # Algorithm ID: SHA256withRSA 4 | # Validity 5 | # Not Before: 12/12/2012 12:01:03 (dd-mm-yyyy hh:mm:ss) (121212120103Z) 6 | # Not After: 26/09/2100 12:01:04 (dd-mm-yyyy hh:mm:ss) (21000926120104Z) 7 | # Issuer 8 | # C = In 9 | # O = Huawei 10 | # OU = HTIPL 11 | # 2.5.4.46 = LSW 12 | # ST = Karnataka 13 | # CN = ROOT 14 | # Subject 15 | # C = In 16 | # O = Huawei 17 | # OU = HTIPL 18 | # 2.5.4.46 = LSW 19 | # ST = Karnataka 20 | # CN = Quidway 21 | -----BEGIN CERTIFICATE----- 22 | MIIDZDCCAkygAwIBAgIE/9FoCzANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJJbjEPMA0GA1UEChMGSHVhd2VpMQ4wDAYDVQQLEwVIVElQTDEMMAoGA1UELhMDTFNXMRIwEAYDVQQIEwlLYXJuYXRha2ExDTALBgNVBAMTBFJPT1QwIBcNMTIxMjEyMTIwMTAzWhgPMjEwMDA5MjYxMjAxMDRaMGIxCzAJBgNVBAYTAkluMQ8wDQYDVQQKEwZIdWF3ZWkxDjAMBgNVBAsTBUhUSVBMMQwwCgYDVQQuEwNMU1cxEjAQBgNVBAgTCUthcm5hdGFrYTEQMA4GA1UEAxMHUXVpZHdheTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPHPx8xWOQ7uGRD9hii6vh2BNlD7/PTKAlxl2QoN1Efw4eDUuh4MjBtdxjRfg1Ed+38G4e3F3ZKVrxn8k3nO/kZa46MK1Apl00qyfmTD8Wu/Y8F9f6ECAMyKdq6rSEiFvkM+UktcVhZ6+cPNTc9gLHLJxo3n5KxLQnfcZAsVy83hXdM6pRssN1nweINKKTVYcARVp2WtCEBf7Mk2W9njCs3/q9mLpxpvPOWNB7HjP9RvHyGs1fbHoo+vtIPpdBvpbB1DMnbsjxBsvut0ZPFA9jElZeWfIr6au8FZRnRJ5plpn7FHI3nfvH+XVzmLVERhKwDYCxMuxkAOyHJwEYMTCKcCAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgXgMA8GA1UdEwEB/wQFMAMCAQIwDQYJKoZIhvcNAQELBQADggEBAN5Pa5sY5p+gU6nY5s3V9Gp+hENNceMwYhorKL8YoJ+EksQr8pdwC7i3uMLl4pfm6NkOLl1THZt9cb4eykqwuGpOnDRKgg6J3DH2127MszxAmcLarMuq1MUJ2AxARVnIuUJCI02DHFEVZt2YQglbOEgX7dfDniENKZAMGfgTqpQRd6fdnjO0qloSheDnYiPK/lZNrivNUkOEQLQm6SH3WKuymg7JXPRuvD+Cr0hoNmCYYOJDL4WoR1wQlO3iDtZpVk50/8Q9t67iFAZUBx0dMvbBrqbTFroNjWf4deHaJ+uO7rWk2GpeYYvy0i8d2IFb2ASoB+I/DSpPPPZqn9lXsm0= 23 | -----END CERTIFICATE----- 24 | -------------------------------------------------------------------------------- /x509/testdata/qwac.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIGOTCCBSGgAwIBAgIKKsuAdWCKbJGgsjANBgkqhkiG9w0BAQsFADBLMQswCQYD 3 | VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM 4 | FEJ1eXBhc3MgQ2xhc3MgMyBDQSAyMB4XDTIwMDIwNDE0MDUwOVoXDTIyMDIwMzIy 5 | NTkwMFowgcExDTALBgNVBBEMBDAxNTAxDTALBgNVBAcMBE9TTE8xHTAbBgNVBA8M 6 | FFByaXZhdGUgT3JnYW5pemF0aW9uMRMwEQYLKwYBBAGCNzwCAQMTAk5PMQswCQYD 7 | VQQGEwJOTzERMA8GA1UECgwIVklQUFMgQVMxGzAZBgNVBAMMEnF3YWMucHJvZC52 8 | aXBwcy5ubzEcMBoGA1UEYQwTUFNETk8tRlNBLTkxODcxMzg2NzESMBAGA1UEBRMJ 9 | OTE4NzEzODY3MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApZhG4M3e 10 | j2sh+PdDZdMP6mW2w0Ulw11O6xg2NWaU4qypfggxS+HC5QM65GGyvHZh0BlVTYs1 11 | zuIQSxeylitwcoyOLpv1kZtXtvhXjGlnJJJCXOJh6g86WeWrhUxHFOQQtvtFg7Zh 12 | aYpeyldabnHcDcyxq3LVQmRL6WQwSQgEHCIlXCSI5+DCcBKr9iZYokq0kAg6jCFJ 13 | ojhUypv/rRYS2C3HBWtlWiw1Ln0BeJVEzXaCyQsmtX/TQb0W4O1YhGmvj7fC+P+m 14 | Qh4PJqwd2mU5CGjcJWLdd664TudjU8uDiR7/VgwaCbi0m8ugcJNxvZ3/yLElj95a 15 | HY6gKG+rmciIGQIDAQABo4ICpjCCAqIwCQYDVR0TBAIwADAfBgNVHSMEGDAWgBQi 16 | MC7S+/ZLysC4O9IExOly5pebDDAdBgNVHQ4EFgQUoALxp/1Knpky7+66oaOqHi7n 17 | 7sUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD 18 | AjBTBgNVHSAETDBKMDQGCGCEQgEaAQMDMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8v 19 | d3d3LmJ1eXBhc3Mubm8vY3BzMAcGBWeBDAEBMAkGBwQAi+xAAQQwOgYDVR0fBDMw 20 | MTAvoC2gK4YpaHR0cDovL2NybC5idXlwYXNzLm5vL2NybC9CUENsYXNzM0NBMi5j 21 | cmwwHQYDVR0RBBYwFIIScXdhYy5wcm9kLnZpcHBzLm5vMGoGCCsGAQUFBwEBBF4w 22 | XDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuYnV5cGFzcy5jb20wNQYIKwYBBQUH 23 | MAKGKWh0dHA6Ly9jcnQuYnV5cGFzcy5uby9jcnQvQlBDbGFzczNDQTIuY2VyMB8G 24 | BWeBDAMBBBYwFBMDUFNEEwJOTwwJOTE4NzEzODY3MIHTBggrBgEFBQcBAwSBxjCB 25 | wzAIBgYEAI5GAQEwaQYGBACBmCcCMF8wJjARBgcEAIGYJwEDDAZQU1BfQUkwEQYH 26 | BACBmCcBAgwGUFNQX1BJDC1UaGUgRmluYW5jaWFsIFN1cGVydmlzb3J5IEF1dGhv 27 | cml0eSBvZiBOb3J3YXkMBk5PLUZTQTATBgYEAI5GAQYwCQYHBACORgEGAzA3BgYE 28 | AI5GAQUwLTArFiVodHRwczovL3d3dy5idXlwYXNzLm5vL3Bkcy9wZHNfZW4ucGRm 29 | EwJlbjATBgorBgEEAdZ5AgQDAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAC6En 30 | zHU7tGVa2HUw0Y3KaRtgSkF3FNAsO63VRac/SZMykM60bM9nuwdy46/o01iQ+wi+ 31 | P/kS5r6UYIBOwLOmv6PrMuj+nV3YhADI9/A1R4MqEjKWHzVefTXUT6vWOm7JDf2n 32 | 4H3wdh/LxdfjxEn01/NcCPh+HEgatldcoXpnirVKctO2Kgg5dD2uLWtPQixr2aJQ 33 | x+4wALCBG7cwKmp0M9CLJv35+O2/1dMwhm95NfpcX6t53F7M9720fTeFTYALX1jd 34 | N2SxA7VyHqhkc0poTNtKtutRkMMWkwcDSz/FD0NMjJdsaVIJ+bdB7gh7JT1hd4CB 35 | JDKRhNRq9aSGGIcEeQ== 36 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /x509/testdata/san.test.cert: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIGNTCCBJ2gAwIBAgIJAKYaiwcTw2VCMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNV 3 | BAYTAlVTMQswCQYDVQQIEwJJTDESMBAGA1UEBxMJQ2hhbXBhaWduMQ0wCwYDVQQK 4 | EwRVSVVDMQswCQYDVQQLEwJDUzERMA8GA1UEAxMIU0FOIFRlc3QxHzAdBgkqhkiG 5 | 9w0BCQEWEHRlc3RAc2FudGVzdC5jb20wHhcNMTYwODI0MTg1NTA4WhcNMTgwODI0 6 | MTg1NTA4WjB+MQswCQYDVQQGEwJVUzELMAkGA1UECBMCSUwxEjAQBgNVBAcTCUNo 7 | YW1wYWlnbjENMAsGA1UEChMEVUlVQzELMAkGA1UECxMCQ1MxETAPBgNVBAMTCFNB 8 | TiBUZXN0MR8wHQYJKoZIhvcNAQkBFhB0ZXN0QHNhbnRlc3QuY29tMIIBojANBgkq 9 | hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzNNJPiLkZhaNcLFfuffykzP4925ggaM+ 10 | XcLoNkvvHivT4bqFKChmhTbE5J9ZGJgy2adniWEApjQHLRhRui6aO4CWkbP63iJT 11 | KJ1CyjV2tUO4ObgMsWlsOPD0ccqUdqw3QpqTgvelBIjENl+bB9yXSe+kDb64cQpi 12 | 9SaT1STVr/CTrDpDD0THdf1GFqFlKM0ioY8u2pa293rn50o9TLtIr4l6kzQaRopz 13 | fZPnJ+CWXTjGIp4YypULsbvp8LIcPIRyp/6U7j8XMhJr33DW5wOfPcKBT/aJm5PI 14 | LRwKHodQ14yNxKW0g+OizTHKdRkVHEKSwFEp4rEfsr20erx6Vyh7Fq+7IjoP/5gT 15 | bNJmWRxJ1h88xpCxETNfpqXt4x5LkTA9sXpMNTk4Bpy02k/0KNMqTO2osI5Mof5+ 16 | hxGe7CkhaB1OujmaoPMRB7+cKCIf5dv1u+0GH4k7YlOwYiev+mHzIOd04rdJG0MN 17 | /y60tEgjs7JiC75AKMldRfqHZ+ZII0NVAgMBAAGjggG0MIIBsDCBywYDVR0RBIHD 18 | MIHAgg1kbnMxLnRlc3QuY29tgg1kbnMyLnRlc3QuY29thwQBAgMEgRFlbWFpbEB0 19 | ZXN0c2FuLmNvbYYTaHR0cDovL3dhdGNoaXQuY29tL6RNMEsxCzAJBgNVBAYTAlVT 20 | MRgwFgYDVQQKEw9NeSBPcmdhbml6YXRpb24xEDAOBgNVBAsTB015IFVuaXQxEDAO 21 | BgNVBAMTB015IE5hbWWgHgYDKgMEoBcMFXNvbWUgb3RoZXIgaWRlbnRpZmllcogD 22 | KgMEMB0GA1UdDgQWBBS5cOJsqTR7n5SkNNkx0Ikc3Cc/VjCBsgYDVR0jBIGqMIGn 23 | gBS5cOJsqTR7n5SkNNkx0Ikc3Cc/VqGBg6SBgDB+MQswCQYDVQQGEwJVUzELMAkG 24 | A1UECBMCSUwxEjAQBgNVBAcTCUNoYW1wYWlnbjENMAsGA1UEChMEVUlVQzELMAkG 25 | A1UECxMCQ1MxETAPBgNVBAMTCFNBTiBUZXN0MR8wHQYJKoZIhvcNAQkBFhB0ZXN0 26 | QHNhbnRlc3QuY29tggkAphqLBxPDZUIwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B 27 | AQsFAAOCAYEAFAHBXJgYGi3MSKfj8npv+C1LlBbUdSMvqBEm4VSYIrsWHQeAabn4 28 | xiEzEs9QX3JsJD/muSo5y7VOiDOOuICPgh8ZDVJ1Rp1IFpr3HZsvLxLaKC7p/6Qc 29 | 9MOFrZR2zwLjTc4VgVJ2r1X596duXuE/we5RMfAPTrqT20CVuiblsF2vvOJLmQr9 30 | o17a0kqAVukkffUoGvHRe1FC4lO4BkJq1DiXzRSUwxXh9Mzb4aGkNzltgP3HSXPz 31 | XTAGq9YxDoV86S1ITzTHDlFQpZoCsXXG4FKhw64gKWO3mFAbM8YMp4cLzdci9TRb 32 | iJVO/ZZnNROlBfPQTLtxSri5Emj9sWCDLAW3TGfDRDCPsYZGcImhpNFtlUkt+RLh 33 | dMsQk95lcahZp9pyHd2NgjsaSsQdJ+/H3F6+7nUTiwHmF0+yUfp6I5uVoFwEM1LY 34 | PWQ+YFfDSaZqzYty9TxwIBy57w59l74+lcx4AilhpT9yam5UfknMXdfI+ZYLK+uu 35 | qqhvcEKP+hR6 36 | -----END CERTIFICATE----- 37 | -------------------------------------------------------------------------------- /x509/testdata/self-signed-invalid-sig.pem: -------------------------------------------------------------------------------- 1 | ertificate: 2 | Data: 3 | Version: 1 (0x0) 4 | Serial Number: 14998008630224366850 (0xd023a162e6c42d02) 5 | Signature Algorithm: sha256WithRSAEncryption 6 | Issuer: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS A 7 | Validity 8 | Not Before: May 27 18:37:25 2016 GMT 9 | Not After : May 25 18:37:25 2026 GMT 10 | Subject: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS A 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (2048 bit) 14 | Modulus: 15 | 00:b0:5a:83:9c:fe:1b:46:24:0b:d9:b0:0a:f2:f1: 16 | 47:bf:05:f1:68:49:6b:d2:50:f7:29:f5:f1:59:a8: 17 | 28:04:e2:7e:c9:d5:e0:86:b5:8f:2f:f9:45:a5:88: 18 | 02:04:cb:9a:c3:19:56:68:c8:eb:fe:c3:46:1a:44: 19 | be:e2:c5:e5:34:5a:18:66:1b:8e:d7:d9:19:f2:22: 20 | 43:6d:4c:28:56:25:48:42:b5:76:e5:d9:c0:86:40: 21 | f7:e7:87:0c:2d:07:e6:bd:84:9e:60:36:97:a8:d3: 22 | de:8a:37:a6:70:68:de:f1:d3:0a:db:fe:11:e8:f9: 23 | 0b:bc:56:47:d3:d4:5a:e5:ce:af:e6:d8:30:de:11: 24 | a3:7a:4d:c7:b5:0a:9c:9a:f6:4d:df:a1:46:6c:91: 25 | 03:e3:c6:be:61:38:b5:cb:1a:b5:82:6d:4d:d2:c6: 26 | 8b:32:25:b3:6d:01:d7:e7:da:2e:fe:a0:95:cf:9c: 27 | a1:e0:89:9e:2b:2b:f3:3a:98:7b:2e:b1:77:b3:88: 28 | 12:71:63:53:bf:b1:df:1e:de:da:13:e8:bd:d4:30: 29 | ec:c2:c4:e7:f9:0a:31:b2:b4:5e:36:9a:90:74:ef: 30 | 6a:45:e5:77:f3:97:8b:68:81:43:05:bc:e5:07:a6: 31 | 2f:9b:b1:c0:59:43:ac:28:bb:36:6c:98:02:72:c4: 32 | 77:3b 33 | Exponent: 65537 (0x10001) 34 | Signature Algorithm: sha256WithRSAEncryption 35 | aa:73:51:c6:c4:9b:8e:2d:a1:04:08:19:f9:c5:58:62:58:55: 36 | c8:71:9c:4b:af:01:cd:c6:34:6d:02:36:d8:34:0d:7b:6b:e6: 37 | 41:f6:eb:6c:be:a5:42:85:a9:fd:38:ee:a3:21:ba:b0:97:e6: 38 | f1:8e:2f:8e:68:ac:87:94:bb:90:8c:e5:b7:02:04:a2:75:35: 39 | df:1b:ea:51:ec:df:85:fb:9f:46:a2:03:5b:f0:02:92:72:f0: 40 | a6:d3:c7:d5:84:78:3a:c2:77:82:eb:ed:e0:59:37:c7:f6:6e: 41 | 2c:34:3a:4e:3c:7a:f2:71:92:51:81:1b:77:0b:27:67:cd:33: 42 | a6:59:a8:c8:c3:38:cd:ad:e3:48:bb:fd:e4:92:4a:e5:73:93: 43 | 15:1a:c9:fd:94:eb:11:6b:cd:45:dd:04:92:da:bb:e8:53:1d: 44 | 65:76:13:ea:a9:3a:e2:7b:f7:a6:66:f7:02:fb:d4:7a:ac:2f: 45 | 72:32:66:0e:b5:97:a0:10:d2:0e:31:fc:e5:3a:74:79:bc:cc: 46 | 97:85:31:85:f3:89:8f:f5:7a:66:53:eb:77:98:51:c3:3f:ed: 47 | 29:b7:e6:bc:30:83:b2:aa:b0:82:98:50:32:a1:4c:da:1e:6f: 48 | a8:c8:49:51:f5:6b:c4:15:18:e6:32:33:d6:31:f6:0d:62:f6: 49 | d2:db:de:ad 50 | -----BEGIN CERTIFICATE----- 51 | MIIDODCCAiACCQDQI6Fi5sQtAjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJV 52 | UzERMA8GA1UECAwITWljaGlnYW4xEjAQBgNVBAcMCUFubiBBcmJvcjEZMBcGA1UE 53 | CgwQVGVzdCBTZWxmLVNpZ25lZDENMAsGA1UEAwwEU1MgQTAeFw0xNjA1MjcxODM3 54 | MjVaFw0yNjA1MjUxODM3MjVaMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNaWNo 55 | aWdhbjESMBAGA1UEBwwJQW5uIEFyYm9yMRkwFwYDVQQKDBBUZXN0IFNlbGYtU2ln 56 | bmVkMQ0wCwYDVQQDDARTUyBBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC 57 | AQEAsFqDnP4bRiQL2bAK8vFHvwXxaElr0lD3KfXxWagoBOJ+ydXghrWPL/lFpYgC 58 | BMuawxlWaMjr/sNGGkS+4sXlNFoYZhuO19kZ8iJDbUwoViVIQrV25dnAhkD354cM 59 | LQfmvYSeYDaXqNPeijemcGje8dMK2/4R6PkLvFZH09Ra5c6v5tgw3hGjek3HtQqc 60 | mvZN36FGbJED48a+YTi1yxq1gm1N0saLMiWzbQHX59ou/qCVz5yh4ImeKyvzOph7 61 | LrF3s4gScWNTv7HfHt7aE+i91DDswsTn+QoxsrReNpqQdO9qReV385eLaIFDBbzl 62 | B6Yvm7HAWUOsKLs2bJgCcsR3OwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCqc1HG 63 | xJuOLaEECBn5xVhiWFXIcZxLrwHNxjRtAjbYNA17a+ZB9utsvqVChan9OO6jIbqw 64 | l+bxji+OaKyHlLuQjOW3AgSidTXfG+pR7N+F+59GogNb8AKScvCm08fVhHg6wneC 65 | 6+3gWTfH9m4sNDpOPHrycZJRgRt3CydnzTOmWajIwzjNreNIu/3kkkrlc5MVGsn9 66 | lOsRa81F3QSS2rvoUx1ldhPqqTrie/emZvcC+9R6rC9yMmYOtZegENIOMfzlOnR5 67 | vMyXhTGF84mP9XpmU+t3mFHDP+0pt+a8MIOyqrCCmFAyoUzaHm+oyElR9WvEFRjm 68 | MjPWMfYNYvbS296t 69 | -----END CERTIFICATE----- 70 | -------------------------------------------------------------------------------- /x509/testdata/self-signed-md5-rsa.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 0 (0x0) 5 | Signature Algorithm: md5WithRSAEncryption 6 | Issuer: C=US, ST=Michigan, L=Howell, O=Howell Public Schools, CN=admin.howellschools.com 7 | Validity 8 | Not Before: Apr 11 13:33:16 2006 GMT 9 | Not After : May 11 13:33:16 2006 GMT 10 | Subject: C=US, ST=Michigan, L=Howell, O=Howell Public Schools, CN=admin.howellschools.com 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (1024 bit) 14 | Modulus (1024 bit): 15 | 00:a6:0b:c6:19:ac:53:f0:4b:0b:21:1d:b3:73:ae: 16 | e1:d9:9b:fd:bd:64:bc:19:61:24:69:3a:3a:fa:1f: 17 | be:d1:4d:44:40:d0:5f:0e:f1:86:52:c2:36:97:0e: 18 | ed:5d:76:7d:4a:f3:82:ae:4b:0e:51:3e:4b:2b:92: 19 | 2b:08:1d:3e:2b:d1:a6:4d:d3:64:05:bc:21:bb:84: 20 | b0:e4:54:e9:bb:af:57:08:14:ef:7c:2f:49:11:21: 21 | 5e:14:a7:09:25:c6:15:a8:60:1d:22:b6:47:f3:bd: 22 | 44:c0:3c:cb:f5:7f:e2:9c:a2:b2:b5:32:fa:16:df: 23 | 53:a7:36:c2:00:cd:ec:34:c1 24 | Exponent: 65537 (0x10001) 25 | X509v3 extensions: 26 | X509v3 Subject Key Identifier: 27 | 45:03:EE:F5:28:53:78:50:61:02:BA:21:7D:81:07:1A:17:98:5C:D1 28 | X509v3 Authority Key Identifier: 29 | keyid:45:03:EE:F5:28:53:78:50:61:02:BA:21:7D:81:07:1A:17:98:5C:D1 30 | DirName:/C=US/ST=Michigan/L=Howell/O=Howell Public Schools/CN=admin.howellschools.com 31 | serial:00 32 | 33 | X509v3 Basic Constraints: 34 | CA:TRUE 35 | Signature Algorithm: md5WithRSAEncryption 36 | 8e:57:6e:55:86:e7:13:ef:a8:c4:d8:a6:d5:c1:0d:5e:65:d6: 37 | 79:de:6e:0e:d6:c8:06:be:cf:44:15:fb:1c:f3:40:91:84:6c: 38 | 02:aa:b4:4d:2d:96:24:ed:32:bf:a4:51:1d:b6:13:36:8a:8b: 39 | 02:72:b4:d4:15:1a:cc:99:ca:81:ab:1d:14:13:f9:62:f5:07: 40 | 59:55:c6:4b:89:a3:9e:2c:ef:e0:8f:f6:e5:d5:fb:9e:72:26: 41 | 9b:6f:9d:75:1c:fb:34:96:81:d9:65:6a:72:20:c7:79:93:65: 42 | f7:cb:ff:5b:7b:41:47:32:ac:ba:b9:4b:df:ae:f2:f0:6d:7d: 43 | ef:e7 44 | -----BEGIN CERTIFICATE----- 45 | MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADBzMQswCQYDVQQGEwJVUzER 46 | MA8GA1UECBMITWljaGlnYW4xDzANBgNVBAcTBkhvd2VsbDEeMBwGA1UEChMVSG93 47 | ZWxsIFB1YmxpYyBTY2hvb2xzMSAwHgYDVQQDExdhZG1pbi5ob3dlbGxzY2hvb2xz 48 | LmNvbTAeFw0wNjA0MTExMzMzMTZaFw0wNjA1MTExMzMzMTZaMHMxCzAJBgNVBAYT 49 | AlVTMREwDwYDVQQIEwhNaWNoaWdhbjEPMA0GA1UEBxMGSG93ZWxsMR4wHAYDVQQK 50 | ExVIb3dlbGwgUHVibGljIFNjaG9vbHMxIDAeBgNVBAMTF2FkbWluLmhvd2VsbHNj 51 | aG9vbHMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmC8YZrFPwSwsh 52 | HbNzruHZm/29ZLwZYSRpOjr6H77RTURA0F8O8YZSwjaXDu1ddn1K84KuSw5RPksr 53 | kisIHT4r0aZN02QFvCG7hLDkVOm7r1cIFO98L0kRIV4UpwklxhWoYB0itkfzvUTA 54 | PMv1f+KcorK1MvoW31OnNsIAzew0wQIDAQABo4HQMIHNMB0GA1UdDgQWBBRFA+71 55 | KFN4UGECuiF9gQcaF5hc0TCBnQYDVR0jBIGVMIGSgBRFA+71KFN4UGECuiF9gQca 56 | F5hc0aF3pHUwczELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1pY2hpZ2FuMQ8wDQYD 57 | VQQHEwZIb3dlbGwxHjAcBgNVBAoTFUhvd2VsbCBQdWJsaWMgU2Nob29sczEgMB4G 58 | A1UEAxMXYWRtaW4uaG93ZWxsc2Nob29scy5jb22CAQAwDAYDVR0TBAUwAwEB/zAN 59 | BgkqhkiG9w0BAQQFAAOBgQCOV25VhucT76jE2KbVwQ1eZdZ53m4O1sgGvs9EFfsc 60 | 80CRhGwCqrRNLZYk7TK/pFEdthM2iosCcrTUFRrMmcqBqx0UE/li9QdZVcZLiaOe 61 | LO/gj/bl1fueciabb511HPs0loHZZWpyIMd5k2X3y/9be0FHMqy6uUvfrvLwbX3v 62 | 5w== 63 | -----END CERTIFICATE----- 64 | -------------------------------------------------------------------------------- /x509/testdata/self-signed.pem: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 3 (0x2) 4 | Serial Number: 1 (0x1) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: CN=unittest 7 | Validity 8 | Not Before: Dec 23 02:29:48 2010 GMT 9 | Not After : Dec 24 02:29:48 2010 GMT 10 | Subject: CN=unittest 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | RSA Public Key: (1024 bit) 14 | Modulus (1024 bit): 15 | 00:d4:ac:33:4e:47:05:f0:91:ec:ba:d4:1b:5b:6b: 16 | 04:6c:c0:89:0a:13:cd:7e:79:98:65:20:ea:4c:c8: 17 | a6:b2:52:18:b8:a8:1e:6a:68:08:34:32:dd:0e:7f: 18 | b4:b0:5d:80:3f:36:4d:00:0f:37:1b:23:e8:e7:6e: 19 | 5f:32:d6:04:9a:1c:dd:f7:23:f3:8e:f5:b1:04:c0: 20 | 1b:4b:d9:cf:a2:17:46:7d:b4:8e:22:43:59:54:d8: 21 | b4:36:aa:25:bc:9d:f7:50:db:51:d4:15:b7:27:92: 22 | 4d:f5:bc:4f:30:37:38:77:73:7d:f6:46:05:73:be: 23 | 8e:67:cf:2a:55:91:a9:8b:81 24 | Exponent: 65537 (0x10001) 25 | Signature Algorithm: sha1WithRSAEncryption 26 | 1b:b9:b6:80:b3:70:ae:b3:2a:f8:99:7b:e5:23:e4:45:51:50: 27 | cc:03:cb:0c:02:03:b1:5a:75:6e:c9:9a:00:95:b7:ac:90:f5: 28 | 85:e0:92:a6:5e:96:4d:1a:a1:d2:99:b3:e7:92:58:7b:b2:c7: 29 | 41:0a:56:e6:73:68:88:88:d9:bf:cf:2a:77:c6:54:8b:c0:bb: 30 | 94:af:cd:da:9c:f2:69:70:13:2e:1c:05:8a:15:16:71:4e:20: 31 | cc:cd:f7:7a:7d:b9:41:11:63:ca:35:7c:12:90:13:62:e1:46: 32 | fd:ef:f3:a3:d8:7b:3e:44:23:bc:5b:51:cf:f9:6a:2f:bd:2e: 33 | 45:de 34 | -----BEGIN CERTIFICATE----- 35 | MIIBmjCCAQOgAwIBAgIBATANBgkqhkiG9w0BAQUFADATMREwDwYDVQQDEwh1bml0 36 | dGVzdDAeFw0xMDEyMjMwMjI5NDhaFw0xMDEyMjQwMjI5NDhaMBMxETAPBgNVBAMT 37 | CHVuaXR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUrDNORwXwkey6 38 | 1BtbawRswIkKE81+eZhlIOpMyKayUhi4qB5qaAg0Mt0Of7SwXYA/Nk0ADzcbI+jn 39 | bl8y1gSaHN33I/OO9bEEwBtL2c+iF0Z9tI4iQ1lU2LQ2qiW8nfdQ21HUFbcnkk31 40 | vE8wNzh3c332RgVzvo5nzypVkamLgQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABu5 41 | toCzcK6zKviZe+Uj5EVRUMwDywwCA7FadW7JmgCVt6yQ9YXgkqZelk0aodKZs+eS 42 | WHuyx0EKVuZzaIiI2b/PKnfGVIvAu5Svzdqc8mlwEy4cBYoVFnFOIMzN93p9uUER 43 | Y8o1fBKQE2LhRv3v86PYez5EI7xbUc/5ai+9LkXe 44 | -----END CERTIFICATE----- 45 | -------------------------------------------------------------------------------- /x509/validation.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package x509 6 | 7 | import "time" 8 | 9 | // Validation stores different validation levels for a given certificate 10 | type Validation struct { 11 | BrowserTrusted bool `json:"browser_trusted"` 12 | BrowserError string `json:"browser_error,omitempty"` 13 | MatchesDomain bool `json:"matches_domain,omitempty"` 14 | Domain string `json:"-"` 15 | } 16 | 17 | // ValidateWithStupidDetail fills out a Validation struct given a leaf 18 | // certificate and intermediates / roots. If opts.DNSName is set, then it will 19 | // also check if the domain matches. 20 | // 21 | // Deprecated: Use verifier.Verify() instead. 22 | func (c *Certificate) ValidateWithStupidDetail(opts VerifyOptions) (chains []CertificateChain, validation *Validation, err error) { 23 | 24 | // Manually set the time, so that all verifies we do get the same time 25 | if opts.CurrentTime.IsZero() { 26 | opts.CurrentTime = time.Now() 27 | } 28 | 29 | // XXX: Don't pass a KeyUsage to the Verify API 30 | opts.KeyUsages = nil 31 | domain := opts.DNSName 32 | opts.DNSName = "" 33 | 34 | out := new(Validation) 35 | out.Domain = domain 36 | 37 | if chains, _, _, err = c.Verify(opts); err != nil { 38 | out.BrowserError = err.Error() 39 | } else { 40 | out.BrowserTrusted = true 41 | } 42 | 43 | if domain != "" { 44 | nameErr := c.VerifyHostname(domain) 45 | if nameErr != nil { 46 | out.MatchesDomain = false 47 | } else { 48 | out.MatchesDomain = true 49 | } 50 | 51 | // Make sure we return an error if either chain building or hostname 52 | // verification fails. 53 | if err == nil && nameErr != nil { 54 | err = nameErr 55 | } 56 | } 57 | validation = out 58 | 59 | return 60 | } 61 | -------------------------------------------------------------------------------- /x509/x509_test_import.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build ignore 6 | // +build ignore 7 | 8 | // This file is run by the x509 tests to ensure that a program with minimal 9 | // imports can sign certificates without errors resulting from missing hash 10 | // functions. 11 | package main 12 | 13 | import ( 14 | "crypto/rand" 15 | "encoding/pem" 16 | "math/big" 17 | "time" 18 | 19 | "github.com/zmap/zcrypto/x509" 20 | "github.com/zmap/zcrypto/x509/pkix" 21 | ) 22 | 23 | func main() { 24 | block, _ := pem.Decode([]byte(pemPrivateKey)) 25 | rsaPriv, err := x509.ParsePKCS1PrivateKey(block.Bytes) 26 | if err != nil { 27 | panic("Failed to parse private key: " + err.Error()) 28 | } 29 | 30 | template := x509.Certificate{ 31 | SerialNumber: big.NewInt(1), 32 | Subject: pkix.Name{ 33 | CommonName: "test", 34 | Organization: []string{"Σ Acme Co"}, 35 | }, 36 | NotBefore: time.Unix(1000, 0), 37 | NotAfter: time.Unix(100000, 0), 38 | KeyUsage: x509.KeyUsageCertSign, 39 | } 40 | 41 | if _, err = x509.CreateCertificate(rand.Reader, &template, &template, &rsaPriv.PublicKey, rsaPriv); err != nil { 42 | panic("failed to create certificate with basic imports: " + err.Error()) 43 | } 44 | } 45 | 46 | var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY----- 47 | MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0 48 | fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu 49 | /ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu 50 | RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/ 51 | EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A 52 | IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS 53 | tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V 54 | -----END RSA PRIVATE KEY----- 55 | ` 56 | -------------------------------------------------------------------------------- /x509/zintermediate/.gitignore: -------------------------------------------------------------------------------- 1 | zintermediate 2 | -------------------------------------------------------------------------------- /zcrypto_schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmap/zcrypto/7510c141e4b73eb4b9f666f445f7a7412b8cdce6/zcrypto_schemas/__init__.py --------------------------------------------------------------------------------