From d80d3014475841c8176b0c2b834cd396c76c4c99 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Fri, 17 Apr 2015 11:42:38 -0400 Subject: [PATCH] Update latest CFSSL to pick up OCSP config. --- Godeps/Godeps.json | 60 +- .../github.com/cloudflare/cfssl/api/api.go | 24 +- .../cloudflare/cfssl/api/api_test.go | 4 +- .../cloudflare/cfssl/api/bundle/bundle.go | 5 +- .../cloudflare/cfssl/api/client/api.go | 11 - .../cloudflare/cfssl/api/client/client.go | 54 +- .../cfssl/api/generator/generator.go | 21 +- .../cloudflare/cfssl/api/info/info.go | 26 +- .../cloudflare/cfssl/api/initca/initca.go | 5 +- .../cloudflare/cfssl/api/scan/scan.go | 7 +- .../cloudflare/cfssl/api/sign/sign.go | 34 +- .../cloudflare/cfssl/api/sign/sign_test.go | 8 +- .../cfssl/bundler/bundle_from_file_test.go | 35 +- .../cfssl/bundler/bundle_from_pem_test.go | 6 +- .../cloudflare/cfssl/bundler/bundler.go | 75 +- .../bundler/bundler_sha1_deprecation_test.go | 202 +- .../cloudflare/cfssl/bundler/bundler_test.go | 392 ++-- ...3d4_021c8d95a0308df09c0000000000611515.crt | 29 + ...63d96_5b25ce6907c4265566d3390c99a954ad.crt | 22 + ...9723b_04e1e7a4dc5cf2f36dc02b42b85d159f.crt | 28 + ...4853f723c307d23da85789ba37c5a7c_023a6f.crt | 26 + ...bbcf668b576f581b6bb621aba5a812f_023a76.crt | 24 + ...bd5ef7751c25b14ba203f_5bc0b8bee6f8e914.crt | 26 + .../cfssl/bundler/testdata/bunnings.pem | 75 - .../cfssl/bundler/testdata/ca.pem.metadata | 42 - .../testdata/cfssl-leaf-ecdsa256-v2.pem | 20 - .../testdata/cfssl-leaf-ecdsa384-v2.pem | 21 - .../testdata/cfssl-leaf-ecdsa521-v2.pem | 22 - .../cfssl/bundler/testdata/draftkings.pem | 30 - .../cfssl/bundler/testdata/firstdata.pem | 94 - .../cfssl/bundler/testdata/inter-L1-v2.csr | 10 - .../cfssl/bundler/testdata/inter-L1-v2.key | 5 - .../cfssl/bundler/testdata/inter-L1-v2.pem | 17 - .../cfssl/bundler/testdata/inter-L2-1.pem | 26 - .../cfssl/bundler/testdata/inter-L2-2.pem | 26 - .../cfssl/bundler/testdata/inter-L2-3.pem | 26 - .../cfssl/bundler/testdata/inter-L2-4.pem | 26 - .../cfssl/bundler/testdata/inter-L2-v2.csr | 19 - .../cfssl/bundler/testdata/inter-L2-v2.key | 27 - .../cfssl/bundler/testdata/inter-L2-v2.pem | 20 - .../cfssl/bundler/testdata/lazada.pem | 30 - .../cfssl/bundler/testdata/riot.pem | 45 - .../cfssl/bundler/testdata/sgizmo.pem | 30 - .../cloudflare/cfssl/cli/bundle/bundle.go | 16 +- .../github.com/cloudflare/cfssl/cli/cli.go | 10 +- .../cloudflare/cfssl/cli/cli_test.go | 5 + .../github.com/cloudflare/cfssl/cli/config.go | 8 + .../cloudflare/cfssl/cli/gencert/gencert.go | 3 +- .../cloudflare/cfssl/cli/genkey/genkey.go | 7 +- .../cfssl/cli/genkey/genkey_test.go | 49 + .../cloudflare/cfssl/cli/info/info.go | 103 + .../cfssl/cli/ocspserve/oscpserve.go | 52 + .../cloudflare/cfssl/cli/ocspsign/ocspsign.go | 5 +- .../cloudflare/cfssl/cli/scan/scan.go | 5 +- .../cloudflare/cfssl/cli/selfsign/selfsign.go | 1 + .../cloudflare/cfssl/cli/serve/serve.go | 14 +- .../cloudflare/cfssl/cli/serve/static.go | 201 ++ .../cfssl/cli/serve/static/index.html | 38 + .../cfssl/cli/serve/static/scan.html | 106 + .../cloudflare/cfssl/cli/sign/sign.go | 5 +- .../cloudflare/cfssl/cli/version/version.go | 1 + .../cloudflare/cfssl/cmd/cfssl/cfssl.go | 24 +- .../cloudflare/cfssl/config/config.go | 4 +- .../cfssl/crypto/pkcs11key/pkcs11key.go | 235 ++ .../cfssl/crypto/pkcs11key/pkcs11key_stub.go | 6 + .../cloudflare/cfssl/crypto/pkcs12/crypto.go | 114 + .../cfssl/crypto/pkcs12/pbkdf/pbkdf.go | 201 ++ .../cloudflare/cfssl/crypto/pkcs12/pkcs12.go | 222 ++ .../cloudflare/cfssl/crypto/pkcs7/pkcs7.go | 130 +- .../github.com/cloudflare/cfssl/csr/csr.go | 31 +- .../cloudflare/cfssl/csr/csr_test.go | 68 +- .../cloudflare/cfssl/errors/error.go | 38 +- .../cloudflare/cfssl/errors/error_test.go | 25 + .../cfssl/helpers/derhelpers/derhelpers.go | 42 + .../cloudflare/cfssl/helpers/helpers.go | 78 +- .../cloudflare/cfssl/helpers/helpers_test.go | 54 +- .../cfssl/helpers/testdata/cert.der | Bin 0 -> 498 bytes .../helpers/testdata/emptypasswordpkcs12.p12 | Bin 0 -> 2557 bytes .../cfssl/helpers/testdata/multiplecerts.p12 | Bin 0 -> 3101 bytes .../cfssl/helpers/testdata/passwordpkcs12.p12 | Bin 0 -> 2557 bytes .../github.com/cloudflare/cfssl/info/info.go | 15 + .../cloudflare/cfssl/initca/initca.go | 32 +- .../cloudflare/cfssl/initca/initca_test.go | 66 +- .../cloudflare/cfssl/ocsp/config/config.go | 28 + .../cloudflare/cfssl/ocsp/ocsp_test.go | 151 ++ .../cloudflare/cfssl/ocsp/pkcs11/pkcs11.go | 42 + .../cfssl/ocsp/pkcs11/pkcs11_stub.go | 17 + .../cloudflare/cfssl/ocsp/testdata/ca-key.pem | 27 + .../cloudflare/cfssl/ocsp/testdata/ca.pem | 23 + .../cloudflare/cfssl/ocsp/testdata/cert.pem | 23 + .../cloudflare/cfssl/ocsp/testdata/resp64.pem | 1 + .../cfssl/ocsp/testdata/response.pem | Bin 0 -> 540 bytes .../cfssl/ocsp/testdata/response_broken.pem | 1 + .../cfssl/ocsp/testdata/response_mix.pem | Bin 0 -> 1260 bytes .../cloudflare/cfssl/ocsp/testdata/server.crt | 13 + .../cloudflare/cfssl/ocsp/testdata/server.key | 15 + .../cfssl/ocsp/testdata/server_broken.crt | 9 + .../cfssl/ocsp/testdata/server_broken.key | 8 + .../cfssl/ocsp/universal/universal.go | 16 + .../cloudflare/cfssl/revoke/revoke.go | 281 +++ .../cloudflare/cfssl/revoke/revoke_test.go | 223 ++ .../github.com/cloudflare/cfssl/scan/broad.go | 84 + .../github.com/cloudflare/cfssl/scan/pki.go | 184 +- .../cloudflare/cfssl/scan/scan_common.go | 61 +- .../cloudflare/cfssl/scan/scan_common_test.go | 28 +- .../cloudflare/cfssl/scan/tls_handshake.go | 14 +- .../cloudflare/cfssl/scan/tls_session.go | 42 +- .../cloudflare/cfssl/selfsign/selfsign.go | 8 +- .../cloudflare/cfssl/signer/local/local.go | 36 +- .../cloudflare/cfssl/signer/pkcs11/pkcs11.go | 2 +- .../cloudflare/cfssl/signer/remote/remote.go | 64 +- .../cfssl/signer/remote/remote_test.go | 16 +- .../cloudflare/cfssl/signer/signer.go | 27 +- .../cfssl/signer/universal/universal_test.go | 41 + .../cloudflare/cfssl/ubiquity/filter.go | 2 +- .../cloudflare/cfssl/ubiquity/sha1.go | 153 ++ .../cfssl/ubiquity/testdata/ca.pem.metadata | 15 + .../cfssl/ubiquity/ubiquity_platform.go | 63 +- .../cfssl/ubiquity/ubiquity_test.go | 331 ++- .../src/github.com/dgryski/go-rc2/LICENSE | 21 + .../github.com/dgryski/go-rc2/bench_test.go | 40 + .../src/github.com/dgryski/go-rc2/rc2.go | 270 +++ .../src/github.com/dgryski/go-rc2/rc2_test.go | 89 + .../src/github.com/miekg/pkcs11/.gitignore | 1 + .../src/github.com/miekg/pkcs11/LICENSE | 27 + .../src/github.com/miekg/pkcs11/README.md | 48 + .../src/github.com/miekg/pkcs11/const.go | 561 +++++ .../src/github.com/miekg/pkcs11/error.go | 98 + .../src/github.com/miekg/pkcs11/hsm.db | Bin 0 -> 10240 bytes .../src/github.com/miekg/pkcs11/pkcs11.go | 1551 ++++++++++++++ .../src/github.com/miekg/pkcs11/pkcs11.h | 299 +++ .../github.com/miekg/pkcs11/pkcs11_test.go | 242 +++ .../src/github.com/miekg/pkcs11/pkcs11f.h | 910 ++++++++ .../src/github.com/miekg/pkcs11/pkcs11t.h | 1885 +++++++++++++++++ .../src/github.com/miekg/pkcs11/softhsm.conf | 1 + .../src/github.com/miekg/pkcs11/types.go | 274 +++ README.md | 18 +- 137 files changed, 10674 insertions(+), 1459 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/CADisigI1CertificationService_cb619f69c2d820b4bc23e4d4339f06a96d6373d4_021c8d95a0308df09c0000000000611515.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/COMODOECCDomainValidationSecureServerCA2_40096167f0bc83714fde12082c6fd4d42b763d96_5b25ce6907c4265566d3390c99a954ad.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/DigiCertSHA2HighAssuranceServerCA_5168ff90af0207753cccd9656462a212b859723b_04e1e7a4dc5cf2f36dc02b42b85d159f.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GeoTrustSSLCA-G3_d26ff796f4853f723c307d23da85789ba37c5a7c_023a6f.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GoogleInternetAuthorityG2_4add06161bbcf668b576f581b6bb621aba5a812f_023a76.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/cloudflare-intercom_8860ba18a477b841041bd5ef7751c25b14ba203f_5bc0b8bee6f8e914.crt delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/bunnings.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/ca.pem.metadata delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa256-v2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa384-v2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa521-v2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/draftkings.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/firstdata.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.csr delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.key delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-1.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-3.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-4.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.csr delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.key delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/lazada.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/riot.pem delete mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/sgizmo.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/info/info.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspserve/oscpserve.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/index.html create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/scan.html create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key_stub.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/crypto.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf/pbkdf.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pkcs12.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/cert.der create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/emptypasswordpkcs12.p12 create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/multiplecerts.p12 create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/passwordpkcs12.p12 create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/info/info.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config/config.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/ocsp_test.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11_stub.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_mix.pem create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.key create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/universal/universal.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke_test.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/broad.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/sha1.go create mode 100644 Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/testdata/ca.pem.metadata create mode 100644 Godeps/_workspace/src/github.com/dgryski/go-rc2/LICENSE create mode 100644 Godeps/_workspace/src/github.com/dgryski/go-rc2/bench_test.go create mode 100644 Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2.go create mode 100644 Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2_test.go create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/.gitignore create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/LICENSE create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/README.md create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/const.go create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/error.go create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/hsm.db create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11.go create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11.h create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11_test.go create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11f.h create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11t.h create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/softhsm.conf create mode 100644 Godeps/_workspace/src/github.com/miekg/pkcs11/types.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 4368f1e2c4a..9edab3288e7 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "github.com/letsencrypt/boulder", - "GoVersion": "go1.4.1", + "GoVersion": "go1.4.2", "Packages": [ "./..." ], @@ -16,77 +16,97 @@ }, { "ImportPath": "github.com/cloudflare/cfssl/api", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/auth", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/bundler", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/cli", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/cmd/cfssl", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/config", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" + }, + { + "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs11key", + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" + }, + { + "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs12", + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/crypto/pkcs7", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/csr", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/errors", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/helpers", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" + }, + { + "ImportPath": "github.com/cloudflare/cfssl/info", + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/initca", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/log", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/ocsp", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" + }, + { + "ImportPath": "github.com/cloudflare/cfssl/revoke", + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/scan", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/selfsign", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/signer", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/cloudflare/cfssl/ubiquity", - "Rev": "e2aa27ef15c4f9c13bb2202ebfedbc90454dd947" + "Rev": "39ec5f93190f042ddf337955d4df679b0305c9df" }, { "ImportPath": "github.com/codegangsta/cli", "Comment": "1.2.0-64-ge1712f3", "Rev": "e1712f381785e32046927f64a7c86fe569203196" }, + { + "ImportPath": "github.com/dgryski/go-rc2", + "Rev": "fd90a5fcd260ebe709a689d0bdca2043afffabfa" + }, { "ImportPath": "github.com/go-sql-driver/mysql", "Comment": "v1.2-88-ga197e5d", @@ -96,6 +116,10 @@ "ImportPath": "github.com/mattn/go-sqlite3", "Rev": "308067797b0fcce4ca06362580dc6db77c1bfeda" }, + { + "ImportPath": "github.com/miekg/pkcs11", + "Rev": "88c9f842544e629ec046105d7fb50d5daafae737" + }, { "ImportPath": "github.com/square/go-jose", "Rev": "d3ba9be3fbf631c353e477ab8fba8ec04f05a8b4" diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api.go index 9d123e5fa18..267cbb4f1e5 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api.go @@ -1,4 +1,4 @@ -// Package api implements an HTTP-based API and server for CF-SSL. +// Package api implements an HTTP-based API and server for CFSSL. package api import ( @@ -16,10 +16,10 @@ type Handler interface { } // HTTPHandler is a wrapper that encapsulates Handler interface as http.Handler. -// HttpHandler also enforces that the Handler only responds to requests with registered HTTP method. +// HTTPHandler also enforces that the Handler only responds to requests with registered HTTP methods. type HTTPHandler struct { - Handler // CFSSL handler - Method string // The assoicated HTTP method + Handler // CFSSL handler + Methods []string // The associated HTTP methods } // HandlerFunc is similar to the http.HandlerFunc type; it serves as @@ -41,9 +41,9 @@ func handleError(w http.ResponseWriter, err error) (code int) { msg := err.Error() httpCode := http.StatusInternalServerError - // If it is recognized as HttpError emitted from cf-ssl, + // If it is recognized as HttpError emitted from cfssl, // we rewrite the status code accordingly. If it is a - // cf-ssl error, set the http status to StatusBadRequest + // cfssl error, set the http status to StatusBadRequest switch err := err.(type) { case *errors.HTTPError: httpCode = err.StatusCode @@ -69,11 +69,17 @@ func handleError(w http.ResponseWriter, err error) (code int) { // and return the response with proper HTTP status code func (h HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { var err error + var match bool // Throw 405 when requested with an unsupported verb. - if r.Method != h.Method { - err = errors.NewMethodNotAllowed(r.Method) - } else { + for _, m := range h.Methods { + if m == r.Method { + match = true + } + } + if match { err = h.Handle(w, r) + } else { + err = errors.NewMethodNotAllowed(r.Method) } status := handleError(w, err) log.Infof("%s - \"%s %s\" %d", r.RemoteAddr, r.Method, r.URL, status) diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api_test.go index fe82f726160..78ebb77d30f 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/api_test.go @@ -73,7 +73,7 @@ func get(t *testing.T, ts *httptest.Server) (resp *http.Response, body []byte) { } func TestRigidHandle(t *testing.T) { - ts := httptest.NewServer(HTTPHandler{Handler: HandlerFunc(simpleHandle), Method: "POST"}) + ts := httptest.NewServer(HTTPHandler{Handler: HandlerFunc(simpleHandle), Methods: []string{"POST"}}) defer ts.Close() // Response to compliment @@ -143,7 +143,7 @@ func TestRigidHandle(t *testing.T) { } func TestCleverHandle(t *testing.T) { - ts := httptest.NewServer(HTTPHandler{Handler: HandlerFunc(cleverHandle), Method: "POST"}) + ts := httptest.NewServer(HTTPHandler{Handler: HandlerFunc(cleverHandle), Methods: []string{"POST"}}) defer ts.Close() // Response ty to compliment diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/bundle/bundle.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/bundle/bundle.go index b90f2f63f45..15702847984 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/bundle/bundle.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/bundle/bundle.go @@ -1,3 +1,4 @@ +// Package bundle implements the HTTP handler for the bundle command. package bundle import ( @@ -27,7 +28,7 @@ func NewHandler(caBundleFile, intBundleFile string) (http.Handler, error) { } log.Info("bundler API ready") - return api.HTTPHandler{Handler: b, Method: "POST"}, nil + return api.HTTPHandler{Handler: b, Methods: []string{"POST"}}, nil } // Handle implements an http.Handler interface for the bundle handler. @@ -59,7 +60,7 @@ func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error { } result = bundle case "certificate": - bundle, err := h.bundler.BundleFromPEM([]byte(blob["certificate"]), []byte(blob["private_key"]), bf) + bundle, err := h.bundler.BundleFromPEMorDER([]byte(blob["certificate"]), []byte(blob["private_key"]), bf, "") if err != nil { log.Warning("bad PEM certifcate or private key") return err diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/api.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/api.go index 6e624fc1a95..22abf87774e 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/api.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/api.go @@ -4,14 +4,3 @@ package client type SignResult struct { Certificate []byte `json:"certificate"` } - -// InfoReq is the request struct for an info API request. -type InfoReq struct { - Label string `json:"label"` - Profile string `json:"profile"` -} - -// InfoResp is the response for an Info API request. -type InfoResp struct { - Certificate string `json:"certificate"` -} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/client.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/client.go index 9a0df32284e..3565dbc95af 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/client.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client/client.go @@ -1,3 +1,4 @@ +// Package client implements the a Go client for CFSSL API commands. package client import ( @@ -14,10 +15,11 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/auth" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" ) -type // A Server points to a remote CFSSL instance. -Server struct { +// A Server points to a remote CFSSL instance. +type Server struct { Address string Port int } @@ -145,22 +147,56 @@ func (srv *Server) Sign(jsonData []byte) ([]byte, error) { } // Info sends an info request to the remote CFSSL server, receiving a -// certificate or an error in response. +// response or an error in response. // It takes the serialized JSON request to send. -func (srv *Server) Info(jsonData []byte) ([]byte, error) { - return srv.Req(jsonData, "info") +func (srv *Server) Info(jsonData []byte) (*info.Resp, error) { + res, err := srv.getResultMap(jsonData, "info") + if err != nil { + return nil, err + } + + info := new(info.Resp) + + if val, ok := res["certificate"]; ok { + info.Certificate = val.(string) + } + var usages []interface{} + if val, ok := res["usages"]; ok { + usages = val.([]interface{}) + } + if val, ok := res["expiry"]; ok { + info.ExpiryString = val.(string) + } + + info.Usage = make([]string, len(usages)) + for i, s := range usages { + info.Usage[i] = s.(string) + } + + return info, nil +} + +func (srv *Server) getResultMap(jsonData []byte, target string) (result map[string]interface{}, err error) { + url := srv.getURL(target) + response, err := srv.post(url, jsonData) + if err != nil { + return + } + result, ok := response.Result.(map[string]interface{}) + if !ok { + err = errors.Wrap(errors.APIClientError, errors.ClientHTTPError, stderr.New("response is formatted improperly")) + return + } + return } // Req performs the common logic for Sign and Info, performing the actual // request and returning the resultant certificate. func (srv *Server) Req(jsonData []byte, target string) ([]byte, error) { - url := srv.getURL(target) - - response, err := srv.post(url, jsonData) + result, err := srv.getResultMap(jsonData, target) if err != nil { return nil, err } - result := response.Result.(map[string]interface{}) cert := result["certificate"].(string) if cert != "" { return []byte(cert), nil diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/generator/generator.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/generator/generator.go index b07f7d47fbd..0cbc3547845 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/generator/generator.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/generator/generator.go @@ -1,3 +1,4 @@ +// Package generator implements the HTTP handlers for certificate generation. package generator import ( @@ -51,7 +52,7 @@ func NewHandler(validator Validator) (http.Handler, error) { Handler: &Handler{ generator: &csr.Generator{Validator: validator}, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } @@ -176,7 +177,7 @@ func NewCertGeneratorHandler(validator Validator, caFile, caKeyFile string, poli cg.generator = &csr.Generator{Validator: validator} - return api.HTTPHandler{Handler: cg, Method: "POST"}, nil + return api.HTTPHandler{Handler: cg, Methods: []string{"POST"}}, nil } // NewCertGeneratorHandlerFromSigner returns a handler directly from @@ -187,7 +188,7 @@ func NewCertGeneratorHandlerFromSigner(validator Validator, signer signer.Signer generator: &csr.Generator{Validator: validator}, signer: signer, }, - Method: "POST", + Methods: []string{"POST"}, } } @@ -234,18 +235,6 @@ func (cg *CertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) e return err } - var certPEM []byte - - var profile *config.SigningProfile - policy := cg.signer.Policy() - if policy != nil && policy.Profiles != nil && req.Profile != "" { - profile = policy.Profiles[req.Profile] - } - - if profile == nil && policy != nil { - profile = policy.Default - } - // This API does not override the subject because it was already added to the CSR signReq := signer.SignRequest{ Hosts: signer.SplitHosts(req.Hostname), @@ -273,7 +262,7 @@ func (cg *CertGeneratorHandler) Handle(w http.ResponseWriter, r *http.Request) e result := map[string]interface{}{ "private_key": string(key), "certificate_request": string(csr), - "certificate": string(certPEM), + "certificate": string(certBytes), "sums": map[string]Sum{ "certificate_request": reqSum, "certificate": certSum, diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info/info.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info/info.go index 6fb1a9c3fa8..8caec52ad09 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info/info.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info/info.go @@ -1,15 +1,14 @@ +// Package info implements the HTTP handler for the info command. package info import ( "encoding/json" - "encoding/pem" "io/ioutil" "net/http" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer" ) @@ -27,14 +26,14 @@ func NewHandler(s signer.Signer) (http.Handler, error) { Handler: &Handler{ sign: s, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } // Handle listens for incoming requests for CA information, and returns // a list containing information on each root certificate. func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error { - req := new(client.InfoReq) + req := new(info.Req) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) @@ -46,13 +45,10 @@ func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error { return errors.NewBadRequest(err) } - cert, err := h.sign.Certificate(req.Label, req.Profile) + resp, err := h.sign.Info(*req) if err != nil { return err } - resp := client.InfoResp{ - Certificate: bundler.PemBlockToString(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}), - } response := api.NewSuccessResponse(resp) w.Header().Set("Content-Type", "application/json") @@ -77,7 +73,7 @@ func NewMultiHandler(signers map[string]signer.Signer, defaultLabel string) (htt signers: signers, defaultLabel: defaultLabel, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } @@ -85,7 +81,7 @@ func NewMultiHandler(signers map[string]signer.Signer, defaultLabel string) (htt // look up the signer whose public certificate should be retrieved. If // the label is empty, the default label is used. func (h *MultiHandler) Handle(w http.ResponseWriter, r *http.Request) error { - req := new(client.InfoReq) + req := new(info.Req) body, err := ioutil.ReadAll(r.Body) if err != nil { log.Warningf("failed to read request body: %v", err) @@ -107,17 +103,13 @@ func (h *MultiHandler) Handle(w http.ResponseWriter, r *http.Request) error { return errors.NewBadRequestString("bad label") } - log.Debug("getting cert") - cert, err := h.signers[req.Label].Certificate("", req.Profile) + log.Debug("getting info") + resp, err := h.signers[req.Label].Info(*req) if err != nil { log.Infof("error getting certificate: %v", err) return err } - resp := client.InfoResp{ - Certificate: bundler.PemBlockToString(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}), - } - response := api.NewSuccessResponse(resp) w.Header().Set("Content-Type", "application/json") enc := json.NewEncoder(w) diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/initca/initca.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/initca/initca.go index 56918a28e43..c51c0e092fc 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/initca/initca.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/initca/initca.go @@ -1,3 +1,4 @@ +// Package initca implements the HTTP handler for the CA initialization command package initca import ( @@ -38,7 +39,7 @@ func initialCAHandler(w http.ResponseWriter, r *http.Request) error { return errors.NewBadRequest(err) } - key, cert, err := initca.New(req) + key, _, cert, err := initca.New(req) if err != nil { log.Warningf("failed to initialise new CA: %v", err) return err @@ -54,5 +55,5 @@ func initialCAHandler(w http.ResponseWriter, r *http.Request) error { // NewHandler returns a new http.Handler that handles request to // initialize a CA. func NewHandler() http.Handler { - return api.HTTPHandler{Handler: api.HandlerFunc(initialCAHandler), Method: "POST"} + return api.HTTPHandler{Handler: api.HandlerFunc(initialCAHandler), Methods: []string{"POST"}} } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/scan/scan.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/scan/scan.go index 08d2cca278f..1289a81ed21 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/scan/scan.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/scan/scan.go @@ -51,7 +51,10 @@ func scanHandler(w http.ResponseWriter, r *http.Request) error { // NewHandler returns a new http.Handler that handles a scan request. func NewHandler() http.Handler { - return api.HTTPHandler{Handler: api.HandlerFunc(scanHandler), Method: "GET"} + return api.HTTPHandler{ + Handler: api.HandlerFunc(scanHandler), + Methods: []string{"GET"}, + } } // scanInfoHandler is an HTTP handler that returns a JSON blob result describing @@ -66,5 +69,5 @@ func scanInfoHandler(w http.ResponseWriter, r *http.Request) error { // NewInfoHandler returns a new http.Handler that handles a request for scan info. func NewInfoHandler() http.Handler { - return api.HTTPHandler{Handler: api.HandlerFunc(scanInfoHandler), Method: "GET"} + return api.HTTPHandler{Handler: api.HandlerFunc(scanInfoHandler), Methods: []string{"GET"}} } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign.go index 23a31ef7ab5..21299bee10e 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign.go @@ -1,3 +1,4 @@ +// Package sign implements the HTTP handler for the certificate signing command. package sign import ( @@ -70,7 +71,7 @@ func NewHandlerFromSigner(signer signer.Signer) (h *api.HTTPHandler, err error) Handler: &Handler{ signer: signer, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } @@ -139,24 +140,15 @@ func (h *Handler) Handle(w http.ResponseWriter, r *http.Request) error { } signReq := jsonReqToTrue(req) - if signReq.Hosts == nil { - return errors.NewBadRequestString("missing parameter 'hostname' or 'hosts'") - } if req.Request == "" { return errors.NewBadRequestString("missing parameter 'certificate_request'") } var cert []byte - var profile *config.SigningProfile - - policy := h.signer.Policy() - if policy != nil && policy.Profiles != nil && req.Profile != "" { - profile = policy.Profiles[req.Profile] - } - - if profile == nil && policy != nil { - profile = policy.Default + profile, err := signer.Profile(h.signer, req.Profile) + if err != nil { + return err } if profile.Provider != nil { @@ -231,7 +223,7 @@ func NewAuthHandlerFromSigner(signer signer.Signer) (http.Handler, error) { Handler: &AuthHandler{ signer: signer, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } @@ -267,15 +259,10 @@ func (h *AuthHandler) Handle(w http.ResponseWriter, r *http.Request) error { log.Critical("signer was initialised without a signing policy") return errors.NewBadRequestString("invalid policy") } - profile := policy.Default - - if policy.Profiles != nil && req.Profile != "" { - profile = policy.Profiles[req.Profile] - } - if profile == nil { - log.Critical("signer was initialised without any valid profiles") - return errors.NewBadRequestString("invalid profile") + profile, err := signer.Profile(h.signer, req.Profile) + if err != nil { + return err } if profile.Provider == nil { @@ -289,9 +276,6 @@ func (h *AuthHandler) Handle(w http.ResponseWriter, r *http.Request) error { } signReq := jsonReqToTrue(req) - if signReq.Hosts == nil { - return errors.NewBadRequestString("missing parameter 'hostname' or 'hosts'") - } if signReq.Request == "" { return errors.NewBadRequestString("missing parameter 'certificate_request'") diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign_test.go index 3fc99ae12a7..a4878edc46a 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/sign/sign_test.go @@ -319,9 +319,9 @@ var signTests = []signTest{ { Hosts: nil, CSRFile: testCSRFile, - ExpectedHTTPStatus: http.StatusBadRequest, - ExpectedSuccess: false, - ExpectedErrorCode: http.StatusBadRequest, + ExpectedHTTPStatus: http.StatusOK, + ExpectedSuccess: true, + ExpectedErrorCode: 0, }, { Hosts: []string{testDomainName}, @@ -335,7 +335,7 @@ var signTests = []signTest{ CSRFile: testBrokenCSRFile, ExpectedHTTPStatus: http.StatusBadRequest, ExpectedSuccess: false, - ExpectedErrorCode: 1002, + ExpectedErrorCode: 9002, }, } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_file_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_file_test.go index 578f5badd06..a636103e80e 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_file_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_file_test.go @@ -38,10 +38,6 @@ For each pair of crypto algorithm X and key size Y, a CA chain is constructed: |-> cfssl-leaf-rsa4096 Test_root_CA is a RSA cert, inter-L1 is RSA 4096 cert, inter-L2 is ecdsa-384 cert. -In addition, we construct another mixed chain of RSA->ECDSA->RSA->ECDSA - Test_root_CA -> inter-L1-v2 -> inter-L2-v2 --> cfssl-leaf-ecdsa256-v2 - |-> cfssl-leaf-ecdsa384-v2 - |-> cfssl-leaf-ecdsa521-v2 The max path length is set to be 1 for non-root CAs. Two inter-* certs are assembled in intermediates.crt @@ -71,11 +67,6 @@ const ( interL1Expired = "testdata/inter-L1-expired.pem" interL1CSR = "testdata/inter-L1.csr" interL2 = "testdata/inter-L2.pem" - interL1v2 = "testdata/inter-L1-v2.pem" - interL2v2 = "testdata/inter-L2-v2.pem" - leafECDSA256v2 = "testdata/cfssl-leaf-ecdsa256-v2.pem" - leafECDSA384v2 = "testdata/cfssl-leaf-ecdsa384-v2.pem" - leafECDSA521v2 = "testdata/cfssl-leaf-ecdsa521-v2.pem" interL2Direct = "testdata/inter-L2-direct.pem" partialBundle = "testdata/partial-bundle.pem" // partialBundle is a partial cert chain {leaf-ecds256, inter-L2} @@ -145,30 +136,6 @@ var fileTests = []fileTest{ errorCallback: nil, bundleChecking: ExpectBundleLength(3), }, - { - cert: leafECDSA256v2, - caBundleFile: testCFSSLRootBundle, - intBundleFile: interL1v2, - extraIntermediates: interL2v2, - errorCallback: nil, - bundleChecking: ExpectBundleLength(3), - }, - { - cert: leafECDSA384v2, - caBundleFile: testCFSSLRootBundle, - intBundleFile: interL1v2, - extraIntermediates: interL2v2, - errorCallback: nil, - bundleChecking: ExpectBundleLength(3), - }, - { - cert: leafECDSA521v2, - caBundleFile: testCFSSLRootBundle, - intBundleFile: interL1v2, - extraIntermediates: interL2v2, - errorCallback: nil, - bundleChecking: ExpectBundleLength(3), - }, // Normal bundling with private key for all supported key types { @@ -371,7 +338,7 @@ var fileTests = []fileTest{ func TestBundleFromFile(t *testing.T) { for _, test := range fileTests { b := newCustomizedBundlerFromFile(t, test.caBundleFile, test.intBundleFile, test.extraIntermediates) - bundle, err := b.BundleFromFile(test.cert, test.key, Optimal) + bundle, err := b.BundleFromFile(test.cert, test.key, Optimal, "") if test.errorCallback != nil { test.errorCallback(t, err) } else { diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_pem_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_pem_test.go index 8ebe0d44685..85250107a10 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_pem_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundle_from_pem_test.go @@ -69,7 +69,7 @@ var pemTests = []pemTest{ func TestBundleFromPEM(t *testing.T) { for _, test := range pemTests { b := test.bundlerConstructor(t) - bundle, err := b.BundleFromPEM(test.cert, test.key, Optimal) + bundle, err := b.BundleFromPEMorDER(test.cert, test.key, Optimal, "") if test.errorCallback != nil { test.errorCallback(t, err) } else { @@ -83,7 +83,7 @@ func TestBundleFromPEM(t *testing.T) { } } -// GoDaddy intermeidate cert valid until year 2034 +// GoDaddy intermediate cert valid until year 2034 var GoDaddyRootCert = []byte(`-----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE @@ -109,7 +109,7 @@ dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf ReYNnyicsbkqWletNw+vHX/bvZ8= -----END CERTIFICATE-----`) -// GoDaddy intermeidate cert valid until year 2026 +// GoDaddy intermediate cert valid until year 2026 var GoDaddyIntermediateCert = []byte(`-----BEGIN CERTIFICATE----- MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler.go index ae075e87ac4..3358c9bdbec 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler.go @@ -1,5 +1,5 @@ // Package bundler implements certificate bundling functionality for -// CF-SSL. +// CFSSL. package bundler import ( @@ -47,12 +47,11 @@ const ( ) const ( - sha2Warning = "The bundle contains certs signed with advanced hash functions such as SHA2, which are problematic at certain operating systems, e.g. Windows XP SP2." - ecdsaWarning = "The bundle contains ECDSA signatures, which are problematic at certain operating systems, e.g. Windows XP SP2, Android 2.2 and Android 2.3." - expiringWarningStub = "The bundle is expiring within 30 days. " - untrustedWarningStub = "The bundle may not be trusted by the following platform(s):" - ubiquityWarning = "The bundle trust ubiquity is not guaranteed: No platform metadata found." - deprecateSHA1WarningStub = "Due to SHA-1 deprecation, the bundle may not be trusted by the following platform(s):" + sha2Warning = "The bundle contains certificates signed with advanced hash functions such as SHA2, which are problematic for certain operating systems, e.g. Windows XP SP2." + ecdsaWarning = "The bundle contains ECDSA signatures, which are problematic for certain operating systems, e.g. Windows XP SP2, Android 2.2 and Android 2.3." + expiringWarningStub = "The bundle is expiring within 30 days." + untrustedWarningStub = "The bundle may not be trusted by the following platform(s):" + ubiquityWarning = "Unable to measure bundle ubiquity: No platform metadata present." ) // A Bundler contains the certificate pools for producing certificate @@ -69,14 +68,14 @@ type Bundler struct { // of valid intermediate certificates, respectively. func NewBundler(caBundleFile, intBundleFile string) (*Bundler, error) { log.Debug("Loading CA bundle: ", caBundleFile) - caBundlePEM, err := ioutil.ReadFile(caBundleFile) + caBundle, err := ioutil.ReadFile(caBundleFile) if err != nil { log.Errorf("root bundle failed to load: %v", err) return nil, errors.Wrap(errors.RootError, errors.ReadFailed, err) } log.Debug("Loading Intermediate bundle: ", intBundleFile) - intBundlePEM, err := ioutil.ReadFile(intBundleFile) + intBundle, err := ioutil.ReadFile(intBundleFile) if err != nil { log.Errorf("intermediate bundle failed to load: %v", err) return nil, errors.Wrap(errors.IntermediatesError, errors.ReadFailed, err) @@ -92,7 +91,8 @@ func NewBundler(caBundleFile, intBundleFile string) (*Bundler, error) { } log.Infof("intermediate stash directory %s created", IntermediateStash) } - return NewBundlerFromPEM(caBundlePEM, intBundlePEM) + return NewBundlerFromPEM(caBundle, intBundle) + } // NewBundlerFromPEM creates a new Bundler from PEM-encoded root certificates and @@ -150,9 +150,9 @@ func (b *Bundler) VerifyOptions() x509.VerifyOptions { // BundleFromFile takes a set of files containing the PEM-encoded leaf certificate // (optionally along with some intermediate certs), the PEM-encoded private key // and returns the bundle built from that key and the certificate(s). -func (b *Bundler) BundleFromFile(bundleFile, keyFile string, flavor BundleFlavor) (*Bundle, error) { +func (b *Bundler) BundleFromFile(bundleFile, keyFile string, flavor BundleFlavor, password string) (*Bundle, error) { log.Debug("Loading Certificate: ", bundleFile) - certsPEM, err := ioutil.ReadFile(bundleFile) + certsRaw, err := ioutil.ReadFile(bundleFile) if err != nil { return nil, errors.Wrap(errors.CertificateError, errors.ReadFailed, err) } @@ -172,12 +172,12 @@ func (b *Bundler) BundleFromFile(bundleFile, keyFile string, flavor BundleFlavor } } - return b.BundleFromPEM(certsPEM, keyPEM, flavor) + return b.BundleFromPEMorDER(certsRaw, keyPEM, flavor, password) } -// BundleFromPEM builds a certificate bundle from the set of byte -// slices containing the PEM-encoded certificate(s), private key. -func (b *Bundler) BundleFromPEM(certsPEM, keyPEM []byte, flavor BundleFlavor) (*Bundle, error) { +// BundleFromPEMorDER builds a certificate bundle from the set of byte +// slices containing the PEM or DER-encoded certificate(s), private key. +func (b *Bundler) BundleFromPEMorDER(certsRaw, keyPEM []byte, flavor BundleFlavor, password string) (*Bundle, error) { log.Debug("bundling from PEM files") var key crypto.Signer var err error @@ -189,11 +189,24 @@ func (b *Bundler) BundleFromPEM(certsPEM, keyPEM []byte, flavor BundleFlavor) (* } } - certs, err := helpers.ParseCertificatesPEM(certsPEM) + certs, err := helpers.ParseCertificatesPEM(certsRaw) if err != nil { - log.Debugf("failed to parse certificates: %v", err) - return nil, err - } else if len(certs) == 0 { + // If PEM doesn't work try DER + var keyDER crypto.Signer + var errDER error + certs, keyDER, errDER = helpers.ParseCertificatesDER(certsRaw, password) + // Only use DER key if no key read from file + if key == nil && keyDER != nil { + key = keyDER + } + if errDER != nil { + log.Debugf("failed to parse certificates: %v", err) + // If neither parser works pass along PEM error + return nil, err + } + + } + if len(certs) == 0 { log.Debugf("no certificates found") return nil, errors.New(errors.CertificateError, errors.DecodeFailed) } @@ -642,11 +655,11 @@ func (b *Bundler) Bundle(certs []*x509.Certificate, key crypto.Signer, flavor Bu messages = append(messages, untrustedMsg) } // Check if there is any platform that rejects the chain because of SHA1 deprecation. - deprecated := ubiquity.DeprecatedSHA1Platforms(matchingChains[0]) - if len(deprecated) > 0 { + sha1Msgs := ubiquity.SHA1DeprecationMessages(matchingChains[0]) + if len(sha1Msgs) > 0 { log.Debug("Populate SHA1 deprecation warning.") statusCode |= errors.BundleNotUbiquitousBit - messages = append(messages, deprecateSHA1Warning(deprecated)) + messages = append(messages, sha1Msgs...) } bundle.Status = &BundleStatus{ExpiringSKIs: getSKIs(bundle.Chain, expiringCerts), Code: statusCode, Messages: messages, Untrusted: untrusted} @@ -716,22 +729,6 @@ func untrustedPlatformsWarning(platforms []string) string { return msg } -// deprecateSHA1Warning generates a warning message with platform names which deprecates SHA1. -func deprecateSHA1Warning(platforms []string) string { - if len(platforms) == 0 { - return "" - } - msg := deprecateSHA1WarningStub - for i, platform := range platforms { - if i > 0 { - msg += "," - } - msg += " " + platform - } - msg += "." - return msg -} - // Optimal chains are the shortest chains, with newest intermediates and most advanced crypto suite being the tie breaker. func optimalChains(chains [][]*x509.Certificate) [][]*x509.Certificate { // Find shortest chains diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_sha1_deprecation_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_sha1_deprecation_test.go index 4e1b5de59bd..5133bb7715b 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_sha1_deprecation_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_sha1_deprecation_test.go @@ -2,114 +2,182 @@ package bundler // This test file contains tests on checking Bundle.Status with SHA-1 deprecation warning. import ( + "crypto/x509" + "io/ioutil" "testing" + "time" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity" ) const ( - sha1CA = "testdata/ca.pem" - testChromeMetadata = "testdata/ca.pem.metadata" - sha1Intermediate = "testdata/inter-L1-sha1.pem" - sha2Intermediate = "testdata/inter-L1.pem" - sha2LeafExp2015Jun2nd = "testdata/inter-L2-1.pem" - sha2LeafExp2016Jan2nd = "testdata/inter-L2-2.pem" - sha2LeafExp2016Jun2nd = "testdata/inter-L2-3.pem" - sha2LeafExp2017Jan2nd = "testdata/inter-L2-4.pem" + sha1CA = "testdata/ca.pem" + sha1CAKey = "testdata/ca.key" + sha1Intermediate = "testdata/inter-L1-sha1.pem" + sha2Intermediate = "testdata/inter-L1.pem" + intermediateKey = "testdata/inter-L1.key" + intermediateCSR = "testdata/inter-L1.csr" + leafCSR = "testdata/cfssl-leaf-ecdsa256.csr" ) func TestChromeWarning(t *testing.T) { b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, "") - // The metadata contains Chrome M39, M40 and M41. The effective date for their SHA1 deprecation - // is pushed to 2014-09-01 to enable unit testing. - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testChromeMetadata) - - // Bundle a leaf cert with expiration on 2015-06-02. - // Expect no SHA-1 deprecation warnings but a SHA2 warning. - bundle, err := b.BundleFromFile(sha2LeafExp2015Jun2nd, "", Ubiquitous) + + s, err := local.NewSignerFromFile(sha1Intermediate, intermediateKey, nil) if err != nil { - t.Fatal("bundling failed: ", err) + t.Fatal(err) } - if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { - t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) + + csrBytes, err := ioutil.ReadFile(leafCSR) + if err != nil { + t.Fatal(err) } - if len(bundle.Status.Messages) != 2 || - bundle.Status.Messages[0] != sha2Warning || - bundle.Status.Messages[1] != ecdsaWarning { - t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) + signingRequest := signer.SignRequest{Request: string(csrBytes)} + + certBytes, err := s.Sign(signingRequest) + if err != nil { + t.Fatal(err) } - // Bundle a leaf cert with expiration on 2016-01-02. - // Expect one SHA-1 deprecation warning from Chrome M41 and a SHA2 warning. - bundle, err = b.BundleFromFile(sha2LeafExp2016Jan2nd, "", Ubiquitous) + // Bundle a leaf cert with default 1 year expiration + bundle, err := b.BundleFromPEMorDER(certBytes, nil, Ubiquitous, "") if err != nil { t.Fatal("bundling failed: ", err) } - if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { - t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) + + // should be not ubiquitous due to SHA2 and ECDSA support issues in legacy platforms + if bundle.Status.Code&errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { + t.Fatal("Incorrect bundle status code. Bundle status code:", bundle.Status.Code) } - if len(bundle.Status.Messages) != 3 || - bundle.Status.Messages[0] != sha2Warning || - bundle.Status.Messages[1] != ecdsaWarning || - bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M41." { - t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) + fullChain := append(bundle.Chain, bundle.Root) + sha1Msgs := ubiquity.SHA1DeprecationMessages(fullChain) + // Since the new SHA-1 cert is expired after 2015, it definitely trigger Chrome's deprecation policies. + if len(sha1Msgs) == 0 { + t.Fatal("SHA1 Deprecation Message should not be empty") + } + // check SHA1 deprecation warnings + var sha1MsgNotFound bool + for _, sha1Msg := range sha1Msgs { + foundMsg := false + for _, message := range bundle.Status.Messages { + if message == sha1Msg { + foundMsg = true + } + } + if !foundMsg { + sha1MsgNotFound = true + break + } + } + if sha1MsgNotFound { + t.Fatalf("Incorrect bundle status messages. Bundle status messages:%v, expected to contain: %v\n", bundle.Status.Messages, sha1Msgs) } - // Bundle a leaf cert with expiration on 2016-06-02. - // Expect SHA-1 deprecation warnings from Chrome M40, M41 and a SHA2 warning. - bundle, err = b.BundleFromFile(sha2LeafExp2016Jun2nd, "", Ubiquitous) +} + +func TestSHA2Preferences(t *testing.T) { + // create a CA signer and signs a new intermediate with SHA-1 + sha1CASigner := makeCASignerFromFile(sha1CA, sha1CAKey, x509.SHA1WithRSA, t) + // create a CA signer and signs a new intermediate with SHA-2 + sha2CASigner := makeCASignerFromFile(sha1CA, sha1CAKey, x509.SHA256WithRSA, t) + + // sign two different intermediates + sha1InterBytes := signCSRFile(sha1CASigner, intermediateCSR, t) + sha2InterBytes := signCSRFile(sha2CASigner, intermediateCSR, t) + + interKeyBytes, err := ioutil.ReadFile(intermediateKey) if err != nil { - t.Fatal("bundling failed: ", err) - } - if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { - t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) + t.Fatal(err) } - if len(bundle.Status.Messages) != 3 || - bundle.Status.Messages[0] != sha2Warning || - bundle.Status.Messages[1] != ecdsaWarning || - bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M40, Chrome Browser M41." { - t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) + // create a intermediate signer from SHA-1 intermediate cert/key + sha2InterSigner := makeCASigner(sha1InterBytes, interKeyBytes, x509.SHA256WithRSA, t) + // sign a leaf cert + leafBytes := signCSRFile(sha2InterSigner, leafCSR, t) + + // create a bundler with SHA-1 and SHA-2 intermediate certs of same key. + b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, "") + if err != nil { + t.Fatal(err) } + sha1Inter, _ := helpers.ParseCertificatePEM(sha1InterBytes) + sha2Inter, _ := helpers.ParseCertificatePEM(sha2InterBytes) + b.IntermediatePool.AddCert(sha1Inter) + b.IntermediatePool.AddCert(sha2Inter) - // Bundle a leaf cert with expiration on 2017-01-02. - // Expect SHA-1 deprecation warnings from Chrome M39, M40, M41 and a SHA2 warning. - bundle, err = b.BundleFromFile(sha2LeafExp2017Jan2nd, "", Ubiquitous) + bundle, err := b.BundleFromPEMorDER(leafBytes, nil, Ubiquitous, "") if err != nil { t.Fatal("bundling failed: ", err) } - if bundle.Status.Code|errors.BundleNotUbiquitousBit != errors.BundleNotUbiquitousBit { - t.Fatal("Incorrect bundle status code. Bundle status:", bundle.Status) + + if bundle.Chain[1].SignatureAlgorithm != x509.SHA256WithRSA { + t.Fatal("ubiquity selection by SHA-2 homogenity failed.") } - if len(bundle.Status.Messages) != 3 || - bundle.Status.Messages[0] != sha2Warning || - bundle.Status.Messages[1] != ecdsaWarning || - bundle.Status.Messages[2] != deprecateSHA1WarningStub+" Chrome Browser M39, Chrome Browser M40, Chrome Browser M41." { - t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) +} + +func makeCASignerFromFile(certFile, keyFile string, sigAlgo x509.SignatureAlgorithm, t *testing.T) signer.Signer { + certBytes, err := ioutil.ReadFile(certFile) + if err != nil { + t.Fatal(err) } + + keyBytes, err := ioutil.ReadFile(keyFile) + if err != nil { + t.Fatal(err) + } + + return makeCASigner(certBytes, keyBytes, sigAlgo, t) + } -func TestUbiquitySHA2Preference(t *testing.T) { - // Add a SHA-2 L1 cert to the intermediate pool. - b := newCustomizedBundlerFromFile(t, sha1CA, sha1Intermediate, sha2Intermediate) - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testChromeMetadata) +func makeCASigner(certBytes, keyBytes []byte, sigAlgo x509.SignatureAlgorithm, t *testing.T) signer.Signer { + cert, err := helpers.ParseCertificatePEM(certBytes) + if err != nil { + t.Fatal(err) + } - bundle, err := b.BundleFromFile(sha2LeafExp2017Jan2nd, "", Ubiquitous) + key, err := helpers.ParsePrivateKeyPEM(keyBytes) if err != nil { - t.Fatal("bundling failed: ", err) + t.Fatal(err) + } + + defaultProfile := &config.SigningProfile{ + Usage: []string{"cert sign"}, + CA: true, + Expiry: time.Hour, + ExpiryString: "1h", + } + policy := &config.Signing{ + Profiles: map[string]*config.SigningProfile{}, + Default: defaultProfile, + } + s, err := local.NewSigner(key, cert, sigAlgo, policy) + if err != nil { + t.Fatal(err) + } + + return s +} + +func signCSRFile(s signer.Signer, csrFile string, t *testing.T) []byte { + csrBytes, err := ioutil.ReadFile(csrFile) + if err != nil { + t.Fatal(err) } - // With same ubiquity score, the chain with SHA2 L1 will be chosen. And so there is no Chrome warning. - if len(bundle.Status.Messages) != 2 || - bundle.Status.Messages[0] != sha2Warning || - bundle.Status.Messages[1] != ecdsaWarning { - t.Fatal("Incorrect bundle status messages. Bundle status messages:", bundle.Status.Messages) + signingRequest := signer.SignRequest{Request: string(csrBytes)} + certBytes, err := s.Sign(signingRequest) + if err != nil { + t.Fatal(err) } + return certBytes } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_test.go index a034e6f576d..a604b7ea809 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/bundler_test.go @@ -23,18 +23,15 @@ const ( testIntCaBundle = "testdata/int-bundle.pem" testNSSRootBundle = "testdata/nss.pem" testMetadata = "testdata/ca-bundle.crt.metadata" - firstdataPEM = "testdata/firstdata.pem" - forcebundlePEM = "testdata/forcebundle.pem" - draftkingsPEM = "testdata/draftkings.pem" // expires in July 2015 - riotPEM = "testdata/riot.pem" - bunningsPEM = "testdata/bunnings.pem" testCFSSLRootBundle = "testdata/ca.pem" testCAFile = "testdata/ca.pem" testCAKeyFile = "testdata/ca.key" testCFSSLIntBundle = "testdata/intermediates.crt" emptyPEM = "testdata/empty.pem" interL1SHA1 = "testdata/inter-L1-sha1.pem" + interL1Key = "testdata/inter-L1.key" interL2SHA1 = "testdata/inter-L2-sha1.pem" + interL2Key = "testdata/inter-L2.key" ) // Simply create a bundler @@ -92,7 +89,7 @@ var godaddySubjectString = `/Country=US/Province=Arizona/Locality=Scottsdale/Org // Also serves as a JSON format regression test. func TestBundleMarshalJSON(t *testing.T) { b := newBundler(t) - bundle, _ := b.BundleFromPEM(GoDaddyIntermediateCert, nil, Optimal) + bundle, _ := b.BundleFromPEMorDER(GoDaddyIntermediateCert, nil, Optimal, "") bytes, err := json.Marshal(bundle) if err != nil { @@ -167,7 +164,7 @@ func TestBundleMarshalJSON(t *testing.T) { func TestBundleWithECDSAKeyMarshalJSON(t *testing.T) { b := newCustomizedBundlerFromFile(t, testCFSSLRootBundle, testCFSSLIntBundle, "") - bundle, _ := b.BundleFromFile(leafECDSA256, leafKeyECDSA256, Optimal) + bundle, _ := b.BundleFromFile(leafECDSA256, leafKeyECDSA256, Optimal, "") jsonBytes, err := json.Marshal(bundle) if err != nil { @@ -203,7 +200,7 @@ func TestBundleWithECDSAKeyMarshalJSON(t *testing.T) { func TestBundleWithRSAKeyMarshalJSON(t *testing.T) { b := newCustomizedBundlerFromFile(t, testCFSSLRootBundle, testCFSSLIntBundle, "") - bundle, _ := b.BundleFromFile(leafRSA2048, leafKeyRSA2048, Optimal) + bundle, _ := b.BundleFromFile(leafRSA2048, leafKeyRSA2048, Optimal, "") jsonBytes, err := json.Marshal(bundle) if err != nil { @@ -250,7 +247,7 @@ func TestBundleHostnamesMarshalJSON(t *testing.T) { t.Fatal("Hostnames construction failed for cloudflare.com.", string(hostnames)) } - bundle, _ = b.BundleFromPEM(GoDaddyIntermediateCert, nil, Optimal) + bundle, _ = b.BundleFromPEMorDER(GoDaddyIntermediateCert, nil, Optimal, "") expected := []byte(`["Go Daddy Secure Certification Authority"]`) hostnames, _ = json.Marshal(bundle.Hostnames) if !bytes.Equal(hostnames, expected) { @@ -262,7 +259,7 @@ func TestBundleHostnamesMarshalJSON(t *testing.T) { // Tests on verifying the rebundle flag and error code in Bundle.Status when rebundling. func TestRebundleFromPEM(t *testing.T) { newBundler := newCustomizedBundlerFromFile(t, testCFSSLRootBundle, interL1, "") - newBundle, err := newBundler.BundleFromPEM(expiredBundlePEM, nil, Optimal) + newBundle, err := newBundler.BundleFromPEMorDER(expiredBundlePEM, nil, Optimal, "") if err != nil { t.Fatalf("Re-bundle failed. %s", err.Error()) } @@ -314,7 +311,7 @@ func TestRebundleExpiring(t *testing.T) { if err != nil { t.Fatalf("bundle failed. %s", err.Error()) } - newBundle, err := bundler.BundleFromPEM(expiredBundlePEM, nil, Optimal) + newBundle, err := bundler.BundleFromPEMorDER(expiredBundlePEM, nil, Optimal, "") if err != nil { t.Fatalf("Re-bundle failed. %s", err.Error()) } @@ -349,7 +346,7 @@ func TestUbiquitousBundle(t *testing.T) { ubiquity.Platforms = []ubiquity.Platform{platformA, platformB} // Optimal bundle algorithm will picks up the new root and shorten the chain. - optimalBundle, err := b.BundleFromFile(leafECDSA256, "", Optimal) + optimalBundle, err := b.BundleFromFile(leafECDSA256, "", Optimal, "") if err != nil { t.Fatal("Optimal bundle failed:", err) } @@ -363,7 +360,7 @@ func TestUbiquitousBundle(t *testing.T) { checkUbiquityWarningAndCode(t, optimalBundle, true) // Ubiquitous bundle will remain the same. - ubiquitousBundle, err := b.BundleFromFile(leafECDSA256, "", Ubiquitous) + ubiquitousBundle, err := b.BundleFromFile(leafECDSA256, "", Ubiquitous, "") if err != nil { t.Fatal("Ubiquitous bundle failed") @@ -385,7 +382,7 @@ func TestUbiquityBundleWithoutMetadata(t *testing.T) { // Without platform info, ubiquitous bundling falls back to optimal bundling. ubiquity.Platforms = nil - nuBundle, err := b.BundleFromFile(leafECDSA256, "", Ubiquitous) + nuBundle, err := b.BundleFromFile(leafECDSA256, "", Ubiquitous, "") if err != nil { t.Fatal("Ubiquitous-fall-back-to-optimal bundle failed: ", err) @@ -417,155 +414,271 @@ func checkUbiquityWarningAndCode(t *testing.T, bundle *Bundle, expected bool) { } } -// FIXME: test case expires in July 2015 -// Regression test on ubiquity. -// It is to make sure ubiquitous bundles are generated so they can be trusted by Android 2.2 -// and its variants. -// -// Leaf cert from DraftKings.com is issued by a GoDaddy intermediate cert, -// which in turn is issued by a GoDaddy Root Certificate (CN: Go Daddy Root Certificate Authority -// G2). The NSS library includes this root cert. So optimal bundle should only have two certs. -// However, that root cert is not present in trust stores of Android <= 2.2. Ubiquitous bundling -// should be able to recognize this scenario and produces a bundle that includes the GoDaddy Root -// cert as an intermediate, which is verified by older trust roots. -func TestAndroidUbiquitousBundle(t *testing.T) { - leafs := []string{draftkingsPEM} - for _, leaf := range leafs { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testMetadata) - - // Optimal bundle algorithm will use the Godaddy Root/GeoTrust CA. - optimalBundle, err := b.BundleFromFile(leaf, "", Optimal) - if err != nil { - t.Fatal("Optimal bundle failed:", err) - } - if len(optimalBundle.Chain) != 2 { - t.Fatal("Optimal bundle failed") - } - checkUbiquityWarningAndCode(t, optimalBundle, true) - - // Ubiquitous bundle will include a 2nd intermediate CA. - ubiquitousBundle, err := b.BundleFromFile(leaf, "", Ubiquitous) - if err != nil { - t.Fatal("Ubiquitous bundle failed") - - } - if len(ubiquitousBundle.Chain) != 3 { - t.Fatal("Ubiquitous bundle failed") - } - if len(ubiquitousBundle.Status.Untrusted) != 0 { - t.Fatal("Regression: Ubiquitous bundle has untrusted platforms: ", ubiquitousBundle.Status.Untrusted) - } - checkUbiquityWarningAndCode(t, ubiquitousBundle, false) - } -} - // Regression test on bundle with flavor 'Force'. // Compare to ubiquitous bundle which will optimize bundle length given the platform ubiquity is the same, force bundle // with return the same bundle as long as the input bundle is verified. func TestForceBundle(t *testing.T) { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testMetadata) - bundle, err := b.BundleFromFile(firstdataPEM, "", Ubiquitous) + // create a CA signer and signs a new intermediate with SHA-2 + caSigner := makeCASignerFromFile(testCAFile, testCAKeyFile, x509.SHA256WithRSA, t) + interL1Bytes := signCSRFile(caSigner, interL1CSR, t) + + // create a inter L1 signer + interL1KeyBytes, err := ioutil.ReadFile(interL1Key) if err != nil { - t.Fatal("ubiquitous bundling failed.", err) + t.Fatal(err) } - if len(bundle.Chain) != 2 { - t.Fatal("ubiquitous bundling failed. Bundle length:", len(bundle.Chain)) + interL1Signer := makeCASigner(interL1Bytes, interL1KeyBytes, x509.SHA256WithRSA, t) + + // sign a level 2 intermediate + interL2Bytes := signCSRFile(interL1Signer, interL2CSR, t) + + // create a inter L2 signer + interL2KeyBytes, err := ioutil.ReadFile(interL2Key) + if err != nil { + t.Fatal(err) + } + + interL2Signer := makeCASigner(interL2Bytes, interL2KeyBytes, x509.ECDSAWithSHA256, t) + + // interL2 sign a leaf cert + leafBytes := signCSRFile(interL2Signer, leafCSR, t) + + // create two platforms + // both trust the CA cert and L1 intermediate + caBytes, err := ioutil.ReadFile(testCAFile) + if err != nil { + t.Fatal(err) } - if bundle.Status.IsRebundled == false { - t.Fatal("force bundling failed, incorrect bundle.Status", bundle.Status) + ca, _ := helpers.ParseCertificatePEM(caBytes) + interL1, _ := helpers.ParseCertificatePEM(interL1Bytes) + platformA := ubiquity.Platform{ + Name: "A", + Weight: 100, + KeyStore: make(ubiquity.CertSet), + HashUbiquity: ubiquity.SHA2Ubiquity, + KeyAlgoUbiquity: ubiquity.ECDSA521Ubiquity, } + platformB := ubiquity.Platform{ + Name: "B", + Weight: 100, + KeyStore: make(ubiquity.CertSet), + HashUbiquity: ubiquity.SHA2Ubiquity, + KeyAlgoUbiquity: ubiquity.ECDSA521Ubiquity, + } + + platformA.KeyStore.Add(ca) + platformA.KeyStore.Add(interL1) + platformB.KeyStore.Add(ca) + platformB.KeyStore.Add(interL1) + ubiquity.Platforms = []ubiquity.Platform{platformA, platformB} + + caBundle := string(caBytes) + string(interL1Bytes) + interBundle := string(interL2Bytes) + string(interL1Bytes) + fullChain := string(leafBytes) + string(interL2Bytes) + string(interL1Bytes) - bundle, err = b.BundleFromFile(firstdataPEM, "", Force) + // create bundler + b, err := NewBundlerFromPEM([]byte(caBundle), []byte(interBundle)) if err != nil { - t.Fatal("force bundling failed.", err) + t.Fatal(err) } + // The input PEM bundle is 3-cert chain. + bundle, err := b.BundleFromPEMorDER([]byte(fullChain), nil, Force, "") + if err != nil { + t.Fatal("Force bundle failed:", err) + } if len(bundle.Chain) != 3 { - t.Fatal("force bundling failed. Bundle length:", len(bundle.Chain)) + t.Fatal("Force bundle failed:") + } + if len(bundle.Status.Untrusted) != 0 { + t.Fatal("Force bundle failed:") } - if bundle.Status.IsRebundled == true { - t.Fatal("force bundling failed, incorrect bundle.Status", bundle.Status) + // With ubiquity flavor, we should have a shorter chain, given L1 is ubiquitous trusted. + bundle, err = b.BundleFromPEMorDER([]byte(fullChain), nil, Ubiquitous, "") + if err != nil { + t.Fatal("Ubiquitous bundle failed:", err) + } + if len(bundle.Chain) != 2 { + t.Fatal("Ubiquitous bundle failed:") + } + if len(bundle.Status.Untrusted) != 0 { + t.Fatal("Ubiquitous bundle failed:") } + // With optimal flavor, we should have a shorter chain as well. + bundle, err = b.BundleFromPEMorDER([]byte(fullChain), nil, Optimal, "") + if err != nil { + t.Fatal("Optimal bundle failed:", err) + } + if len(bundle.Chain) != 2 { + t.Fatal("Optimal bundle failed:") + } + if len(bundle.Status.Untrusted) != 0 { + t.Fatal("Optimal bundle failed:") + } } -// TODO(nick): re-enable with non-expired certificate -func testUpdateIntermediate(t *testing.T) { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testMetadata) - // forcebundle.pem contains a newer intermediate, which should be used when bundling. - ub, err := b.BundleFromFile(forcebundlePEM, "", Ubiquitous) +func TestUpdateIntermediate(t *testing.T) { + // create a CA signer and signs a new intermediate with SHA-2 + caSigner := makeCASignerFromFile(testCAFile, testCAKeyFile, x509.SHA256WithRSA, t) + sha2InterBytes := signCSRFile(caSigner, interL1CSR, t) + interKeyBytes, err := ioutil.ReadFile(interL1Key) if err != nil { - t.Fatal("ubiquitous bundling failed.", err) + t.Fatal(err) } - // Ubiquitous bundle should use the intermediate from NSS since it will score higher. - if len(ub.Chain) != 2 { - t.Fatal("force bundling failed. Bundle length:", len(ub.Chain)) - } + // create a intermediate signer from intermediate cert/key + sha2InterSigner := makeCASigner(sha2InterBytes, interKeyBytes, x509.SHA256WithRSA, t) + // sign a leaf cert + leafBytes := signCSRFile(sha2InterSigner, leafCSR, t) - if ub.Status.IsRebundled == false { - t.Fatal("force bundling failed, incorrect bundle.Status", ub.Status) + // read CA cert bytes + caCertBytes, err := ioutil.ReadFile(testCAFile) + if err != nil { + t.Fatal(err) } - - fb, err := b.BundleFromFile(forcebundlePEM, "", Force) - + // create a bundler with the test root CA and no intermediates + b, err := NewBundlerFromPEM(caCertBytes, nil) if err != nil { - t.Fatal("force bundling failed.", err) + t.Fatal(err) } - // Force bundle should use the intermediate from input, indicating intermediate pool is updated. - if len(fb.Chain) != 2 { - t.Fatal("force bundling failed. Bundle length:", len(fb.Chain)) + // create a cert bundle: leaf + inter + chainBytes := string(leafBytes) + string(sha2InterBytes) + bundle, err := b.BundleFromPEMorDER([]byte(chainBytes), nil, Ubiquitous, "") + if err != nil { + t.Fatal("Valid bundle should be accepted. error:", err) + } + if bundle.Status.IsRebundled { + t.Fatal("rebundle should never happen here") } - if fb.Status.IsRebundled == true { - t.Fatal("force bundling failed, incorrect bundle.Status", fb.Status) + // Now bundle with the leaf cert + bundle2, err := b.BundleFromPEMorDER(leafBytes, nil, Ubiquitous, "") + if err != nil { + t.Fatal("Valid bundle should be accepted. error:", err) + } + if !bundle2.Status.IsRebundled { + t.Fatal("rebundle should happen here") } } -// FIXME: test case expires in July 2015 func TestForceBundleFallback(t *testing.T) { - leafs := []string{draftkingsPEM} - for _, leaf := range leafs { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testMetadata) + // create a CA signer and signs a new intermediate with SHA-2 + caSigner := makeCASignerFromFile(testCAFile, testCAKeyFile, x509.SHA256WithRSA, t) + sha2InterBytes := signCSRFile(caSigner, interL1CSR, t) - forceBundle, err := b.BundleFromFile(leaf, "", Force) - if err != nil { - t.Fatal("Force bundle failed:", err) - } + interKeyBytes, err := ioutil.ReadFile(interL1Key) + if err != nil { + t.Fatal(err) + } - ubiquitousBundle, err := b.BundleFromFile(leaf, "", Ubiquitous) - if err != nil { - t.Fatal("Ubiquitous bundle failed") + // create a intermediate signer from intermediate cert/key + sha2InterSigner := makeCASigner(sha2InterBytes, interKeyBytes, x509.SHA256WithRSA, t) + // sign a leaf cert + leafBytes := signCSRFile(sha2InterSigner, leafCSR, t) - } + // read CA cert bytes + caCertBytes, err := ioutil.ReadFile(testCAFile) + if err != nil { + t.Fatal(err) + } + // create a bundler with the test root CA and the new intermediate + b, err := NewBundlerFromPEM(caCertBytes, sha2InterBytes) + if err != nil { + t.Fatal(err) + } - if diff(ubiquitousBundle.Chain, forceBundle.Chain) { - t.Fatal("Force bundle fallback failed.") - } + // Now bundle with the leaf cert with Force + bundle, err := b.BundleFromPEMorDER(leafBytes, nil, Force, "") + if err != nil { + t.Fatal("Valid bundle should be generated, error:", err) + } + + // Force bundle fallback to creating a valid bundle + if len(bundle.Chain) != 2 { + t.Fatal("incorrect bundling") + } + if !bundle.Status.IsRebundled { + t.Fatal("rebundle should happen here") } + } // Regression test: ubiquity bundle test with SHA2-homogeneous preference should not override root ubiquity. -func TestSHA2Homogeneity(t *testing.T) { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - ubiquity.Platforms = nil - ubiquity.LoadPlatforms(testMetadata) - // The input PEM bundle is 3-cert chain with a cross-signed GeoTrust certificate, - // aimed to provide cert ubiquity to Android 2.2 - bundle, err := b.BundleFromFile(bunningsPEM, "", Force) +func TestSHA2HomogeneityAgainstUbiquity(t *testing.T) { + // create a CA signer and signs a new intermediate with SHA-1 + caSigner := makeCASignerFromFile(testCAFile, testCAKeyFile, x509.SHA1WithRSA, t) + interL1Bytes := signCSRFile(caSigner, interL1CSR, t) + + // create a inter L1 signer + interL1KeyBytes, err := ioutil.ReadFile(interL1Key) + if err != nil { + t.Fatal(err) + } + + interL1Signer := makeCASigner(interL1Bytes, interL1KeyBytes, x509.SHA256WithRSA, t) + + // sign a level 2 intermediate + interL2Bytes := signCSRFile(interL1Signer, interL2CSR, t) + + // create a inter L2 signer + interL2KeyBytes, err := ioutil.ReadFile(interL2Key) + if err != nil { + t.Fatal(err) + } + + interL2Signer := makeCASigner(interL2Bytes, interL2KeyBytes, x509.ECDSAWithSHA256, t) + + // interL2 sign a leaf cert + leafBytes := signCSRFile(interL2Signer, leafCSR, t) + + // create two platforms + // platform A trusts the CA cert and L1 intermediate + // platform B trusts the CA cert + caBytes, err := ioutil.ReadFile(testCAFile) + if err != nil { + t.Fatal(err) + } + + ca, _ := helpers.ParseCertificatePEM(caBytes) + interL1, _ := helpers.ParseCertificatePEM(interL1Bytes) + platformA := ubiquity.Platform{ + Name: "A", + Weight: 100, + KeyStore: make(ubiquity.CertSet), + HashUbiquity: ubiquity.SHA2Ubiquity, + KeyAlgoUbiquity: ubiquity.ECDSA521Ubiquity, + } + platformB := ubiquity.Platform{ + Name: "B", + Weight: 100, + KeyStore: make(ubiquity.CertSet), + HashUbiquity: ubiquity.SHA2Ubiquity, + KeyAlgoUbiquity: ubiquity.ECDSA521Ubiquity, + } + + platformA.KeyStore.Add(ca) + platformA.KeyStore.Add(interL1) + platformB.KeyStore.Add(ca) + ubiquity.Platforms = []ubiquity.Platform{platformA, platformB} + + caBundle := string(caBytes) + string(interL1Bytes) + interBundle := string(interL2Bytes) + string(interL1Bytes) + fullChain := string(leafBytes) + string(interL2Bytes) + string(interL1Bytes) + + // create bundler + b, err := NewBundlerFromPEM([]byte(caBundle), []byte(interBundle)) + if err != nil { + t.Fatal(err) + } + + // The input PEM bundle is 3-cert chain. + bundle, err := b.BundleFromPEMorDER([]byte(fullChain), nil, Force, "") if err != nil { t.Fatal("Force bundle failed:", err) } @@ -576,8 +689,9 @@ func TestSHA2Homogeneity(t *testing.T) { t.Fatal("Force bundle failed:") } - // With ubiquity flavor, we should not sacrifice Android 2.2 and rebundle with a shorter chain. - bundle, err = b.BundleFromFile(bunningsPEM, "", Ubiquitous) + // With ubiquity flavor, we should not sacrifice trust store ubiquity and rebundle with a shorter chain + // with SHA2 homogenity. + bundle, err = b.BundleFromPEMorDER([]byte(fullChain), nil, Ubiquitous, "") if err != nil { t.Fatal("Ubiquitous bundle failed:", err) } @@ -588,9 +702,8 @@ func TestSHA2Homogeneity(t *testing.T) { t.Fatal("Ubiquitous bundle failed:") } - // With optimal flavor, we should have a shorter chain with only SHA-2 intermediates. But Android 2.2 - // is untrusted. - bundle, err = b.BundleFromFile(bunningsPEM, "", Optimal) + // With optimal flavor, we should have a shorter chain. + bundle, err = b.BundleFromPEMorDER([]byte(fullChain), nil, Optimal, "") if err != nil { t.Fatal("Optimal bundle failed:", err) } @@ -640,16 +753,30 @@ func checkECDSAWarningAndCode(t *testing.T, bundle *Bundle, expected bool) { // bundle uses SHA-256 which is not supported in Windows XP SP2. We should present a warning // on this. func TestSHA2Warning(t *testing.T) { - b := newCustomizedBundlerFromFile(t, testNSSRootBundle, testIntCaBundle, "") - // Optimal bundle algorithm will use the Godaddy Root/GeoTrust CA. - optimalBundle, err := b.BundleFromFile(riotPEM, "", Optimal) + // create a CA signer and signs a new intermediate with SHA-2 + caSigner := makeCASignerFromFile(testCAFile, testCAKeyFile, x509.SHA256WithRSA, t) + sha2InterBytes := signCSRFile(caSigner, interL1CSR, t) + + // read CA cert bytes + caCertBytes, err := ioutil.ReadFile(testCAFile) + if err != nil { + t.Fatal(err) + } + + // create a bundler with the test root CA and no intermediates + b, err := NewBundlerFromPEM(caCertBytes, nil) + if err != nil { + t.Fatal(err) + } + + optimalBundle, err := b.BundleFromPEMorDER(sha2InterBytes, nil, Optimal, "") if err != nil { t.Fatal("Optimal bundle failed:", err) } checkSHA2WarningAndCode(t, optimalBundle, true) // Ubiquitous bundle will include a 2nd intermediate CA. - ubiquitousBundle, err := b.BundleFromFile(riotPEM, "", Ubiquitous) + ubiquitousBundle, err := b.BundleFromPEMorDER(sha2InterBytes, nil, Ubiquitous, "") if err != nil { t.Fatal("Ubiquitous bundle failed") @@ -661,11 +788,12 @@ func TestSHA2Warning(t *testing.T) { // A test bundle that contains ECDSA384 but no SHA1. Expect ECDSA warning and no SHA-2 warning. func TestECDSAWarning(t *testing.T) { b := newCustomizedBundlerFromFile(t, testCAFile, interL1SHA1, "") - // Optimal - optimalBundle, err := b.BundleFromFile(interL2SHA1, "", Optimal) + + optimalBundle, err := b.BundleFromFile(interL2SHA1, "", Optimal, "") if err != nil { t.Fatal("Optimal bundle failed:", err) } + checkSHA2WarningAndCode(t, optimalBundle, false) checkECDSAWarningAndCode(t, optimalBundle, true) } @@ -713,6 +841,8 @@ func createInterCert(t *testing.T, csrFile string, policy *config.Signing, profi return } + +// newBundler creates bundler from byte slices of CA certs and intermediate certs in PEM format func newBundlerFromPEM(t *testing.T, caBundlePEM, intBundlePEM []byte) (b *Bundler) { b, err := NewBundlerFromPEM(caBundlePEM, intBundlePEM) if err != nil { @@ -722,7 +852,7 @@ func newBundlerFromPEM(t *testing.T, caBundlePEM, intBundlePEM []byte) (b *Bundl } // newCustomizedBundleCreator is a helper function that returns a new Bundler -// takes specified CA bundle, intermediate bundle, and any additional intermdiate certs to generate a bundler. +// takes specified CA bundle, intermediate bundle, and any additional intermdiate certs to generate a bundler. func newCustomizedBundlerFromFile(t *testing.T, caBundle, intBundle, adhocInters string) (b *Bundler) { b, err := NewBundler(caBundle, intBundle) if err != nil { diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/CADisigI1CertificationService_cb619f69c2d820b4bc23e4d4339f06a96d6373d4_021c8d95a0308df09c0000000000611515.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/CADisigI1CertificationService_cb619f69c2d820b4bc23e4d4339f06a96d6373d4_021c8d95a0308df09c0000000000611515.crt new file mode 100644 index 00000000000..233904f2a3e --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/CADisigI1CertificationService_cb619f69c2d820b4bc23e4d4339f06a96d6373d4_021c8d95a0308df09c0000000000611515.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE5zCCA8+gAwIBAgIRAhyNlaAwjfCcAAAAAABhFRUwDQYJKoZIhvcNAQEFBQAw +SjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRp +c2lnIGEucy4xETAPBgNVBAMTCENBIERpc2lnMB4XDTEyMDUzMTE3NDkwMloXDTE2 +MDMxNTE3NDkwMlowYzELMAkGA1UEBhMCU0sxEzARBgNVBAcMCkJyYXRpc2xhdmEx +EzARBgNVBAoMCkRpc2lnIGEucy4xKjAoBgNVBAMMIUNBIERpc2lnIEkxIENlcnRp +ZmljYXRpb24gU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANBg8jAhWMX34D/st646D2g+5dAYB0o6Pv9SYdEzNZvozFj/1fO80vMQMRX75DUv +nvAkKIZvDALuqVRVuj7fDGlsQiu9GlFvtAXg6cDd/5WbnQns/ersDLFZ9vFVOYZQ +PgLpy2O0AiBgL5bxrYx0kUvurySstNlrYMzrtMiZpOmu+bVFHQrGjpTInfwiZOgB +4Tr+KcP/k0y7QRC+QTE2PNT7k/H/FxzGfQvc8zayGxYFuq85Kpk1wKtIfxBy37M4 +nMg4zQfeKbTQajrWh3/Yl0JGlR49oS/wmnyvMWq3VTx8D0BYShSAq2nkBg+Yf1GL +Fpm18TlwVy8dvXBv9QqrY08CAwEAAaOCAa0wggGpMGkGCCsGAQUFBwEBBF0wWzAj +BggrBgEFBQcwAYYXaHR0cDovL2NhLW9jc3AuZGlzaWcuc2swNAYIKwYBBQUHMAKG +KGh0dHA6Ly93d3cuZGlzaWcuc2svY2EvY2VydC9jYV9kaXNpZy5kZXIwHQYDVR0O +BBYEFMthn2nC2CC0vCPk1DOfBqltY3PUMB8GA1UdIwQYMBaAFI2ySWidcgglucAn +9VCTVkhGcfmPMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYG +A1UdHwRfMF0wLaAroCmGJ2h0dHA6Ly93d3cuZGlzaWcuc2svY2EvY3JsL2NhX2Rp +c2lnLmNybDAsoCqgKIYmaHR0cDovL2NhLmRpc2lnLnNrL2NhL2NybC9jYV9kaXNp +Zy5jcmwwUAYDVR0gBEkwRzBFBg4rgR6Rk+YKAAAAAQEEAzAzMDEGCCsGAQUFBwIB +FiVodHRwOi8vd3d3LmRpc2lnLnNrL19wZGYvY3AtZGlzaWcucGRmMB4GA1UdEQQX +MBWBE2Nhb3BlcmF0b3JAZGlzaWcuc2swDQYJKoZIhvcNAQEFBQADggEBAHiH87TX ++efGy8a3Te8Pxa/KBXhbS1nB6N2WyzklQmWRqfhGFecMPq4OeKtcE/M/K28KiP8e +4HgPM8XiwJ1k7MFp8dc6k/9LBiIeI+w4pGBXoIp0TfZJU4kUDRjAGVR6R1nj2/Iz +UCnXa9+35pyRvFSuA6q7P2xC6OL4wNnbG6wPU3PUX2kCEUxfhxKJnpa2XZtZCCOC +zWqRTHihw05HjfoayIp3O71kYe1LWxpl4QPStwO3gHOQKKUR1f9XCwqqlYwN/wbY +Cv/ef1hzECVsFL7kGGEbA6P+DDu3EnRcsVot1XCI0rsFFgF241qiUiiwf26jf+53 +e1FbYT/ZFR0D3BI= +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/COMODOECCDomainValidationSecureServerCA2_40096167f0bc83714fde12082c6fd4d42b763d96_5b25ce6907c4265566d3390c99a954ad.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/COMODOECCDomainValidationSecureServerCA2_40096167f0bc83714fde12082c6fd4d42b763d96_5b25ce6907c4265566d3390c99a954ad.crt new file mode 100644 index 00000000000..3e0f6c08512 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/COMODOECCDomainValidationSecureServerCA2_40096167f0bc83714fde12082c6fd4d42b763d96_5b25ce6907c4265566d3390c99a954ad.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDnzCCAyWgAwIBAgIQWyXOaQfEJlVm0zkMmalUrTAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwOTI1MDAw +MDAwWhcNMjkwOTI0MjM1OTU5WjCBkjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxODA2BgNVBAMTL0NPTU9ETyBFQ0MgRG9tYWluIFZhbGlk +YXRpb24gU2VjdXJlIFNlcnZlciBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD +QgAEAjgZgTrJaYRwWQKOqIofMN+83gP8eR06JSxrQSEYgur5PkrkM8wSzypD/A7y +ZADA4SVQgiTNtkk4DyVHkUikraOCAWYwggFiMB8GA1UdIwQYMBaAFHVxpxlIGbyd +nepBR9+UxEh3mdN5MB0GA1UdDgQWBBRACWFn8LyDcU/eEggsb9TUK3Y9ljAOBgNV +HQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEF +BQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgGBmeBDAECATBMBgNV +HR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FQ0ND +ZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDByBggrBgEFBQcBAQRmMGQwOwYIKwYB +BQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET0VDQ0FkZFRydXN0 +Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC5jb21vZG9jYTQuY29tMAoG +CCqGSM49BAMDA2gAMGUCMQCsaEclgBNPE1bAojcJl1pQxOfttGHLKIoKETKm4nHf +EQGJbwd6IGZrGNC5LkP3Um8CMBKFfI4TZpIEuppFCZRKMGHRSdxv6+ctyYnPHmp8 +7IXOMCVZuoFwNLg0f+cB0eLLUg== +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/DigiCertSHA2HighAssuranceServerCA_5168ff90af0207753cccd9656462a212b859723b_04e1e7a4dc5cf2f36dc02b42b85d159f.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/DigiCertSHA2HighAssuranceServerCA_5168ff90af0207753cccd9656462a212b859723b_04e1e7a4dc5cf2f36dc02b42b85d159f.crt new file mode 100644 index 00000000000..8c4c7410586 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/DigiCertSHA2HighAssuranceServerCA_5168ff90af0207753cccd9656462a212b859723b_04e1e7a4dc5cf2f36dc02b42b85d159f.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy +YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2 +4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC +Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1 +itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn +4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X +sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft +bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy +dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG +BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ +UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D +aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd +aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH +E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly +/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu +xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF +0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae +cPUeybQ= +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GeoTrustSSLCA-G3_d26ff796f4853f723c307d23da85789ba37c5a7c_023a6f.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GeoTrustSSLCA-G3_d26ff796f4853f723c307d23da85789ba37c5a7c_023a6f.crt new file mode 100644 index 00000000000..8d12709910d --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GeoTrustSSLCA-G3_d26ff796f4853f723c307d23da85789ba37c5a7c_023a6f.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K +hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ +U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B +89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx +j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB +I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv +vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl +aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB +AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw +QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1 +c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5 +bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq +n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9 +Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg +3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45 +SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N +QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp +zNSS +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GoogleInternetAuthorityG2_4add06161bbcf668b576f581b6bb621aba5a812f_023a76.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GoogleInternetAuthorityG2_4add06161bbcf668b576f581b6bb621aba5a812f_023a76.crt new file mode 100644 index 00000000000..5273269a24f --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/GoogleInternetAuthorityG2_4add06161bbcf668b576f581b6bb621aba5a812f_023a76.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8DCCAtigAwIBAgIDAjp2MA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG +EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy +bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP +VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv +h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE +ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ +EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC +DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7 +qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD +VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig +JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF +BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMBcGA1UdIAQQ +MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQUFAAOCAQEAJ4zP6cc7vsBv6JaE ++5xcXZDkd9uLMmCbZdiFJrW6nx7eZE4fxsggWwmfq6ngCTRFomUlNz1/Wm8gzPn6 +8R2PEAwCOsTJAXaWvpv5Fdg50cUDR3a4iowx1mDV5I/b+jzG1Zgo+ByPF5E0y8tS +etH7OiDk4Yax2BgPvtaHZI3FCiVCUe+yOLjgHdDh/Ob0r0a678C/xbQF9ZR1DP6i +vgK66oZb+TWzZvXFjYWhGiN3GhkXVBNgnwvhtJwoKvmuAjRtJZOcgqgXe/GFsNMP +WOH7sf6coaPo/ck/9Ndx3L2MpBngISMjVROPpBYCCX65r+7bU2S9cS+5Oc4wt7S8 +VOBHBw== +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/cloudflare-intercom_8860ba18a477b841041bd5ef7751c25b14ba203f_5bc0b8bee6f8e914.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/cloudflare-intercom_8860ba18a477b841041bd5ef7751c25b14ba203f_5bc0b8bee6f8e914.crt new file mode 100644 index 00000000000..73066696c39 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/intermediates/cloudflare-intercom_8860ba18a477b841041bd5ef7751c25b14ba203f_5bc0b8bee6f8e914.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEbTCCA9igAwIBAgIIW8C4vub46RQwCwYJKoZIhvcNAQELMH0xCzAJBgNVBAYT +AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv +MRMwEQYDVQQKDApDbG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQG +A1UEAwwNQ0ZTU0xfVEVTVF9DQTAeFw0xNTA1MjkyMTUyMDBaFw0xNTA1MjkyMjUy +MDBaMIGMMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UE +CxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET +MBEGA1UECBMKQ2FsaWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDlCnV+vj0sVPy8SqHL +AlI+xwnPhWgzj2VevD6Nz1Zu1BeQ5m5y4CWCf+GmRGTP7+a/C510Fw6rpmInB0Ng +xxwQ2rC08fJtCnijlGH/VjEPIHY5lRaAomcM8Rgx6JOuv9BpZJKpr9pyUMV53JeW +RbWuLH5nEMdyk9NpetS2gWxt4/D20QlhK/tHkROrcLmEUddwIGdwE8JzI88c77Fu +u6pgMtHKvl4GGH0yvb4T7PvCdH8V2tCH7bt8roXd9MSyFVy7uORkfouip7EsVREU +mlcY5EvpR141KXbZqiOQiusJ+u76mEUQNk8wCR1/CW/ii9v1BKOVjXwCfEtIXjg0 +APJx1VNSSH6XoDpUETL+eQ4J0FL9XNbsDuYar7+zD0N1/5vSo3HLNRQR9f0lbsys +sWBEN+CxK19xyPumr21Z0bU0f1B5H52VSF0q3I1Ju9wRo994a7YipdGcmZ2lChmT +7r3mzlBTYl3poU26q34v8wG9U7Jv4fsZJ+RGebDI+TR3QG6Yod06l9oEYZxWXBY7 +STOs8wuTu3huSnan/IpWnV017Vsc61D5G+QrqcxZdXckt3anZKCF75JpUnJ7vuow +TmmHlb8KIMa9mOvcuGX4P6mz8gTi2arl/aL27kj9Q0Jgv/y1ebe2Bx2P9TF6+VND +DL3J/vSVlFeqLt2reAIBKnytLwIDAQABo2YwZDAOBgNVHQ8BAf8EBAMCAAQwEgYD +VR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUiGC6GKR3uEEEG9Xvd1HCWxS6ID8w +HwYDVR0jBBgwFoAUuF7vrmdQt9bzB+VqvlWzZzoNkj4wCwYJKoZIhvcNAQELA4GB +ACn1ZlQ9fzh/XH2jK6rv8C+H/sMKfRQ0f+UCa4K3vQpg/jiliNlP6ZtBi/TFTd0y +GfGPQlCKktZuw6SuNmXD/lUc3A1H1IcYfKVpK7bOJ6+q9OD1CAO+xt3VQdr4K5W+ +inQTvCvz0oFEKh2rSbmFferidcKBN+nkeHcLUOSn7zDN +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/bunnings.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/bunnings.pem deleted file mode 100644 index 5b4ce36a633..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/bunnings.pem +++ /dev/null @@ -1,75 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIE2jCCA8KgAwIBAgIQB0GfyZ37ARHtj7oFnxJVqDANBgkqhkiG9w0BAQsFADBE -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU -R2VvVHJ1c3QgU1NMIENBIC0gRzMwHhcNMTQwNTA2MDAwMDAwWhcNMTYwNjIxMjM1 -OTU5WjCBiTELMAkGA1UEBhMCQVUxETAPBgNVBAgMCFZpY3RvcmlhMRYwFAYDVQQH -DA1IYXd0aG9ybiBFYXN0MR8wHQYDVQQKDBZCdW5uaW5ncyBHcm91cCBMaW1pdGVk -MRIwEAYDVQQLDAlFY29tbWVyY2UxGjAYBgNVBAMMESouYnVubmluZ3MuY29tLmF1 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqpFpWh6yMFhX6O24zyjD -/RKi3qwQeCokwLf2mkEIkcZPvrm/aDQ26e+ZieUJeXHTK9zwxibHCRqYZYAkMvuS -k5ZuB6bdA9ipdPLQN9sG4dsJGNRV3MdbXRK6534BWc8LbbG3O+1p6X8Fm3tpYC5u -C5H+Ek2Gm2uf3hQys+O8mYieEONg5Xf3SqBzGyT3yPztPZQXthjRJfMcBF9UJe5b -a1MB0IYYefph3Bo7HHb3pX9ywqiC8zffoIoowsysg+gU9tKoPRUgAbUcV/IjM037 -sy+qe4BK++cifD9UN7R2to6F373MtOl5ldMG7fXdOhf3cALPiwYe5P3XAHC3UkXA -aQIDAQABo4IBgDCCAXwwLQYDVR0RBCYwJIIRKi5idW5uaW5ncy5jb20uYXWCD2J1 -bm5pbmdzLmNvbS5hdTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAtBgNVHR8E -JjAkMCKgIKAehhxodHRwOi8vZ24xLnN5bWNiLmNvbS9nbjEuY3JsMGUGA1UdIARe -MFwwWgYKYIZIAYb4RQEHNjBMMCMGCCsGAQUFBwIBFhdodHRwczovL2Quc3ltY2Iu -Y29tL2NwczAlBggrBgEFBQcCAjAZFhdodHRwczovL2Quc3ltY2IuY29tL3JwYTAd -BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU0m/3lvSF -P3I8MH0j2oV4m6N8WnwwWgYIKwYBBQUHAQEETjBMMCAGCCsGAQUFBzABhhRodHRw -Oi8vZ24yLnN5bWNiLmNvbTAoBggrBgEFBQcwAoYcaHR0cDovL2duMS5zeW1jYi5j -b20vZ24xLmNydDANBgkqhkiG9w0BAQsFAAOCAQEA1jfVww4Vm/aXvfev4UOgg+7G -LWuJDm7j0F7oB48Xjah9iuGFWSfmq0Z8nTfM+d5X+BOH1fmJ+O1zLs8S8IBUTgVk -hbdWXy8NA+r8ufaF2MDJiL1tfHwn3WgAnc1T+w+HMIRMPNlRs+ZEBXEbpXUJmHOW -rSbFlLN4fwWvN8icuNWO4TuJDqvh5WjQvIFdytygJbMeb5FjLEHFmYftAW5co2cN -2+FRA+WZ8lfebr5/rObxUoZs8PYCNp7BkXoYZRSI49TEEe+QmO9Q1OmbfPzflJfJ -fIR/XQZ2zHvuZTd3nfbIkDZoHYnyJwKj29UUKWwHRL+6celDM9/kDwIXbIem2g== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg -U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K -hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ -U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B -89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx -j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB -I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv -vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T -AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl -aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB -AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw -QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1 -c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5 -bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq -n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9 -Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg -3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45 -SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N -QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp -zNSS ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT -MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 -aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw -WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE -AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m -OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu -T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c -JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR -Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz -PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm -aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM -TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g -LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO -BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv -dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB -AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL -NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W -b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S ------END CERTIFICATE----- \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/ca.pem.metadata b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/ca.pem.metadata deleted file mode 100644 index 2dc32cfdec1..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/ca.pem.metadata +++ /dev/null @@ -1,42 +0,0 @@ -[ -{ - "name":"Chrome Browser M39", - "weight": 0, - "hash_algo": "SHA2", - "key_algo": "ECDSA256", - "hash_algo_expiry": { - "target": "SHA1", - "effective_date": "2014-09-01T00:00:00Z", - "expiry_deadline": "2017-01-01T00:00:00Z" - } -}, -{ - "name":"Chrome Browser M40", - "weight": 0, - "hash_algo": "SHA2", - "key_algo": "ECDSA256", - "hash_algo_expiry": { - "target": "SHA1", - "effective_date": "2014-09-01T00:00:00Z", - "expiry_deadline": "2016-06-01T00:00:00Z" - } -}, -{ - "name":"Chrome Browser M41", - "weight": 0, - "hash_algo": "SHA2", - "key_algo": "ECDSA256", - "hash_algo_expiry": { - "target": "SHA1", - "effective_date": "2014-09-01T00:00:00Z", - "expiry_deadline": "2016-01-01T00:00:00Z" - } -}, -{ - "name":"Test Platform", - "weight": 1, - "hash_algo": "SHA2", - "key_algo": "ECDSA521", - "keystore": "ca.pem" -} -] diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa256-v2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa256-v2.pem deleted file mode 100644 index d487bd05dce..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa256-v2.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDTTCCAjegAwIBAgIIaqaClruOQWMwCwYJKoZIhvcNAQELMIGGMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEXMBUGA1UEAxMOY2xvdWRmbGFyZS5jb20wHhcNMTQwNTI3MTgwMzA4WhcN -MTUwNTI3MTgwODA4WjCBizELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNsb3VkRmxh -cmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcTDVNhbiBG -cmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHDAaBgNVBAMTE2Nsb3VkZmxh -cmUtbGVhZi5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASMRv3xvcv4I5QF -7we+23hES2waKDffBRhQMVVAOSIJcpb4JnzcVJiPJjNlMPbczi5vbzkQK2kkjOP+ -okqQia3go4GGMIGDMA4GA1UdDwEB/wQEAwIApjAdBgNVHSUEFjAUBggrBgEFBQcD -AQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQU4t+cr91m -a5IxOPeiezgN8W9FBNowHwYDVR0jBBgwFoAUfb7i6rIruh9UuqhvSZlEoevO5qgw -CwYJKoZIhvcNAQELA4IBAQDXW01KmbTDyOcVvF+gU9tIUs0xjrEaMEmm5vwlukSH -AmliEUEAieRdsJsPgFxwzifBksZpa4J8FTUNs7tS1JIievAgtTj08wY/sdBhF8pX -s0JmfTyW93IJYOqJrgkpqHRH0bOfuNidxjzEeqg06GL1rnqD3wS7q4wKpJ0jR8Ws -iYK9URC6KB8WMLqJTOt4GwRSHfhink1iAc7Nlw2Id26o2kFDGHHyB4S5XsSc0YrB -hUuzKOkC1hHsvR07OBolpvzXsGR1S77UVOKvgpU5DiTbyjX2iycJGtBdhil+w0U/ -Gq99AYLLfFKG67C1lSM5BLincp0AX2wYrY/hf8MTDdag ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa384-v2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa384-v2.pem deleted file mode 100644 index 4a4fa04c677..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa384-v2.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDajCCAlSgAwIBAgIIKkKT9A/MDD4wCwYJKoZIhvcNAQELMIGGMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEXMBUGA1UEAxMOY2xvdWRmbGFyZS5jb20wHhcNMTQwNTI3MTgwNDEyWhcN -MTUwNTI3MTgwOTEyWjCBizELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNsb3VkRmxh -cmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcTDVNhbiBG -cmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHDAaBgNVBAMTE2Nsb3VkZmxh -cmUtbGVhZi5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATWIrww4dyIpJG/t/zq -HIrcuCUF5sSz9p42U4WDbUeMuwcYsadOSi6KvILWs8nHA5JbnruDlhZ6ZpI8qj0P -tDCH/wSSqAOEOIjYgjf2XxevdC0f6WT6zEWblkhlW9vPdC+jgYYwgYMwDgYDVR0P -AQH/BAQDAgCmMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMB -Af8ECDAGAQH/AgEBMB0GA1UdDgQWBBTiTQoJuFODtNnEnbYaxy+He8lO+DAfBgNV -HSMEGDAWgBR9vuLqsiu6H1S6qG9JmUSh687mqDALBgkqhkiG9w0BAQsDggEBAJIu -Gg+4SJYA1vwlP6di/cXrctbfuFmxkHb+2+xMnJhRGzWZSk26ZRSfJmfyl4VR8x5y -oYFpvIV1JsihIKoVWt34gZJrtUM5yZLIqEpaIzQd+yxg3NtUZ+Br0YDYKJOJ+GOl -/uk5Nz10I5qqGZgCLTxW2riQH2z8hY8Bow7eh1SfazSVzuqOHGobaspbrxzkbqYE -OlJeGyg1YUsf6X2SlaGgO3uYon6gVanPj3e/I3yUciCLouD72PP2IY5O/bllVp1R -7VEgbrJAsfMtVywH5KV9R8A+VuxGj8nIh3JrckBlCfj5U9sicJbWIQbcjlBXn4/Y -EHD1hD0LRPKdq7eZ1GI= ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa521-v2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa521-v2.pem deleted file mode 100644 index 7fbb82b50d3..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/cfssl-leaf-ecdsa521-v2.pem +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkDCCAnqgAwIBAgIIQafPjiBzOXkwCwYJKoZIhvcNAQELMIGGMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEXMBUGA1UEAxMOY2xvdWRmbGFyZS5jb20wHhcNMTQwNTI3MTgwNDI2WhcN -MTUwNTI3MTgwOTI2WjCBizELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNsb3VkRmxh -cmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcTDVNhbiBG -cmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHDAaBgNVBAMTE2Nsb3VkZmxh -cmUtbGVhZi5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAEp3UqqoJpe6UV7 -y9YR3a8SgMpoRotSKNqeA9JKi+3LyE6p5w3WsENvych1DQc4Tq7nvH4gjRPqO752 -1eXsbmrAYwEK3F1RdexFJJ53DaKuUnYOqiI5pcHKjTDqkr2CABh3cE11Hg2vPHf4 -3vpMp82ojKFzNtSJBSnnV7ab9+g+ziveqKOBhjCBgzAOBgNVHQ8BAf8EBAMCAKYw -HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C -AQEwHQYDVR0OBBYEFDYrMNrJaqxCJjszyculXPsseU/yMB8GA1UdIwQYMBaAFH2+ -4uqyK7ofVLqob0mZRKHrzuaoMAsGCSqGSIb3DQEBCwOCAQEAmytI+1j8r9KmCGEF -9iq60KycOXKlVIsEH890WrpvMLBspr0+NGDHCZA5BcVB0aOpyno8Vj/9y6qlr2Wr -+CNrChF3UmGTzROqJeAXH4N8gnOoZGSUVYBcNJnGgji/ZURsrE5IPw5d9oMGRRvb -q+JdUVlr1G7YGo6mtVHHUCG3okeUj7ddjLMCDGaprIPk1teqR/94jvcG+2cLgrge -riJMqtOI8EFckcvHfcA3bZ4G2mXmikWje2od0UaWT5VS1htCKJhlxAFTcaz3qg2o -T1hNaWSM72HiBCZERI+iwI0CmBBRkOIBOxznh1/boa5O0tWN4o55Ureh9rbF3xep -q2GQSw== ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/draftkings.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/draftkings.pem deleted file mode 100644 index baeb882d811..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/draftkings.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFLDCCBBSgAwIBAgIHBEK/bqLmmjANBgkqhkiG9w0BAQsFADCBtDELMAkGA1UE -BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY -BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMS0wKwYDVQQLEyRodHRwOi8vY2VydHMu -Z29kYWRkeS5jb20vcmVwb3NpdG9yeS8xMzAxBgNVBAMTKkdvIERhZGR5IFNlY3Vy -ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjAeFw0xNDA0MjgxODIyMDlaFw0x -NTA3MTMyMDI0MDlaMD4xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRl -ZDEZMBcGA1UEAwwQKi5kcmFmdGtpbmdzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBANGdW/XXPUTqrbTkDwOEKD4aN7t6qdo6kbyVeozX0WXfSuVG -JoFPnHYRc1NBlgRpz+2fcWJaAm61IRg2OGVbgM86JqI1B4/TnjHTgHqtxiu8oyKF -mAJFV15ZEqdKa4sDgx+HWUgLIljsF4BjSgXLdFKY05pBnNOxMEgrypZUE3sAKRcZ -WUOJUsL7fLi+mjtbCtzvaO5zpMpmsSlodvt481i1nhQauh4mpGimxWXuvJp49uuz -OnVwmaB3JiBk8QeOTbIfzjvbW0yO/8nTL3z75oZRll/mKhxhYruRLH2s/Fnfad3c -KRZTHVAwGeU75CHeu5EhCwIDYWrOrF33P5ShR/kCAwEAAaOCAbYwggGyMA8GA1Ud -EwEB/wQFMAMBAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1Ud -DwEB/wQEAwIFoDA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdvZGFkZHku -Y29tL2dkaWcyczEtNDkuY3JsMFMGA1UdIARMMEowSAYLYIZIAYb9bQEHFwEwOTA3 -BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv -c2l0b3J5LzB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw -LmdvZGFkZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRpZmljYXRlcy5n -b2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSMEGDAWgBRAwr0n -jsw0gzCiM9f7bLPwtCyAzjArBgNVHREEJDAighAqLmRyYWZ0a2luZ3MuY29tgg5k -cmFmdGtpbmdzLmNvbTAdBgNVHQ4EFgQUkF4a4BpBmRLNfTDDir3K9m++N3AwDQYJ -KoZIhvcNAQELBQADggEBAGU/LaXNXEyagwZxxDOTJHRH6CUofPwvJJiIIfF3ANLz -ulFb4H9ap38X/rOnIZHJHUjYVGBhVfwFfhhJHXjQHm+V9ixHYNIVPeCifAQw0xE5 -V6M79+9BbuRvrKNF7mI60gtY2JL/L1L+Uj1R2VX2velw2GSMr6fyJdwq5N4cfmwf -QP0LRkyHOn6wMX74mYzPQ/51OQi9pzvKPXJE8vwUi1rKvAiViqivXbCLiisdx13h -5/BOx8fUjLSew66QJLjU8laZDK2bIzEf2JczLuY92yyS2ifgLyalKieY6y10y/O+ -4TWjhNY5msjyIqXeLXwAO1CjRZzFIv/li+HXka6qAFQ= ------END CERTIFICATE----- \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/firstdata.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/firstdata.pem deleted file mode 100644 index 9c4842f4be6..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/firstdata.pem +++ /dev/null @@ -1,94 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFjDCCBHSgAwIBAgIQTeNLe9jcoRyAtFeMsEB3/DANBgkqhkiG9w0BAQUFADCB -tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug -YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMm -VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwHhcNMTQwOTA0 -MDAwMDAwWhcNMTYwOTA0MjM1OTU5WjCBsjELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0dlb3JnaWExEDAOBgNVBAcUB0F0bGFudGExHzAdBgNVBAoUFkZpcnN0IERhdGEg -Q29ycG9yYXRpb24xNjA0BgNVBAsULUZpcnN0IERhdGEgUkFTIChSZXRhaWwgYW5k -IEFsbGlhbmNlIFNlcnZpY2VzKTEmMCQGA1UEAxQdZ2xvYmFsZ2F0ZXdheWU0LmZp -cnN0ZGF0YS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCunuir -5P0VQDraZ+iHqz1XItS2sEKCNoG23eWz1Xh87GSPYtrBgOXznNo079ruf48vY5da -KKs6YhjMsOXhJrA0kGfsq3/0WPLZjlWzFdM/0NMdV/Z9iYzBPkrR6Hz64sNGBnEP -BWYvpblmchtyUWhuy58W69VoufYUJMnmbBj1OxPufI97AXdoaoFapMYbaHKdqBJy -2lLmqDalR7oYb4dnZvZY/arEAstLULCAn36X1O7/dKQQXxtmUkUS4XZj26pHEmIJ -5ld4ERZJU67AnKimk5nXmlGWIJPpOo9Aw/0Lwx3BCDN4eC7hPiL+atgtLBKHxy1m -HaWLSdXOLCvrqZKnAgMBAAGjggGXMIIBkzBJBgNVHREEQjBAgh8qLmdsb2JhbGdh -dGV3YXlFNC5maXJzdGRhdGEuY29tgh1nbG9iYWxnYXRld2F5ZTQuZmlyc3RkYXRh -LmNvbTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEF -BQcDAQYIKwYBBQUHAwIwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYB -BQUHAgEWF2h0dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0 -dHBzOi8vZC5zeW1jYi5jb20vcnBhMB8GA1UdIwQYMBaAFA1EXBZTRMGCfh0gqyX0 -AWPYvnmlMCsGA1UdHwQkMCIwIKAeoByGGmh0dHA6Ly9zZC5zeW1jYi5jb20vc2Qu -Y3JsMFcGCCsGAQUFBwEBBEswSTAfBggrBgEFBQcwAYYTaHR0cDovL3NkLnN5bWNk -LmNvbTAmBggrBgEFBQcwAoYaaHR0cDovL3NkLnN5bWNiLmNvbS9zZC5jcnQwDQYJ -KoZIhvcNAQEFBQADggEBAEhlHPB7R1QwmpQPG1JzplryKqJ5fYZoPEiF3qfSoB+6 -cKJ8Xkhg7uga+/ZH55lErVIbWZjxIxtImAOYnQjm8uWiW8ElrbS42plUkNCk/tuU -X7JcomwCaeE4dUrHF/pe9ao6SOh5KXCZGr0HyY64MOvdxOy6RXTsjDeabwI8CeNn -LauoOg9Ey9hl2Dmv+iAY9ANtb+4nMLQoeH3HPfUpaeIUaCm500RKiEw3pjvWRpwV -5HC7RoWa9tyK/7AvMNbXLfURmhO5/MJ9iUjrSdwJOfryscSSPPrGdrgeKTufn4qu -n7W3DwNqap9Cog4hn7KZJXNaNA0qjB54UPEERcd0bTE= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy -aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG -5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8 -f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK -tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo -GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV -M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB -2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz -aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4 -RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw -czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG -A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu -Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp -bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo -dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w -GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+ -HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ -KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB -WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6 -bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp -dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg -W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4 -Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT -LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw -HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv -ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 -RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb -ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR -TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH -iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB -AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 -dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 -BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy -aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI -KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU -j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t -L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v -b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC -BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA -A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K -lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ -tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/ ------END CERTIFICATE----- \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.csr b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.csr deleted file mode 100644 index b8f274fd092..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.csr +++ /dev/null @@ -1,10 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIBezCCASECAQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl -MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh -bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMR0wGwYDVQQDExRjbG91ZGZsYXJl -LWludGVyLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLgOKlWwIAIeURde -yvDMhgfn6xPp1gn8oUeLmsniBm7I+j84IsVzUso8/MpjMZ9nB8lQUanhv3Kmqcyj -HNj+iFegMjAwBgkqhkiG9w0BCQ4xIzAhMB8GA1UdEQQYMBaCFGNsb3VkZmxhcmUt -aW50ZXIuY29tMAoGCCqGSM49BAMCA0gAMEUCIEJcy2mn2YyK8lVE+HHmr2OsmdbH -4CLDVXFBwxke8ObqAiEAx/il1cDKvQ/I36b4XjBnOX2jcQ5oaCNPFFBE74WQ/ps= ------END CERTIFICATE REQUEST----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.key b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.key deleted file mode 100644 index 156aec3c833..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.key +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEILbwI4u4bw+HtafMqFnrL7LOrqNEZH5rW5ygSrigfrVLoAoGCCqGSM49 -AwEHoUQDQgAEuA4qVbAgAh5RF17K8MyGB+frE+nWCfyhR4uayeIGbsj6PzgixXNS -yjz8ymMxn2cHyVBRqeG/cqapzKMc2P6IVw== ------END EC PRIVATE KEY----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.pem deleted file mode 100644 index c626d86606e..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L1-v2.pem +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICwzCCAi6gAwIBAgIIOdnmLRHpa9owCwYJKoZIhvcNAQEFMH0xCzAJBgNVBAYT -AlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2Nv -MRMwEQYDVQQKDApDbG91ZEZsYXJlMRQwEgYDVQQLDAtERVZfVEVTVElORzEWMBQG -A1UEAwwNQ0ZTU0xfVEVTVF9DQTAeFw0xNDA1MjcxNzUzMjhaFw0xNTA1MjcxNzU4 -MjhaMIGMMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UE -CxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzET -MBEGA1UECBMKQ2FsaWZvcm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5j -b20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4DipVsCACHlEXXsrwzIYH5+sT -6dYJ/KFHi5rJ4gZuyPo/OCLFc1LKPPzKYzGfZwfJUFGp4b9ypqnMoxzY/ohXo4GG -MIGDMA4GA1UdDwEB/wQEAwIApjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH -AwIwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUwsdbMieQ99qPYmlsL5L8 -2HWQyakwHwYDVR0jBBgwFoAUuF7vrmdQt9bzB+VqvlWzZzoNkj4wCwYJKoZIhvcN -AQEFA4GBAIyZZ7dPQsDKLR+ZwDXjSdsTws+9mZvqzfTb89LJ7H1pEoVI0x+MQncG -zbsN713Vu2GCBHZilmfINsBbZYdaqqVTpqLtAFMce7aBiLrpcLHyegzTJIn+zzMa -v5498Mo7S8NUOeGtTAPepExf9lOxiexynEkk5U+AF04nzspNOwTY ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-1.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-1.pem deleted file mode 100644 index 3be24fa17d8..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-1.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZTCCAk+gAwIBAgIIQTLl8XrmJF0wCwYJKoZIhvcNAQENMIGMMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwOTIzMTc1 -NTI4WhcNMTUwNTMxMTgwMDI4WjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs -b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs -b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw -f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P -IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo3sweTAO -BgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgw -BgEB/wIBATAdBgNVHQ4EFgQUPd/cWIaY6MopIO6ldKx79dLpF1cwHwYDVR0jBBgw -FoAU111IKWksDvRzq0AcRqjjkhR7BxAwCwYJKoZIhvcNAQENA4ICAQAz96PKFCed -WSwOchAQszXDzaIcKSyyA1DQYEn5LvDTAcMgHg0KSb9bArv40ctwwvWQKwb9M4+M -ax1+xmZi7Vg9wjad4Pz+UHDxf+rnEAFBuN6dneNpv1J9qxK1yf9GkMsl10CGeh0x -AkHOut5rbb2hL0OrLOxhUK5M7pJf8zCMIirz9MHBDC+Xy4IKfEh8s4sKc2XRjnKv -/H2tjcUL9AP8c7AA3GPoMuMVZSygI3SmH0gu+wQcR3KQCnetvObqNoI/DEv+45pI -2B7CAf5FVhErqM9Gq2IuQQt9/7YosxL+wTvVNobKYmwP9NWFVtkJYpF1I63LtnaJ -+MN9b/fVYDjI9IBKXFD10eec2CZkUEj13bWOgIN1gwyL6IzXPOaT/oax/TVlMIpI -q3YnjMCEVS09sp2zAuLMYd97G8CMaRtGrtJM5V4rZ5l5u0w0So8FJac3pYugRm3V -udpPNUBkR4FPMCMUGExJWNADooDXs31UxPQXMdcRai8Gb1mZQGyOhQQJgH1MsoYY -f4OFvwvWsWlKL063Jc+a31fLs6LaH+4AVDyYgfBT5SyK9jQEr1q3HSGyzs7K48iP -MEBWnfd2VOyoUdbENab5vZo5ewnj79xp7Qbcugduu2phs0oxp1737fS13BgdpDdQ -9eueSTt1QsRE0SShMG5VqewfxQNk5BYrYg== ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-2.pem deleted file mode 100644 index 71cd0cf03af..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-2.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZTCCAk+gAwIBAgIIQkDSA6gKNdAwCwYJKoZIhvcNAQENMIGMMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwOTIzMTc1 -NjEwWhcNMTYwMTAyMTgwMTEwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs -b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs -b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw -f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P -IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo3sweTAO -BgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgw -BgEB/wIBATAdBgNVHQ4EFgQUPd/cWIaY6MopIO6ldKx79dLpF1cwHwYDVR0jBBgw -FoAU111IKWksDvRzq0AcRqjjkhR7BxAwCwYJKoZIhvcNAQENA4ICAQCi53nUiAaE -aHSpCkebgcktFfDTTsY/7YCPFv0RxE08f+OMzndWpoS6dFYCxP1HetlYOh5a/3wm -9zj2IL6rY7CXyI6x2RH97Sdc4ibjcIqHdUuaFmG+qwjtI8TGeOFvwrdwx6i610Mc -cLqgc3gvtcLeqbMFkA0/js+viMg+bMTR+cEEIT3MHMq7byOzQa+koia9ZLAdiZsj -IkWGTg5tkySnwyQztLRjWknZ1syujarcoJ9VY8uWipQNMzrs91ZaAwHmeSdODsbn -Wvg7HZInbxCIzQz1/65FhdHzPbOv8MmQ1wlHqNNPYehXOgptsv9GN+DJlhiM62dp -tTRJnc3URyP4xfkVWtYXxuGBdGXPaktsNFBb163QJtrajAe9FtBqsIEUDDuUjNB1 -rbw7xYUW5byiMPA1auHU3CHXg86LwU3TpE0d5hZriNCKzfLSpWJZa3WmQ0bc1ZLC -1m3EhK0fDqGz+NbyP7eyJl1nUGwElbhbHaK1HpopxtGKKi1xbMTjpU2Ery8bUXcK -EsUJWsxb8yU6BC25+ZWcHeuTaeSK+zlk/kvyMXgueslAoWUznmNhrLrTX3Ansjrf -MT1eo/cy+OU5FJslmhV0lhMy2W/lsAUqTGugMP2x1lhUnKy3/17XULh8v6BfmddR -XpQy1L6IceNMPfsKCvt5pg3urtpunV8ImQ== ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-3.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-3.pem deleted file mode 100644 index 2ff7807435e..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-3.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZTCCAk+gAwIBAgIIbHgGsniC/IUwCwYJKoZIhvcNAQENMIGMMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwOTIzMTc1 -NzE3WhcNMTYwNjAyMTgwMjE3WjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs -b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs -b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw -f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P -IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo3sweTAO -BgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgw -BgEB/wIBATAdBgNVHQ4EFgQUPd/cWIaY6MopIO6ldKx79dLpF1cwHwYDVR0jBBgw -FoAU111IKWksDvRzq0AcRqjjkhR7BxAwCwYJKoZIhvcNAQENA4ICAQDkbiOxZ4Pq -y6TrubrmTwcRLLSDcXi8WeWv2AG6nAqZWAJXi/eUFggzNNgvAt4B/VH81YCkRN7R -YAefVztVSRxffOFTEk8PDQ55pthTbCdnaeJL1dP7PGZ7Dg1djxSC9G2jJ38xFQY3 -5aM7BwbFcs5Iqd9MhbJIhrJfL22O5XpTTWzHGLOsS4H42If9qkTtajjMPwMbPUrZ -jJj6bWyOqfuGKef/Orn72EV9fPwyrLoTg9TPlKqX9ghm7fvuc9UVcEbFOAVSV9lS -3mEct1uwLBAEi/xhOlGN7jOn6q/w/0h2CI04FUe3/HB5rR0ffbqc2AdjO2R5uMgl -9XQ+u4/kOE5hHha8cSNSyScRiWr3yrG+3TaX4qdKnVUdP0LcoKZBm7+JYqTqsW5U -jr+sQmJrvWcEMx9Q5+5krDRhTWmyd4V27zgZ5T5Ilv3TC3zZ+VjJASKEHPFrClae -PdwkBdhxJRaXhkku7slW9Dgw4E0/0el2iytODoikzwcdlQQwQhvAnbtrJOhsXX1b -OpSQGfSZerAsuYSpiaNygF39HKxzgeZAEI5H+0R048Fcpysq8KVIET2B78zn0+mx -nSNOBP3SDLMcvlXDALpD6svSzQKuoQ1gyZUZzrJanbNJgA1gg2dQyEs13xhS8Vuc -Jtq40kpRnc9Pr3LNTL4Z95xMMqxYRBc3Xw== ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-4.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-4.pem deleted file mode 100644 index d202e376381..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-4.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZTCCAk+gAwIBAgIIfwUOgDbzUY4wCwYJKoZIhvcNAQENMIGMMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKQ2xvdWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdp -bmVlcmluZzEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZv -cm5pYTEdMBsGA1UEAxMUY2xvdWRmbGFyZS1pbnRlci5jb20wHhcNMTQwOTIzMTc1 -NzM1WhcNMTcwMTAyMTgwMjM1WjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkNs -b3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5lZXJpbmcxFjAUBgNVBAcT -DVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3JuaWExHTAbBgNVBAMTFGNs -b3VkZmxhcmUtaW50ZXIuY29tMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEIVkjNJGw -f3F0XWJH7yQSVtxuoBidi5JNsQ7FhxEQcZEl3b+/1iF60TBY2Yi6KwJuA6nIE73P -IXGyfNhThw4D8CiZbackQ/ufgz2DyvxyWFDPzLr7TXeM/0wSp/imoxWeo3sweTAO -BgNVHQ8BAf8EBAMCAKAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgw -BgEB/wIBATAdBgNVHQ4EFgQUPd/cWIaY6MopIO6ldKx79dLpF1cwHwYDVR0jBBgw -FoAU111IKWksDvRzq0AcRqjjkhR7BxAwCwYJKoZIhvcNAQENA4ICAQAyTpWzbiOa -cB6FIsfRCGpqKZiaNMeuaJr8RPDYgXMAU4pK0ymZfZPWcUDDsVLEt5Zz4fJBd4E1 -UzJ0GuuFswhGoICmYF397akwfOnXcbV+TBjdPPtsnsq71jRFlswdf6HkGqdQfMls -x6JnkM9XXDlWqKoVV8sHhnfvDOD5xZv2nLhIwBzt3dnrkhAKAI9jncHuJWO0KaxW -n8KhrAuoerQAz3+VM0y30siSAs4tBgmrKIc8AFh/S72VHUzBAnlc00LYE4M26/fQ -28EJzy01F3uuHHyRn56uQ/miWT5ttPxdUneN4SzQV7oB3ij6W9+QIrK0/uDMhw7l -NLk3nyj9V+XYbgynpgB2N92BK0MNYI9Jp0ULFgrAQaGadoo4XfDquQulWx8c7Zo+ -/qpcjnAVy317LjvWZbdGu/rBEU6j7rMOKqRcmjkm+7ESuLv6OOj4JVMtvSEdtpPL -MK4mNAYa3O8qJMphjwokseF+9AfpBEJJzFFYiV7LyjFZlexSFOE1XZ1i0KaR7k+0 -RxbBxz9ciovhYgDr9db3jQqcU8UR8mIgxcpqmWFinNmZ0Sr0/pkXyZzZPUmH99bD -vZEsmuFsEv1r+/7BAaPtWFnXwaacFkdEpVOKq5VJtNXMvAgYt7RJQobTDFFIMTaN -j4NKTmOqq1CTnqNmxPZqAyDotTucUJAbRA== ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.csr b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.csr deleted file mode 100644 index 232fa779831..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.csr +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIIDCjCCAfQCAQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJl -MRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2luZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJh -bmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRcwFQYDVQQDEw5jbG91ZGZsYXJl -LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOLFLykOd2j31AQn -kaToYtstGvw5wLb4YnlzipQ6aULlD0H0GHM9IwhdSmcTWUWPb/U83g/ma1uD3Pp2 -IdWd6xfjyOJF5XhgkyfRY65wS6vPZRm2MNSFXem+0AKHdhxIhb/QPMASqC/yaiPi -nvtOpBiCNl1Q2N4y9pkV0oD/T4rrn3RXP6iL1k4CNRS54JPCd+aI5Om+axVPU8Id -ZeUXQwXISaFrcC/bFXAHGX5hBMVu34lhCxvR4smweZkVmW++bIv26az8TSb5nVn4 -TstLJIaOoOqot0sis04+0oX/GXfTPfkWyzfTVFN7cb9H+gz0FZJKtXQZv6qdntji -9FdR+pkCAwEAAaBAMD4GCSqGSIb3DQEJDjExMC8wLQYDVR0RBCYwJIIOY2xvdWRm -bGFyZS5jb22CEnd3dy5jbG91ZGZsYXJlLmNvbTALBgkqhkiG9w0BAQsDggEBABfM -9XTMqMqmfAAymWC4/W+vbh301KBoydcTnDQ/7B+ftHRE0O3FUsdL3wobj3qBieJo -MiQwiL7+GksszHvN9+YOUi70wpFuKghLhadb7p5GzL0+JgK2eQnLYb37/lQSiWwn -hht1YMOzErR/KHlxNUafk71bDEeytUcOvvtujf86nZiEnBpvp47zDjMkDersczM0 -wj7S50IY8/vRsc2Q8vy+Q7D2FPEwjs4wCGVSqzwX2NPn3fZb/2pWRCie9kxHUfUP -L5xO4WoFGuirT6E2GnUWDdH661Pj5yEKvmr+qPl+eVoLjrtx0g5rAmA7rGlGrkqp -r4idH/BbJUaDlRHM/Hk= ------END CERTIFICATE REQUEST----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.key b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.key deleted file mode 100644 index 36ecabb1afd..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEA4sUvKQ53aPfUBCeRpOhi2y0a/DnAtvhieXOKlDppQuUPQfQY -cz0jCF1KZxNZRY9v9TzeD+ZrW4Pc+nYh1Z3rF+PI4kXleGCTJ9FjrnBLq89lGbYw -1IVd6b7QAod2HEiFv9A8wBKoL/JqI+Ke+06kGII2XVDY3jL2mRXSgP9PiuufdFc/ -qIvWTgI1FLngk8J35ojk6b5rFU9Twh1l5RdDBchJoWtwL9sVcAcZfmEExW7fiWEL -G9HiybB5mRWZb75si/bprPxNJvmdWfhOy0skho6g6qi3SyKzTj7Shf8Zd9M9+RbL -N9NUU3txv0f6DPQVkkq1dBm/qp2e2OL0V1H6mQIDAQABAoIBAQCzT3HcCAlZoeUu -p88dU3efkUnuOQhuZXcQS9E/JfTHpXHsF8Qhky0ZVxMW8BC91Q6VHt0EO5GWWm0o -SrK0Q9t6F25npRcumUaizIoCi9756tMpgouX8CDzTCMUbOJyuNGxe0oeImKFDyzo -VTCazHMqwgOUw/HHuQqOv9ekkrzlva8U+Z5MGZB4B2acHIAJHO9uYGzdeAjF3grm -dQ3QFGXJM0JzPmXfnUiDeOWIoVbo4YROFhf7qNlcnyLdkrYe0/XsSYQM9dRGKRPK -nkOkMv0sC8rOqNuJUn3tf1OOjzVQxlzB8Key6MOQ1c+kqsdCnL88/93CvI5NHazx -hwUmesmBAoGBAPpkDtgeWjxeIjOfuxXDYb04XbVmKquKNOIEk5OADmaacSGzdemh -XLRaNVMEYMcgMJViDDKW8g4k+zuZgzooMxNynlLNU5wfazwX2LLjReJFvZb/SxMM -N9+vQo8fcGz+p5g1tbeE6w86mpsTiAGx9Wa4J4GnY8jF6XUjZHO0X91pAoGBAOfZ -qrDkPMDSiVk62FP6LlPrj09bt1NTkBfv5dWhN/XeHjuus7unDhNiRmphhgF0VZse -XPtT/PUO0YgYlyaYJDDDE0IxgHuoK9wvEb2sqEtkZSw7IUhehheZ/+YfXzSA5fwa -vhXt0ghB0d9oVJuRoxb17MncjpjDAKy0QR5drR2xAoGBAMlNwkVseZ2JDLQ2WgHQ -N/cZpvUc83dAQO3pQgBW9rz0s7mlf0naqh5xW+enYGsW7RhcYHQXuPk4MCelbsRF -53JeNv1ZCDw/YkZI4bZIVDnrWdZY3zGsJAuY6skIPKnUPkd3/uVRXm267ut4U2MR -gLsZmOF7AxU6UEwVrT/8pwnpAoGAKxbVFlMUx3FZfW/mTJUujwI0fDc7dw0MtqYr -POzdjaBeVhE97h46C3g0Rgkh8ptAXbfi6ALP/GtonbaUQOP9teJLbf3tNw4mOKG2 -1l2EWZ6q/vFuWhjXKwO//3DNLODX3WbK9SBh7I7vBmpJbzA980J5Y3rONa3oLjDB -+XbHecECgYEArOEv2D3fE3Hd6rEbxXinqekxMa+V1OCDO1IPz4wwr9RDMVUMxwqF -f0es1PQ2eMJGrAMbySxPfSZG05ou/tA+zR0qPwc/+dX0BbaXCiNT3gbhvL1L2fBc -7wr+MIUe2fi54JUWrUNMDHngRhXRKt2rZZRTfqVaFmZX02Y3fMZ2dWg= ------END RSA PRIVATE KEY----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.pem deleted file mode 100644 index 3b632524033..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/inter-L2-v2.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDXDCCAwKgAwIBAgIIfTkIXBckiQ4wCgYIKoZIzj0EAwIwgYwxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2lu -ZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9y -bmlhMR0wGwYDVQQDExRjbG91ZGZsYXJlLWludGVyLmNvbTAeFw0xNDA1MjcxNzU1 -MjZaFw0xNTA1MjcxODAwMjZaMIGGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQ2xv -dWRGbGFyZTEcMBoGA1UECxMTU3lzdGVtcyBFbmdpbmVlcmluZzEWMBQGA1UEBxMN -U2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5pYTEXMBUGA1UEAxMOY2xv -dWRmbGFyZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDixS8p -Dndo99QEJ5Gk6GLbLRr8OcC2+GJ5c4qUOmlC5Q9B9BhzPSMIXUpnE1lFj2/1PN4P -5mtbg9z6diHVnesX48jiReV4YJMn0WOucEurz2UZtjDUhV3pvtACh3YcSIW/0DzA -Eqgv8moj4p77TqQYgjZdUNjeMvaZFdKA/0+K6590Vz+oi9ZOAjUUueCTwnfmiOTp -vmsVT1PCHWXlF0MFyEmha3Av2xVwBxl+YQTFbt+JYQsb0eLJsHmZFZlvvmyL9ums -/E0m+Z1Z+E7LSySGjqDqqLdLIrNOPtKF/xl30z35Fss301RTe3G/R/oM9BWSSrV0 -Gb+qnZ7Y4vRXUfqZAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgCmMB0GA1UdJQQW -MBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEBMB0GA1Ud -DgQWBBR9vuLqsiu6H1S6qG9JmUSh687mqDAfBgNVHSMEGDAWgBTCx1syJ5D32o9i -aWwvkvzYdZDJqTAKBggqhkjOPQQDAgNIADBFAiA1sNmHjK4MF0USUIYiCBINpG3b -G8zRSWc5mEwCVCCGGQIhAPuTm12Hnmc6PUMmS12uQoz+UpQ536lYpHqLoe/yZHDk ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/lazada.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/lazada.pem deleted file mode 100644 index 7afddd7c8eb..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/lazada.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFMzCCBBugAwIBAgIDESgIMA0GCSqGSIb3DQEBCwUAMDwxCzAJBgNVBAYTAlVT -MRcwFQYDVQQKEw5HZW9UcnVzdCwgSW5jLjEUMBIGA1UEAxMLUmFwaWRTU0wgQ0Ew -HhcNMTQwMzA5MDcwODA2WhcNMTUwNDEwMTkwODU3WjCBvjEpMCcGA1UEBRMgOWRp -eGpNZTVGQS9Fd0pjMWxhM01IQ1JBOTNnTFZobkoxEzARBgNVBAsTCkdUODM1NTg5 -ODAxMTAvBgNVBAsTKFNlZSB3d3cucmFwaWRzc2wuY29tL3Jlc291cmNlcy9jcHMg -KGMpMTQxLzAtBgNVBAsTJkRvbWFpbiBDb250cm9sIFZhbGlkYXRlZCAtIFJhcGlk -U1NMKFIpMRgwFgYDVQQDDA8qLmxhemFkYS5jb20ucGgwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQDKlGxmI33lQbcQHI5Fhf6EQGoqVVmHYRU5whipFg5g -BButLAPj8TTDgD6a1iKPDsnQvNZnVjKLnjAu8c/lwwF7GevfuAS/SXasmKiONJ1b -w+/MPWia/j++AoGIwKJe6py6r9INy3rTFrwuzSemzTnAja/VYtMPiAR/tAIK8FmU -JZpop8JvGMr0KpmCBrJ4/HxFQwlmJjjSuvronNtN3h10vX1vNXCyobwaL2UplY8c -0QZv6PdS8gzdki4H5AwOSnzJiY6RJPH6qR9dotQFYvSEHwUACHp7AOKkhdtO/+fG -rd0+0vXLznyhIGZjT+T8at1H3/1udBhUkoAc76Xlqu3FAgMBAAGjggG5MIIBtTAf -BgNVHSMEGDAWgBRraT1qGEJK3Y8CZTn9NSSGeJEWMDAOBgNVHQ8BAf8EBAMCBaAw -HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCkGA1UdEQQiMCCCDyoubGF6 -YWRhLmNvbS5waIINbGF6YWRhLmNvbS5waDBDBgNVHR8EPDA6MDigNqA0hjJodHRw -Oi8vcmFwaWRzc2wtY3JsLmdlb3RydXN0LmNvbS9jcmxzL3JhcGlkc3NsLmNybDAd -BgNVHQ4EFgQUWh9QqoLYcrJ8u85o7CXAemGUtKQwDAYDVR0TAQH/BAIwADB4Bggr -BgEFBQcBAQRsMGowLQYIKwYBBQUHMAGGIWh0dHA6Ly9yYXBpZHNzbC1vY3NwLmdl -b3RydXN0LmNvbTA5BggrBgEFBQcwAoYtaHR0cDovL3JhcGlkc3NsLWFpYS5nZW90 -cnVzdC5jb20vcmFwaWRzc2wuY3J0MEwGA1UdIARFMEMwQQYKYIZIAYb4RQEHNjAz -MDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMv -Y3BzMA0GCSqGSIb3DQEBCwUAA4IBAQA8NsDVERjLyQ8CjsF4IcE9jNjr0ryXMV2E -qLu27SAAp+walxOlf8RbZbwO7NxjiJi6Lubu0GOEVIrzqTzGta131dkKwmxVpSVq -LcOpHHqmQTv0WDYKjhNc5PhjhfpjLnK5xjhJsd6us/FT/VYaeeq9XEnjCTc9JME8 -DUWnE0DK+14pOgH/KAzIpQCUGRaWOZgXbFkptIhgKikqOd/otKBHy/JNvqOk9ugJ -zz+O5ZMBUZq3h7rDIjt/o+l4mv+f2DG1eiugOXLIukpMeK+ixM5b8uuprXqEK7oG -qTal86QTe9+E/2KbOO+jUmh5JNsQmkYZKm4foM7pk4bHXPWxUco5 ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/riot.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/riot.pem deleted file mode 100644 index c6f31f5de86..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/riot.pem +++ /dev/null @@ -1,45 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIH5TCCBs2gAwIBAgIQBVtqmc8x2tl8Fe1v9s7UoDANBgkqhkiG9w0BAQsFADBw -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz -dXJhbmNlIFNlcnZlciBDQTAeFw0xMzEyMzEwMDAwMDBaFw0xNzAxMDQxMjAwMDBa -MHcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRUwEwYDVQQHEwxT -YW50YSBNb25pY2ExGTAXBgNVBAoTEFJpb3QgR2FtZXMsIEluYy4xITAfBgNVBAMT -GGxxLm5hMS5sb2wucmlvdGdhbWVzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKpicFUVqYz1ArARQ5LoncPu14OhxYq9dYUJvm9tdKCdig7KQYDa -4SDo8cMiWPuxr3DB48ZeIOpZtF9VplDhdDGMnbifO8ohCiAuCITnP+ft+dLdcTeB -AW5M5l2MaLxj/vdCRzENPa7KbzS0jnd5WBIkwsgkh8E4OSrTkIfNK+kQiBMz+9Td -EHJagUvZ9vfTu0aSXx7+9bw/rDxCylWDbevYNBiBFMfgclhrW6NLlXBhbmRzxeY+ -lOScZdJkKoMGFXVaXsHh6BILdIypedCNrURBKWzFoke3y9dU8IPqgfdkvhm1aQXv -EdLo/gh+GMbaYK5ZFBYhneX/MQIqMNpoBZcCAwEAAaOCBHIwggRuMB8GA1UdIwQY -MBaAFFFo/5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBQXUcvgDtxEapXyIy30 -2IYF6jYhvjCCASgGA1UdEQSCAR8wggEbghhscS5uYTEubG9sLnJpb3RnYW1lcy5j -b22CF2xxLmV1LmxvbC5yaW90Z2FtZXMuY29tghlscS5ldW4xLmxvbC5yaW90Z2Ft -ZXMuY29tghdscS5rci5sb2wucmlvdGdhbWVzLmNvbYIXbHEuYnIubG9sLnJpb3Rn -YW1lcy5jb22CF2xxLnRyLmxvbC5yaW90Z2FtZXMuY29tghdscS5ydS5sb2wucmlv -dGdhbWVzLmNvbYIYbHEub2MxLmxvbC5yaW90Z2FtZXMuY29tghhscS5sYTEubG9s -LnJpb3RnYW1lcy5jb22CGGxxLmxhMi5sb2wucmlvdGdhbWVzLmNvbYIZbHEucGJl -MS5sb2wucmlvdGdhbWVzLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYI -KwYBBQUHAwEGCCsGAQUFBwMCMHUGA1UdHwRuMGwwNKAyoDCGLmh0dHA6Ly9jcmwz -LmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNlcnZlci1nMS5jcmwwNKAyoDCGLmh0dHA6 -Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNlcnZlci1nMS5jcmwwggHEBgNV -HSAEggG7MIIBtzCCAbMGCWCGSAGG/WwBATCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6 -Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggr -BgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAA -QwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAA -YQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUA -cgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4A -ZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAA -bABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAA -aQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIA -ZQBmAGUAcgBlAG4AYwBlAC4wgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQcwAYYY -aHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2Fj -ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZl -ckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBzj+qBxGES -JBeOuJo2rc2xT8ezNT2l+Kg/NjSr65t/U+u6xMELufGF/fqWPzsfHT3CXHMiAW2P -lVHejbaePfkeNxHbkaLa15X3+dGOXR04a2QTI4zdexTZ9Xsx8chQZA4bEradIVl+ -o2y+MPN+6Hr1g2M2aw2d+1xxvVQcNe2iQDfUWSRd70wt8DXnpqFCumlCwZfYojpk -NQ/ahCg3AKu/3gQPgjyXB7HUf14M8x6PwNw4IK0LCC99HaqQID/V4jVw47beJ6FC -7+dW9nkrZBRgIHnqah90El+75oqwAmW8rewmTOKAXxRafGK6WreAZ0x9qfbBXFiH -VRL8HkH3gqBT ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/sgizmo.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/sgizmo.pem deleted file mode 100644 index bbf0aedfb82..00000000000 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler/testdata/sgizmo.pem +++ /dev/null @@ -1,30 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFLzCCBBegAwIBAgIHBJgUJzNPaDANBgkqhkiG9w0BAQsFADCBtDELMAkGA1UE -BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY -BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMS0wKwYDVQQLEyRodHRwOi8vY2VydHMu -Z29kYWRkeS5jb20vcmVwb3NpdG9yeS8xMzAxBgNVBAMTKkdvIERhZGR5IFNlY3Vy -ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjAeFw0xNDA0MDkxNjIyMDlaFw0x -NDEyMDQxNjU4NTVaMD8xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRl -ZDEaMBgGA1UEAwwRKi5zdXJ2ZXlnaXptby5jb20wggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQC+U1kaSViTxGfD5U5krfafN9+4jSq51CNnTZJY1CTJjihb -ym8n1ZNVrrCvivcGHT0BMHzDLVnQ2VLcac1F7TkjT5OCL5neSGLS6fnjoR5lPIvU -KZfG94hPAMXXjqc3/cpDEenQv2JaNDL6r/f4fNzGalqSf5IkPvg0GxX2knWhjwTG -f8cO+z08fKKKGt0tDt5/Dx6rxuqLxSg/eQhTU/QUUObuMeQCXtGfbC4n/sQJz0O5 -It5+EofG+KYb4gxJf/aScJv1PRSlSy9wYw6TJoUEn905VsFMH/mJuThzw5H976Vn -Vchh5fUJItlU5T2kVRAnuLF0dI3unl+fx5h+cEXPAgMBAAGjggG4MIIBtDAPBgNV -HRMBAf8EBTADAQEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNV -HQ8BAf8EBAMCBaAwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nb2RhZGR5 -LmNvbS9nZGlnMnMxLTM4LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcBMDkw -NwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVw -b3NpdG9yeS8wdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz -cC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0ZXMu -Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAUQMK9 -J47MNIMwojPX+2yz8LQsgM4wLQYDVR0RBCYwJIIRKi5zdXJ2ZXlnaXptby5jb22C -D3N1cnZleWdpem1vLmNvbTAdBgNVHQ4EFgQUogJIgFe3mwaqFPDUiPyEd+JcDi0w -DQYJKoZIhvcNAQELBQADggEBAF+Lu4aZ7JJmxHUY7w+fAxH8iBdMH5zwyjDWEFmP -quUuoy7G+1V5cFecKbXk9iYUgazygDETa2UP8wBWTS6V2RYL/PsF9+HdwOX0e9QA -JxZQ0ry9MZU72H1ZeIDRYGHqKOLMqkLIsbpSyDD6GyRNzLvZx7MiwDJ8Ou5wAT/6 -is5Sga9DZ/ffXbg79Ku0yalDwQfimHDAHRQhoYdCf6QhDog+RiNfSdJsU2NofiFu -f920or/2t9t9egCzXQHi3iPC979+eII0YAxnnHEQkndUvSoihVn625wqHetXpcz3 -zkQ5F7NVrR/giUHmVE6rpy4uuQ16cwBgMqoTzDBQ/0rs6lo= ------END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/bundle/bundle.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/bundle/bundle.go index 1f5e8affaf1..c177f171c9b 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/bundle/bundle.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/bundle/bundle.go @@ -1,3 +1,4 @@ +// Package bundle implements the bundle command. package bundle import ( @@ -9,23 +10,24 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity" ) -var bundlerUsageText = // Usage text of 'cfssl bundle' -`cfssl bundle -- create a certificate bundle that contains the client cert +// Usage text of 'cfssl bundle' +var bundlerUsageText = `cfssl bundle -- create a certificate bundle that contains the client cert Usage of bundle: - Bundle local certificate files - cfssl bundle -cert file [-ca-bundle file] [-int-bundle file] [-metadata file] [-key keyfile] [-flavor optimal|ubiquitous|force] + cfssl bundle -cert file [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file] [-key keyfile] [-flavor optimal|ubiquitous|force] [-password password] - Bundle certificate from remote server. - cfssl bundle -domain domain_name [-ip ip_address] [-ca-bundle file] [-int-bundle file] [-metadata file] + cfssl bundle -domain domain_name [-ip ip_address] [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file] Flags: ` // flags used by 'cfssl bundle' -var bundlerFlags = []string{"cert", "key", "ca-bundle", "int-bundle", "flavor", "metadata", "domain", "ip"} +var bundlerFlags = []string{"cert", "key", "ca-bundle", "int-bundle", "flavor", "int-dir", "metadata", "domain", "ip", "password"} // bundlerMain is the main CLI of bundler functionality. func bundlerMain(args []string, c cli.Config) (err error) { + bundler.IntermediateStash = c.IntDir ubiquity.LoadPlatforms(c.Metadata) flavor := bundler.BundleFlavor(c.Flavor) // Initialize a bundler with CA bundle and intermediate bundle. @@ -48,13 +50,13 @@ func bundlerMain(args []string, c cli.Config) (err error) { return } } - bundle, err = b.BundleFromPEM(certPEM, keyPEM, flavor) + bundle, err = b.BundleFromPEMorDER(certPEM, keyPEM, flavor, "") if err != nil { return } } else { // Bundle the client cert - bundle, err = b.BundleFromFile(c.CertFile, c.KeyFile, flavor) + bundle, err = b.BundleFromFile(c.CertFile, c.KeyFile, flavor, c.Password) if err != nil { return } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli.go index e5b00deebc4..052b41dafd6 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli.go @@ -1,3 +1,4 @@ +// Package cli provides the template for adding new cfssl commands package cli /* @@ -84,16 +85,19 @@ func Start(cmds map[string]*Command) { registerFlags(&c, cfsslFlagSet) // Initial parse of command line arguments. By convention, only -h/-help is supported. - flag.Parse() if flag.Usage == nil { flag.Usage = func() { fmt.Fprintf(os.Stderr, usage) for name := range cmds { - fmt.Fprintf(os.Stderr, "%s\n", name) + fmt.Fprintf(os.Stderr, "\t%s\n", name) } + fmt.Fprintf(os.Stderr, "Top-level flags:\n") + flag.PrintDefaults() } } + flag.Parse() + if flag.NArg() < 1 { fmt.Fprintf(os.Stderr, "No command is given.\n") flag.Usage() @@ -112,7 +116,7 @@ func Start(cmds map[string]*Command) { // The usage of each individual command is re-written to mention // flags defined and referenced only in that command. cfsslFlagSet.Usage = func() { - fmt.Fprintf(os.Stderr, "%s", cmd.UsageText) + fmt.Fprintf(os.Stderr, "\t%s", cmd.UsageText) for _, name := range cmd.Flags { if f := cfsslFlagSet.Lookup(name); f != nil { printDefaultValue(f) diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli_test.go index 9114c31d7b0..9619580fbfa 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/cli_test.go @@ -8,6 +8,11 @@ import ( var cfsslFlagSet = flag.NewFlagSet("cfssl", flag.ExitOnError) +// The testing style from this package is borrowed from the Go flag +// library's methodology for testing this. We set flag.Usage to nil, +// then replace it with a closure to ensure the usage function was +// called appropriately. + // 'cfssl -help' should be supported. func TestHelp(t *testing.T) { called := false diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/config.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/config.go index 8d951b20d48..882d3096e10 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/config.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/config.go @@ -22,6 +22,7 @@ type Config struct { IntBundleFile string Address string Port int + Password string ConfigFile string CFG *config.Config Profile string @@ -46,6 +47,9 @@ type Config struct { List bool Family string Scanner string + Responses string + Path string + UseLocal bool } // registerFlags defines all cfssl command flags and associates their values with variables. @@ -80,6 +84,10 @@ func registerFlags(c *Config, f *flag.FlagSet) { f.BoolVar(&c.List, "list", false, "list possible scanners") f.StringVar(&c.Family, "family", "", "scanner family regular expression") f.StringVar(&c.Scanner, "scanner", "", "scanner regular expression") + f.StringVar(&c.Responses, "responses", "", "file to load OCSP responses from") + f.StringVar(&c.Path, "path", "/", "Path on which the server will listen") + f.StringVar(&c.Password, "password", "", "Password for accessing PKCS #12 data passed to bundler") + f.BoolVar(&c.UseLocal, "uselocal", false, "serve local static files as opposed to compiled ones") if pkcs11.Enabled { f.StringVar(&c.Module, "pkcs11-module", "", "PKCS #11 module") diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/gencert/gencert.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/gencert/gencert.go index 3d2d4a82488..1ee43d84057 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/gencert/gencert.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/gencert/gencert.go @@ -1,3 +1,4 @@ +// Package gencert implements the gencert command. package gencert import ( @@ -52,7 +53,7 @@ func gencertMain(args []string, c cli.Config) (err error) { if err != nil { log.Errorf("%v\n", err) log.Infof("generating a new CA key and certificate from CSR") - cert, key, err = initca.New(&req) + cert, _, key, err = initca.New(&req) if err != nil { return } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey.go index 10060a4dc77..4bee7da4937 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey.go @@ -1,3 +1,4 @@ +// Package genkey implements the genkey command. package genkey import ( @@ -41,13 +42,13 @@ func genkeyMain(args []string, c cli.Config) (err error) { } if c.IsCA { - var key, cert []byte - cert, key, err = initca.New(&req) + var key, csrPEM, cert []byte + cert, csrPEM, key, err = initca.New(&req) if err != nil { return } - cli.PrintCert(key, nil, cert) + cli.PrintCert(key, csrPEM, cert) } else { if req.CA != nil { err = errors.New("ca section only permitted in initca") diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey_test.go index 5bc1f3fd0e6..bbdde7e5f20 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey/genkey_test.go @@ -1 +1,50 @@ package genkey + +import ( + "encoding/json" + "os" + "os/exec" + "path" + "testing" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli" +) + +func TestGenkey(t *testing.T) { + //testing through console + gopath := os.Getenv("GOPATH") + cfssl := path.Join(gopath, "bin", "cfssl") + testdata := path.Join(gopath, "src", "github.com", "cloudflare", "cfssl", "testdata") + + out, err := exec.Command(cfssl, "genkey", path.Join(testdata, "csr.json")).Output() + if err != nil { + t.Fatal(err) + } + + var response map[string]interface{} + err = json.Unmarshal(out, &response) + if err != nil { + t.Fatal(err) + } + + if response["key"] == nil { + t.Fatal("No key is outputted.") + } + if response["csr"] == nil { + t.Fatal("No csr is outputted.") + } + + c := cli.Config{} + + err = genkeyMain([]string{path.Join(testdata, "csr.json")}, c) + if err != nil { + t.Fatal(err) + } + + c.IsCA = true + + err = genkeyMain([]string{path.Join(testdata, "csr.json")}, c) + if err != nil { + t.Fatal(err) + } +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/info/info.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/info/info.go new file mode 100644 index 00000000000..b63b49410ec --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/info/info.go @@ -0,0 +1,103 @@ +// Package info implements the info command. +package info + +import ( + "encoding/json" + "fmt" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/sign" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" + + goerr "errors" +) + +var infoUsageTxt = `cfssl info -- get info about a remote signer + +Usage: + +Get info about a remote signer: +cfssl info -remote remote_host [-label label] [-profile profile] [-label label] + +Flags: +` + +var infoFlags = []string{"remote", "label", "profile", "config"} + +func getInfoFromRemote(c cli.Config) (resp *info.Resp, err error) { + req := new(info.Req) + req.Label = c.Label + req.Profile = c.Profile + + serv := client.NewServer(c.Remote) + + reqJSON, _ := json.Marshal(req) + resp, err = serv.Info(reqJSON) + if err != nil { + return + } + + _, err = helpers.ParseCertificatePEM([]byte(resp.Certificate)) + if err != nil { + return + } + + return +} + +func getInfoFromConfig(c cli.Config) (resp *info.Resp, err error) { + s, err := sign.SignerFromConfig(c) + if err != nil { + return + } + + req := new(info.Req) + req.Label = c.Label + req.Profile = c.Profile + + resp, err = s.Info(*req) + if err != nil { + return + } + + return +} + +func infoMain(args []string, c cli.Config) (err error) { + if len(args) > 0 { + return goerr.New("argument is provided but not defined; please refer to the usage by flag -h.") + } + + var resp *info.Resp + + if c.Remote != "" { + resp, err = getInfoFromRemote(c) + if err != nil { + return + } + } else if c.CFG != nil { + resp, err = getInfoFromConfig(c) + if err != nil { + return + } + } else { + return goerr.New("Either -remote or -config must be given. Refer to cfssl info -h for usage.") + } + + respJSON, err := json.Marshal(resp) + if err != nil { + return errors.NewBadRequest(err) + } + fmt.Print(string(respJSON)) + return nil +} + +// Command defines the commmand-line procedure for info +var Command = &cli.Command{ + UsageText: infoUsageTxt, + Flags: infoFlags, + Main: infoMain, +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspserve/oscpserve.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspserve/oscpserve.go new file mode 100644 index 00000000000..c9060738c90 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspserve/oscpserve.go @@ -0,0 +1,52 @@ +// Package ocspserve implements the oscpserve function. +package ocspserve + +import ( + "errors" + "fmt" + "net/http" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp" +) + +// Usage text of 'cfssl serve' +var ocspServerUsageText = `cfssl ocspserve -- set up an HTTP server that handles OCSP requests from a file (see RFC 5019) + + Usage of ocspserve: + cfssl ocspserve [-address address] [-port port] [-responses file] + + Flags: + ` + +// Flags used by 'cfssl serve' +var ocspServerFlags = []string{"address", "port", "responses"} + +// ocspServerMain is the command line entry point to the OCSP responder. +// It sets up a new HTTP server that responds to OCSP requests. +func ocspServerMain(args []string, c cli.Config) error { + // serve doesn't support arguments. + if len(args) > 0 { + return errors.New("argument is provided but not defined; please refer to the usage by flag -h") + } + + if c.Responses == "" { + return errors.New("no response file provided, please set the -responses flag") + } + + src, err := ocsp.NewSourceFromFile(c.Responses) + if err != nil { + return errors.New("unable to read response file") + } + + log.Info("Registering OCSP responder handler") + http.Handle(c.Path, ocsp.Responder{Source: src}) + + addr := fmt.Sprintf("%s:%d", c.Address, c.Port) + log.Info("Now listening on ", addr) + return http.ListenAndServe(addr, nil) +} + +// CLIServer assembles the definition of Command 'serve' +var Command = &cli.Command{UsageText: ocspServerUsageText, Flags: ocspServerFlags, Main: ocspServerMain} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspsign/ocspsign.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspsign/ocspsign.go index 38a07df13c3..ee7fd8658e2 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspsign/ocspsign.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspsign/ocspsign.go @@ -1,3 +1,4 @@ +// Package ocspsign implements the ocspsign command. package ocspsign import ( @@ -10,8 +11,8 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp" ) -var ocspSignerUsageText = // Usage text of 'cfssl ocspsign' -`cfssl ocspsign -- signs an OCSP response for a given CA, cert, and status" +// Usage text of 'cfssl ocspsign' +var ocspSignerUsageText = `cfssl ocspsign -- signs an OCSP response for a given CA, cert, and status" Usage of ocspsign: cfssl ocspsign -ca cert -responder cert -key key -cert cert [-reason code] diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/scan/scan.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/scan/scan.go index 64b3595a5f5..8c4e5bde3a3 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/scan/scan.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/scan/scan.go @@ -1,3 +1,4 @@ +// Package scan implements the scan CLI. package scan import ( @@ -21,7 +22,7 @@ var scanFlags = []string{"list", "family", "scanner"} func printJSON(v interface{}) { b, _ := json.MarshalIndent(v, "", " ") - fmt.Printf("%s\n", b) + fmt.Printf("%s\n\n", b) } func scanMain(args []string, c cli.Config) (err error) { @@ -36,6 +37,8 @@ func scanMain(args []string, c cli.Config) (err error) { return } + fmt.Printf("Scanning %s...\n", host) + var results map[string]scan.FamilyResult results, err = scan.Default.RunScans(host, c.Family, c.Scanner) if err != nil { diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/selfsign/selfsign.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/selfsign/selfsign.go index 14ef2e455cd..8b43ae05bd5 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/selfsign/selfsign.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/selfsign/selfsign.go @@ -1,3 +1,4 @@ +// Package selfsign implements the selfsign command. package selfsign import ( diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/serve.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/serve.go index 4bf211b0351..005cc19ebc1 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/serve.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/serve.go @@ -1,3 +1,4 @@ +// Package serve implements the serve command for CFSSL's API. package serve import ( @@ -18,19 +19,19 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity" ) -var serverUsageText = // Usage text of 'cfssl serve' -`cfssl serve -- set up a HTTP server handles CF SSL requests +// Usage text of 'cfssl serve' +var serverUsageText = `cfssl serve -- set up a HTTP server handles CF SSL requests Usage of serve: cfssl serve [-address address] [-ca cert] [-ca-bundle bundle] \ - [-ca-key key] [-int-bundle bundle] [-port port] [-metadata file] \ - [-remote remote_host] [-config config] + [-ca-key key] [-int-bundle bundle] [-int-dir dir] [-port port] \ + [-metadata file] [-remote remote_host] [-config config] [-uselocal] Flags: ` // Flags used by 'cfssl serve' -var serverFlags = []string{"address", "port", "ca", "ca-key", "ca-bundle", "int-bundle", "int-dir", "metadata", "remote", "config"} +var serverFlags = []string{"address", "port", "ca", "ca-key", "ca-bundle", "int-bundle", "int-dir", "metadata", "remote", "config", "uselocal"} // registerHandlers instantiates various handlers and associate them to corresponding endpoints. func registerHandlers(c cli.Config) error { @@ -95,6 +96,9 @@ func registerHandlers(c cli.Config) error { log.Info("Setting up scaninfo endpoint") http.Handle("/api/v1/cfssl/scaninfo", scan.NewInfoHandler()) + log.Info("Setting up static endpoints") + http.Handle("/", http.FileServer(FS(c.UseLocal))) + log.Info("Handler set up complete.") return nil } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static.go new file mode 100644 index 00000000000..1453c1322dc --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static.go @@ -0,0 +1,201 @@ +package serve + +import ( + "bytes" + "compress/gzip" + "io/ioutil" + "net/http" + "os" + "path" + "sync" + "time" +) + +type escLocalFS struct{} + +var escLocal escLocalFS + +type escStaticFS struct{} + +var escStatic escStaticFS + +type escFile struct { + compressed string + size int64 + local string + isDir bool + + data []byte + once sync.Once + name string +} + +func (escLocalFS) Open(name string) (http.File, error) { + f, present := escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + return os.Open(f.local) +} + +func (escStaticFS) prepare(name string) (*escFile, error) { + f, present := escData[path.Clean(name)] + if !present { + return nil, os.ErrNotExist + } + var err error + f.once.Do(func() { + f.name = path.Base(name) + if f.size == 0 { + return + } + var gr *gzip.Reader + gr, err = gzip.NewReader(bytes.NewBufferString(f.compressed)) + if err != nil { + return + } + f.data, err = ioutil.ReadAll(gr) + }) + if err != nil { + return nil, err + } + return f, nil +} + +func (fs escStaticFS) Open(name string) (http.File, error) { + f, err := fs.prepare(name) + if err != nil { + return nil, err + } + return f.File() +} + +func (f *escFile) File() (http.File, error) { + type httpFile struct { + *bytes.Reader + *escFile + } + return &httpFile{ + Reader: bytes.NewReader(f.data), + escFile: f, + }, nil +} + +func (f *escFile) Close() error { + return nil +} + +func (f *escFile) Readdir(count int) ([]os.FileInfo, error) { + return nil, nil +} + +func (f *escFile) Stat() (os.FileInfo, error) { + return f, nil +} + +func (f *escFile) Name() string { + return f.name +} + +func (f *escFile) Size() int64 { + return f.size +} + +func (f *escFile) Mode() os.FileMode { + return 0 +} + +func (f *escFile) ModTime() time.Time { + return time.Time{} +} + +func (f *escFile) IsDir() bool { + return f.isDir +} + +func (f *escFile) Sys() interface{} { + return f +} + +// FS returns a http.Filesystem for the embedded assets. If useLocal is true, +// the filesystem's contents are instead used. +func FS(useLocal bool) http.FileSystem { + if useLocal { + return escLocal + } + return escStatic +} + +// FSByte returns the named file from the embedded assets. If useLocal is +// true, the filesystem's contents are instead used. +func FSByte(useLocal bool, name string) ([]byte, error) { + if useLocal { + f, err := escLocal.Open(name) + if err != nil { + return nil, err + } + return ioutil.ReadAll(f) + } + f, err := escStatic.prepare(name) + if err != nil { + return nil, err + } + return f.data, nil +} + +// FSMustByte is the same as FSByte, but panics if name is not present. +func FSMustByte(useLocal bool, name string) []byte { + b, err := FSByte(useLocal, name) + if err != nil { + panic(err) + } + return b +} + +// FSString is the string version of FSByte. +func FSString(useLocal bool, name string) (string, error) { + b, err := FSByte(useLocal, name) + return string(b), err +} + +// FSMustString is the string version of FSMustByte. +func FSMustString(useLocal bool, name string) string { + return string(FSMustByte(useLocal, name)) +} + +var escData = map[string]*escFile{ + + "/index.html": { + local: "cli/serve/static/index.html", + size: 943, + compressed: "" + + "\x1f\x8b\b\x00\x00\tn\x88\x00\xff|S\xc1\x8e\xd30\x10\xbd\xf7+\x86\\zj\x86\xd5r@+7\x97B\x01\x81\xc4J]\x0e\x1c\x1d\xdbm\xbc\xebږ=\x81\xae\x10\xff\x8e\xed$ݴ+q\x8a\xed\x99\xf7f\xe6\xcd\v{\xf3\xe1\xfb\xe6\xe1\xe7\xfdG\xe8\xe8h\x9a\x05\x9b>\x8a\xcbf\x01\xc0\x8e\x8a8\x88\x8e\x87\xa8h]\xfdxخ" + + "\xdeW\xcd\"GH\x93Q\xcdf\xbb\xdb}\x83\x15\xec\x04\xb7\f\x87\xb7\x1c5\xda>A\x17\xd4~\xbdD\x14\xd2>\xc6Z\x18\xd7˽\xe1A\xd5\xc2\x1d\x91?\xf2\x13\x1a\xddF\xa4ߚH\x85U\xeb\x1cE\n\xdc\xe3m}[\xbfC\x11#\x9e\xdfꣶuzYBPf\xbd\x8c\xf4lT\xec\x94\"\xf0\xa9\x8a\"\xd1-K\xe1\x12\xc8" + + "'\x80\xd6\xc9g\xf8S\x8e\x00\x9eK\xa9\xedaE\xce\xdfݾ\xf5\xa7\xf2\xfc7#p\x840\x1c\xa6^\xb0\f,d\x96\xff\x02ax\x8c\xeb*\x1d[\x1e`\xf8\xac\xa4\xda\xf3\xde\xd0t\xdd듒\x99\xba\x1a*3\xa9\xcf@\xe1,qmU\x18c\x97ё W\x9ee\xa4\x1c~\x95\xd1\x06ne5HZa5\bϐ\x9fI1" + + "\xb1\x96ͼn\xc0\x18\ue8da\x9a\x9d\xee\xf3j\xbd\x99\x95\x9b\x12\xd3g\x96S\x96:\xbf\x96&\xc7~bZ\u007f\x9d\xbdS5\x83\x13\xf8\x05\x10\xe7H\x86\xbd\xb9\xea\xfa\xe2\xc80\x15\x1e<\xf6\x1f\x19Yw3\x8533\x9aiN\xe3\xe7/oo\u007fC\x01\xbaMI\x15a7ff9\xabޡB\xd2|\xe1c\x9cf\xd5J\x85)\x17M\x96s\"i\x98\x8a\x12\x93\x15\xd9`\xce\x12\x85\xf5{\xa65\x95A\"\x84VZ\x92\x1a_\x85W\xe15N\x95»\xb1\xb0dU\b#>\x92\x94/" + + "|\xa5\xb7\x9c\xaa\x82R\x8dj@\xa1:-|\vl'L+\x11\xd9\x16\xfd\v\r\xf3\xd4$\xcbX\xb5\f\xb4\xa8\xbfGW_כ\x1b;\xf1\xd1h\xe0V%\xc2\xce\xeb\xb3ȨZc\x15Y\xa3\x94\x13\xa5\x16\x1e4\x13\"\x91{\x05\x19\xcdI\xc3u\xd7\xcdنfƸ\x17[\xbbQ\xc6v\x8a\xa9\xa84a\x15\x95\xed\xdcp\xb65" + + "`\x90{\x12 CF\x12\x89$U湐z\xd8s\x81\x8f0\xd9\x19\xc5`ծ\xcc!\x01\xceI\xadhG\xb6\xeb\xf7\xd1\x1aރ\xeb\x04\xe1Փ\xb1\x8b\xda\xefZ\x92-\x1f\x05\xcb\x1f\x9a\xdc\xf1b\x97\td\xa0\x88\xfb\x9a\x11n\xf8\x88\xf5\xa0\x19a\x00v9\xf6@\x18\xa3ⲛ\xaaɒ\xee\"\xe8\xe0\x8b\xcb6\x14}\x13R" + + "\xbc\x9f\\\x03\bH\xa0\xca\xe0[d\x1ae\x16\\w\r\x91\xe7\x90\xf6\xc1u?R\xb9\x90e\xa7h\xda\x01\xab ש\x87X\x06\x96r\xa5\xc0\x16P\xf0 \x88%\x1d\x8c\fCI\x12\xca\x11\x18Xx\x85Pڋ\u007f\x81\u007f\x88\x93\x19\x8eQĪ\xba\xd1\x03\x18\xe3\xbf\x14\xdc\xe1X\x95\x16\xc1\xb5kNRZ\b\x0e1hAC!\x97" + + "\x1e\xd2\xdb\x1ad4\xdd\x00\x04\x8a\x92FkQuv\x13]!\xf8\x05\xb5d%\x91\xdbNX5I\xc9t\x17I\xa7\xd2_=C\xe7\xf8\xfa}\x99\xa8k\x92p\xdai\xba\x8e\xfd\x87\x9a!\xc1e\x9a\xb5](\x15\xac\xa6\x99\x8b\x92\xa4\n\xf6\xa8\xf2b(Lfv\xb7;\x86DjRQ\x1e,\xa5hj\xa7G\xd2\x14\xac2Q\x19͝" + + "\u007fǒ\xb5\xf3:R)`k\xa4d\n\x1b\xe2T\xcd[\xfd\xd3P\xb9\xc5߄\x97\xe1U۱\x15ne\xe9:S\xf1ުC}2\xf3\xbf\xda'\x94?\x0f\xddR\xcd\xf2\xa6J5\xf0\x9d\xd15\xad\xf4|W\xf5\x8c|\x1b\x04\x10\xa6e\xad\xb7\xb3\xf9M7\x19.\xa9\xfe\xf5\xf6\xd5\xef3\x1f\x93\x9a\xe1\xf5%\xb6\xb6\xed^\xfe\xc1d" + + "\xd5\xc2GϬ\r\xd3\x01\x03k\xc2g\xf3\v\xb4Cˈ&{0\x84X\x8e\xec\xd8\x1b_5iJ\xa1Vߡ\xa7O\x91\x1br<\xfc\xbb\xbe\x82!AIZ̆\"=\x88\x9c\x94\x8co\xefM\xa6_ CL\r\xf5\x11ZCQv\x8a\xf7\x90ih\x81\xfcH\xcbؿ\x19\b\xf5\x04\x9eY\x89,6\xbe\xf5\xacCϏ\xdeb" + + "3qR\xf5\xb3\xb3ql\xb3\xf5\xda\xfa\xd3s\xd6\xf4\xa1\xc0\xb5\xde:౻\x13\x84\xc0\xdbS\"\xceݾ\xfd\x9e\xbf#e\x13Х\x84b\n\xb1t\x86\xdex\xb6\xef\xdd\u074cD͂\xb7\xa2\v\xe4\xfd,D\xe6\x1d\xf2\x9d\x0e\xa1\x82]\xd7Epɷu\xc1\xa0\xc0\xa1]+\x10\xef\x02Ŗf\a\xbe\xc5F6F\xc6\xfc\xe4\n" + + "\xc11\x8e(\x87\xf3mH\xe7/\"+8\xf2\x1f\x8d\x11\xdd\xc0dI\xccJ\x8d\xa9\xb5P\x9f\xc3\xeeG\xf2x\xb1\x92\xb4\x14k:&\x05\b\x0f\x13z\x1cp(]j\"&ǠOd*h\x1dl^\x97\x92\xa2\xd1\xe6H\xdc\xe5\xa4\xef\x06\xfcɤl\x85\xcf!\xd2M\x05w58\xa0\xb3O\x8c\xf6\x01x\x1f\xfeޜ\x90\xc0\xe1I" + + "h\x1a-\xcc\xfcPcϡՀ\x15\x17Ɋ\xa6pR\u007f\xf8\x80\xc6SDJ\xb2\x9dL\x87\t\x8a\xff\xb3\xf6\xb8\xa7\xad@\x8eH\xaf\x041\x88\xd6\xe6\x02<\xe6\r\x9d\xe63]\x80\xa60\x0e\xc3p~\xc2\xd7cK\x02\xc5\xca\x12;Z\xa4\xbbg\x9c^\x0f\x9a4g_h\xc2T-Y\xbe\x9d\xb5>\x9f\x82\xf8\xb4\x8c\xb5d&\x12c" + + "R\xdf\xdeM&L\x1cݧc+#O\x8e\xa6\xe5ax&\u061cܵc\xbf\x8ey4ilx%!uM\xabl\xb6\xb700\xfdq~6f\xb0ǶW\x9d\x10\xbe\xfd\xcc\xfb\x85\xfb\x1c\xeb.7Nj\u007f\x8d\x82[\xac\xfd\xa2\x83\xef\x02\xf3y\xfb_\x00\x00\x00\xff\xff\x06N\x9fR\xf5\x0e\x00\x00", + }, + + "/": { + isDir: true, + local: "cli/serve/static", + }, +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/index.html b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/index.html new file mode 100644 index 00000000000..b6942f5dce7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/index.html @@ -0,0 +1,38 @@ + + + + + + CFSSL - Scan + + + + + + + +
+

CFSSL: CloudFlare's PKI toolkit

+ +

See blog post or contribute on GitHub

+
+ + \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/scan.html b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/scan.html new file mode 100644 index 00000000000..db73a12e1a3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/serve/static/scan.html @@ -0,0 +1,106 @@ + + + + + + CFSSL - Scan + + + + + + + +
+

Scan

+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/sign/sign.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/sign/sign.go index bd8aa2e1dfe..e67e34cc7f1 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/sign/sign.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/sign/sign.go @@ -1,3 +1,4 @@ +// Package sign implements the sign command. package sign import ( @@ -11,8 +12,8 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/universal" ) -var signerUsageText = // Usage text of 'cfssl sign' -`cfssl sign -- signs a client cert with a host name by a given CA and CA key +// Usage text of 'cfssl sign' +var signerUsageText = `cfssl sign -- signs a client cert with a host name by a given CA and CA key Usage of sign: cfssl sign -ca cert -ca-key key [-config config] [-profile profile] [-hostname hostname] CSR [SUBJECT] diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/version/version.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/version/version.go index 251394b7170..02915b57a2e 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/version/version.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/version/version.go @@ -1,3 +1,4 @@ +// Package version implements the version command. package version import ( diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cmd/cfssl/cfssl.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cmd/cfssl/cfssl.go index 2546403c3d8..e0fe26ed296 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/cmd/cfssl/cfssl.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/cmd/cfssl/cfssl.go @@ -27,6 +27,8 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/bundle" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/gencert" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/genkey" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/info" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspserve" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/ocspsign" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/scan" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/cli/selfsign" @@ -38,20 +40,22 @@ import ( // main defines the cfssl usage and registers all defined commands and flags. func main() { - flag.Usage = nil // Add command names to cfssl usage + flag.Usage = nil // this is set to nil for testabilty flag.IntVar(&log.Level, "loglevel", log.LevelInfo, "Log level") // Register commands. cmds := map[string]*cli.Command{ - "bundle": bundle.Command, - "sign": sign.Command, - "serve": serve.Command, - "version": version.Command, - "genkey": genkey.Command, - "gencert": gencert.Command, - "ocspsign": ocspsign.Command, - "selfsign": selfsign.Command, - "scan": scan.Command, + "bundle": bundle.Command, + "sign": sign.Command, + "serve": serve.Command, + "version": version.Command, + "genkey": genkey.Command, + "gencert": gencert.Command, + "ocspsign": ocspsign.Command, + "ocspserve": ocspserve.Command, + "selfsign": selfsign.Command, + "scan": scan.Command, + "info": info.Command, } // Register all command flags. cli.Start(cmds) diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/config/config.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/config/config.go index 91dc1b8e287..9bbe39a0346 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/config/config.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/config/config.go @@ -1,4 +1,4 @@ -// Package config contains the configuration logic for CF-SSL. +// Package config contains the configuration logic for CFSSL. package config import ( @@ -16,6 +16,7 @@ import ( cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" + ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config" ) // A CSRWhitelist stores booleans for fields in the CSR. If a CSRWhitelist is @@ -297,6 +298,7 @@ type Signing struct { // Config stores configuration information for the CA. type Config struct { Signing *Signing `json:"signing"` + OCSP *ocspConfig.Config `json:"ocsp"` AuthKeys map[string]AuthKey `json:"auth_keys,omitempty"` Remotes map[string]string `json:"remotes,omitempty"` } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key.go new file mode 100644 index 00000000000..8c72fd54034 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key.go @@ -0,0 +1,235 @@ +// +build pkcs11 + +// Package pkcs11key implements crypto.Signer for PKCS #11 private +// keys. Currently, only RSA keys are support. +package pkcs11key + +import ( + "crypto" + "crypto/rsa" + "errors" + "io" + "math/big" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/miekg/pkcs11" +) + +// from src/pkg/crypto/rsa/pkcs1v15.go +var hashPrefixes = map[crypto.Hash][]byte{ + crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}, + crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14}, + crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, + crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, + crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, + crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, + crypto.MD5SHA1: {}, // A special TLS case which doesn't use an ASN1 prefix. + crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14}, +} + +// PKCS11Key is an implementation of the crypto.Signer interface +// using a key stored in a PKCS#11 hardware token. This enables +// the use of PKCS#11 tokens with the Go x509 library's methods +// for signing certificates. +type PKCS11Key struct { + // The PKCS#11 library to use + module *pkcs11.Ctx + + // The name of the slot to be used. + // We will automatically search for this in the slot list. + slotDescription string + + // The PIN to be used to log in to the device + pin string + + // The public key corresponding to the private key. + publicKey rsa.PublicKey + + // The an ObjectHandle pointing to the private key on the HSM. + privateKeyHandle pkcs11.ObjectHandle +} + +// New instantiates a new handle to a PKCS #11-backed key. +func New(module, slot, pin, privLabel string) (ps *PKCS11Key, err error) { + // Set up a new pkcs11 object and initialize it + p := pkcs11.New(module) + if p == nil { + err = errors.New("unable to load PKCS#11 module") + return + } + + if err = p.Initialize(); err != nil { + return + } + + // Initialize a partial key + ps = &PKCS11Key{ + module: p, + slotDescription: slot, + pin: pin, + } + + // Look up the private key + session, err := ps.openSession() + if err != nil { + ps.Destroy() + return + } + defer ps.closeSession(session) + + template := []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY), + pkcs11.NewAttribute(pkcs11.CKA_LABEL, privLabel), + } + if err = p.FindObjectsInit(session, template); err != nil { + ps.Destroy() + return + } + objs, _, err := p.FindObjects(session, 2) + if err != nil { + ps.Destroy() + return + } + if err = p.FindObjectsFinal(session); err != nil { + ps.Destroy() + return + } + + if len(objs) == 0 { + err = errors.New("private key not found") + ps.Destroy() + return + } + ps.privateKeyHandle = objs[0] + + // Populate the pubic key from the private key + // TODO: Add support for non-RSA keys, switching on CKA_KEY_TYPE + template = []*pkcs11.Attribute{ + pkcs11.NewAttribute(pkcs11.CKA_MODULUS, nil), + pkcs11.NewAttribute(pkcs11.CKA_PUBLIC_EXPONENT, nil), + } + attr, err := p.GetAttributeValue(session, ps.privateKeyHandle, template) + if err != nil { + ps.Destroy() + return + } + + n := big.NewInt(0) + e := int(0) + gotModulus, gotExponent := false, false + for _, a := range attr { + if a.Type == pkcs11.CKA_MODULUS { + n.SetBytes(a.Value) + gotModulus = true + } else if a.Type == pkcs11.CKA_PUBLIC_EXPONENT { + bigE := big.NewInt(0) + bigE.SetBytes(a.Value) + e = int(bigE.Int64()) + gotExponent = true + } + } + if !gotModulus || !gotExponent { + ps.Destroy() + return + } + ps.publicKey = rsa.PublicKey{n, e} + + return +} + +// Destroy tears down a PKCS11Key. +// +// This method must be called before the PKCS11Key is GC'ed, in order +// to ensure that the PKCS#11 module itself is properly finalized and +// destroyed. +// +// The idiomatic way to do this (assuming no need for a long-lived +// signer) is as follows: +// +// ps, err := NewPKCS11Signer(...) +// if err != nil { ... } +// defer ps.Destroy() +func (ps *PKCS11Key) Destroy() { + if ps.module != nil { + ps.module.Finalize() + ps.module.Destroy() + } +} + +func (ps *PKCS11Key) openSession() (session pkcs11.SessionHandle, err error) { + // Find slot by description + slots, err := ps.module.GetSlotList(true) + if err != nil { + return + } + for _, slot := range slots { + slotInfo, err := ps.module.GetSlotInfo(slot) + if err != nil { + continue + } + + if slotInfo.SlotDescription == ps.slotDescription { + // Open session + session, err = ps.module.OpenSession(slot, pkcs11.CKF_SERIAL_SESSION) + if err != nil { + return session, err + } + + // Login + if err = ps.module.Login(session, pkcs11.CKU_USER, ps.pin); err != nil { + return session, err + } + + return session, err + } + } + + err = errors.New("slot not found") + return +} + +func (ps *PKCS11Key) closeSession(session pkcs11.SessionHandle) { + ps.module.Logout(session) + ps.module.CloseSession(session) +} + +// Public returns the public key for the PKCS #11 key. +func (ps *PKCS11Key) Public() crypto.PublicKey { + return &ps.publicKey +} + +// Sign performs a signature using the PKCS #11 key. +func (ps *PKCS11Key) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) (signature []byte, err error) { + // Verify that the length of the hash is as expected + hash := opts.HashFunc() + hashLen := hash.Size() + if len(msg) != hashLen { + err = errors.New("input size does not match hash function output size") + return + } + + // Add DigestInfo prefix + // TODO: Switch mechanisms based on CKA_KEY_TYPE + mechanism := []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS, nil)} + prefix, ok := hashPrefixes[hash] + if !ok { + err = errors.New("unknown hash function") + return + } + signatureInput := append(prefix, msg...) + + // Open a session + session, err := ps.openSession() + if err != nil { + return + } + defer ps.closeSession(session) + + // Perform the sign operation + err = ps.module.SignInit(session, mechanism, ps.privateKeyHandle) + if err != nil { + return + } + + signature, err = ps.module.Sign(session, signatureInput) + return +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key_stub.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key_stub.go new file mode 100644 index 00000000000..e4c4f0a5049 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key/pkcs11key_stub.go @@ -0,0 +1,6 @@ +// Package pkcs11key exists to satisfy Go build tools. +// Some Go tools will complain "no buildable Go source files in ..." because +// pkcs11key.go only builds when the pkcs11 tag is supplied. This empty file +// exists only to suppress that error, which blocks completion in some tools +// (specifically godep). +package pkcs11key diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/crypto.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/crypto.go new file mode 100644 index 00000000000..bbcab707d42 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/crypto.go @@ -0,0 +1,114 @@ +package pkcs12 + +// Much credit to at Microsoft's Azure project https://github.com/Azure/go-pkcs12/blob/master/pkcs12.go, +// from which the following decryption code was adapted under the MIT License. The functions in this +// file implement the decryption of pkcs12 formatted data as described in +// https://tools.ietf.org/html/rfc2898#section-6.1.2 + +import ( + "bytes" + "crypto/cipher" + "crypto/des" + "crypto/sha1" + "crypto/x509/pkix" + "encoding/asn1" + "errors" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf" + rc2 "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/dgryski/go-rc2" +) + +type pbeParams struct { + Salt []byte + Iterations int +} + +const ( + pbeWithSHAAnd3KeyTripleDESCBC = "pbeWithSHAAnd3-KeyTripleDES-CBC" + pbewithSHAAnd40BitRC2CBC = "pbewithSHAAnd40BitRC2-CBC" +) + +var algByOID = map[string]string{ + "1.2.840.113549.1.12.1.3": pbeWithSHAAnd3KeyTripleDESCBC, + "1.2.840.113549.1.12.1.6": pbewithSHAAnd40BitRC2CBC, +} + +var blockcodeByAlg = map[string]func(key []byte) (cipher.Block, error){ + pbeWithSHAAnd3KeyTripleDESCBC: des.NewTripleDESCipher, + pbewithSHAAnd40BitRC2CBC: func(key []byte) (cipher.Block, error) { + return rc2.New(key, len(key)*8) + }, +} + +var ( + deriveKeyByAlg = map[string]func(salt, password []byte, iterations int) []byte{ + pbeWithSHAAnd3KeyTripleDESCBC: func(salt, password []byte, iterations int) []byte { + return pbkdf.PBKDF(sha1Sum, 20, 64, salt, password, iterations, 1, 24) + }, + pbewithSHAAnd40BitRC2CBC: func(salt, password []byte, iterations int) []byte { + return pbkdf.PBKDF(sha1Sum, 20, 64, salt, password, iterations, 1, 5) + }, + } + deriveIVByAlg = map[string]func(salt, password []byte, iterations int) []byte{ + pbeWithSHAAnd3KeyTripleDESCBC: func(salt, password []byte, iterations int) []byte { + return pbkdf.PBKDF(sha1Sum, 20, 64, salt, password, iterations, 2, 8) + }, + pbewithSHAAnd40BitRC2CBC: func(salt, password []byte, iterations int) []byte { + return pbkdf.PBKDF(sha1Sum, 20, 64, salt, password, iterations, 2, 8) + }, + } +) + +func sha1Sum(in []byte) []byte { + sum := sha1.Sum(in) + return sum[:] +} + +//For use decrypting key and certificates, apart from a few minor changes +//this entire function was taken from Azure: https://github.com/Azure/go-pkcs12/blob/master/crypto.go +func decrypt(algorithm pkix.AlgorithmIdentifier, encrypted, password []byte) (decrypted []byte, err error) { + // Generate a CBC Decrypter + cbc, err := cbcGen(algorithm, password) + if err != nil { + return nil, err + } + // Decrypting the secret data + decrypted = make([]byte, len(encrypted)) + cbc.CryptBlocks(decrypted, encrypted) + + if psLen := int(decrypted[len(decrypted)-1]); psLen > 0 && psLen < 9 { + m := decrypted[:len(decrypted)-psLen] + ps := decrypted[len(decrypted)-psLen:] + if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 { + return nil, errors.New("decryption error, incorrect padding") + } + decrypted = m + } else { + return nil, errors.New("decryption error, incorrect padding") + } + + return +} + +// Generating a cbc cipher decoder +func cbcGen(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, error) { + algorithmName, supported := algByOID[algorithm.Algorithm.String()] + if !supported { + return nil, errors.New("Algorithm not supported") + } + var params pbeParams + if _, err := asn1.Unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil { + return nil, err + } + k := deriveKeyByAlg[algorithmName](params.Salt, password, params.Iterations) + iv := deriveIVByAlg[algorithmName](params.Salt, password, params.Iterations) + + code, err := blockcodeByAlg[algorithmName](k) + if err != nil { + return nil, err + } + + cbc := cipher.NewCBCDecrypter(code, iv) + return cbc, nil + +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf/pbkdf.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf/pbkdf.go new file mode 100644 index 00000000000..1f8eeff22e1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf/pbkdf.go @@ -0,0 +1,201 @@ +// Package pbkdf implements +// +// Entire package adapted from https://github.com/Azure/go-pkcs12/blob/master/pbkdf.go +// and https://github.com/Azure/go-pkcs12/blob/master/crypto.go under the MIT +// license. These functions implement cryptographic processes used in decoding +// password protected pfx objects adhering to the pkcs12 standard as documented at +// +// https://tools.ietf.org/html/rfc7292#appendix-B.2 +// +// +package pbkdf + +import ( + "errors" + "math/big" + "unicode/utf16" + "unicode/utf8" +) + +// PBKDF implements RSA Labs' Password-Based Key Derivation Function +func PBKDF(hash func([]byte) []byte, u, v int, salt, password []byte, r int, ID byte, size int) (key []byte) { + // implementation of https://tools.ietf.org/html/rfc7292#appendix-B.2 , RFC text verbatim in comments + + // Let H be a hash function built around a compression function f: + + // Z_2^u x Z_2^v -> Z_2^u + + // (that is, H has a chaining variable and output of length u bits, and + // the message input to the compression function of H is v bits). The + // values for u and v are as follows: + + // HASH FUNCTION VALUE u VALUE v + // MD2, MD5 128 512 + // SHA-1 160 512 + // SHA-224 224 512 + // SHA-256 256 512 + // SHA-384 384 1024 + // SHA-512 512 1024 + // SHA-512/224 224 1024 + // SHA-512/256 256 1024 + + // Furthermore, let r be the iteration count. + + // We assume here that u and v are both multiples of 8, as are the + // lengths of the password and salt strings (which we denote by p and s, + // respectively) and the number n of pseudorandom bits required. In + // addition, u and v are of course non-zero. + + // For information on security considerations for MD5 [19], see [25] and + // [1], and on those for MD2, see [18]. + + // The following procedure can be used to produce pseudorandom bits for + // a particular "purpose" that is identified by a byte called "ID". + // This standard specifies 3 different values for the ID byte: + + // 1. If ID=1, then the pseudorandom bits being produced are to be used + // as key material for performing encryption or decryption. + + // 2. If ID=2, then the pseudorandom bits being produced are to be used + // as an IV (Initial Value) for encryption or decryption. + + // 3. If ID=3, then the pseudorandom bits being produced are to be used + // as an integrity key for MACing. + + // 1. Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + D := []byte{} + for i := 0; i < v; i++ { + D = append(D, ID) + } + + // 2. Concatenate copies of the salt together to create a string S of + // length v(ceiling(s/v)) bits (the final copy of the salt may be + // truncated to create S). Note that if the salt is the empty + // string, then so is S. + + S := []byte{} + { + s := len(salt) + times := s / v + if s%v > 0 { + times++ + } + for len(S) < times*v { + S = append(S, salt...) + } + S = S[:times*v] + } + + // 3. Concatenate copies of the password together to create a string P + // of length v(ceiling(p/v)) bits (the final copy of the password + // may be truncated to create P). Note that if the password is the + // empty string, then so is P. + + P := []byte{} + { + s := len(password) + times := s / v + if s%v > 0 { + times++ + } + for len(P) < times*v { + P = append(P, password...) + } + password = nil + P = P[:times*v] + } + + // 4. Set I=S||P to be the concatenation of S and P. + I := append(S, P...) + + // 5. Set c=ceiling(n/u). + c := size / u + if size%u > 0 { + c++ + } + + // 6. For i=1, 2, ..., c, do the following: + A := make([]byte, c*20) + for i := 0; i < c; i++ { + + // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1, + // H(H(H(... H(D||I)))) + Ai := hash(append(D, I...)) + for j := 1; j < r; j++ { + Ai = hash(Ai[:]) + } + copy(A[i*20:], Ai[:]) + + if i < c-1 { // skip on last iteration + + // B. Concatenate copies of Ai to create a string B of length v + // bits (the final copy of Ai may be truncated to create B). + B := []byte{} + for len(B) < v { + B = append(B, Ai[:]...) + } + B = B[:v] + + // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit + // blocks, where k=ceiling(s/v)+ceiling(p/v), modify I by + // setting I_j=(I_j+B+1) mod 2^v for each j. + { + Bbi := new(big.Int) + Bbi.SetBytes(B) + + one := big.NewInt(1) + + for j := 0; j < len(I)/v; j++ { + Ij := new(big.Int) + Ij.SetBytes(I[j*v : (j+1)*v]) + Ij.Add(Ij, Bbi) + Ij.Add(Ij, one) + Ijb := Ij.Bytes() + if len(Ijb) > v { + Ijb = Ijb[len(Ijb)-v:] + } + copy(I[j*v:(j+1)*v], Ijb) + } + } + } + } + // 7. Concatenate A_1, A_2, ..., A_c together to form a pseudorandom + // bit string, A. + + // 8. Use the first n bits of A as the output of this entire process. + A = A[:size] + + return A + + // If the above process is being used to generate a DES key, the process + // should be used to create 64 random bits, and the key's parity bits + // should be set after the 64 bits have been produced. Similar concerns + // hold for 2-key and 3-key triple-DES keys, for CDMF keys, and for any + // similar keys with parity bits "built into them". +} + +// BMPString computes the Basic Multilingual Plane (BMP) string +// of a []byte +func BMPString(utf8String []byte) ([]byte, error) { + // References: + // https://tools.ietf.org/html/rfc7292#appendix-B.1 + // http://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane + // - non-BMP characters are encoded in UTF 16 by using a surrogate pair of 16-bit codes + // EncodeRune returns 0xfffd if the rune does not need special encoding + // - the above RFC provides the info that BMPStrings are NULL terminated. + + rv := make([]byte, 0, 2*len(utf8String)+2) + + start := 0 + for start < len(utf8String) { + c, size := utf8.DecodeRune(utf8String[start:]) + start += size + if t, _ := utf16.EncodeRune(c); t != 0xfffd { + return nil, errors.New("password contains characters that cannot be encoded in UCS-2") + } + rv = append(rv, byte(c/256), byte(c%256)) + } + rv = append(rv, 0, 0) + return rv, nil +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pkcs12.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pkcs12.go new file mode 100644 index 00000000000..3b160109640 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pkcs12.go @@ -0,0 +1,222 @@ +// Package pkcs12 implements a subset of PKCS #12 as described here: +// https://tools.ietf.org/html/rfc7292 +// +// +// Much credit to at Microsoft's Azure project https: +// github.com/Azure/go-pkcs12/blob/master/pkcs12.go, +// from which much of the parser code was adapted under the MIT License. +// PKCS #12 is a format used for transferring certificates and private keys. +// +// +// In particular the PFX/P12 structure storing certificates and private keys is parsed into a go structure. +// In almost all cases PKCS #12 stored certificates and private keys are password protected at the time of +// marshaling, and so the parse function in this package takes in a password []byte. PKCS #12 make extensive +// use of the PKCS #7 standard, and so the PKCS #7 parser is used frequently here. Although there is +// flexibility in the data a PKCS #12 object can hold, the typical (i.e. openssl generated) form is roughly +// as follows (for more specific details on allowed asn1 structure see the standard) +// +// +// PFX -> +// Version int +// PKCS #7 Data -> +// PKCS #7 encryptedData -> +// CertificateBag -> +// Certificates +// PKCS #7 Data -> +// PKCS #8 ShroudedBag -> +// Private Key +// MAC Data (Not used here) +// +package pkcs12 + +import ( + "crypto" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "errors" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12/pbkdf" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7" + cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers" +) + +const ( + certBagID = "1.2.840.113549.1.12.10.1.3" + pkcs8ShroudedBagID = "1.2.840.113549.1.12.10.1.2" +) + +// Internal types used for asn1 Unmarshaling +type pfx struct { + Raw asn1.RawContent + Version int + AuthSafe asn1.RawValue + MacData asn1.RawValue `asn1:"optional"` +} + +type contentInfo struct { + ContentType asn1.ObjectIdentifier + Content asn1.RawValue `asn1:"tag:0,explicit,optional"` +} + +type safeBag struct { + ID asn1.ObjectIdentifier + Value asn1.RawValue `asn1:"tag:0,explicit"` + Attributes []pkcs12Attribute `asn1:"set,optional"` +} + +type certBag struct { + ID asn1.ObjectIdentifier + Data []byte `asn1:"tag:0,explicit"` +} + +type pkcs12Attribute struct { + ID asn1.ObjectIdentifier + Value asn1.RawValue `asn1:"set"` +} + +type encryptedPrivateKeyInfo struct { + AlgorithmIdentifier pkix.AlgorithmIdentifier + EncryptedData []byte +} + +// PKCS12 contains the Data expected in PKCS #12 objects, one or more certificates +// a private key, an integer indicating the version, and the raw content +// of the structure +type PKCS12 struct { + Version int + Certificates []*x509.Certificate + PrivateKey crypto.Signer +} + +// ParsePKCS12 parses a pkcs12 syntax object +// into a container for a private key, certificate(s), and +// version number +func ParsePKCS12(raw, password []byte) (msg *PKCS12, err error) { + msg = new(PKCS12) + password, err = pbkdf.BMPString(password) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + var Pfx pfx + _, err = asn1.Unmarshal(raw, &Pfx) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + + if msg.Version = Pfx.Version; msg.Version != 3 { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for PKCS #12 PFX version 3")) + } + authSafe, err := pkcs7.ParsePKCS7(Pfx.AuthSafe.FullBytes) + + if err != nil { + return nil, err + } + if authSafe.ContentInfo != "Data" { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("No support for AuthSafe Format")) + } + var authenticatedSafe []asn1.RawValue + _, err = asn1.Unmarshal(authSafe.Content.Data, &authenticatedSafe) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + + } + + if len(authenticatedSafe) != 2 { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("No support for AuthSafe Format")) + } + var bags []safeBag + bags, err = getBags(authenticatedSafe, password) + if err != nil { + return nil, err + } + if len(bags) > 2 || bags == nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("No support for AuthSafe Format")) + } + + certs, pkey, err := parseBags(bags, password) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + msg.Certificates = certs + msg.PrivateKey = pkey + return + +} + +// Given a slice of PKCS #7 content infos containing PKCS #12 Safe Bag Data, +// getBags returns those Safe Bags. +func getBags(authenticatedSafe []asn1.RawValue, password []byte) (bags []safeBag, err error) { + for _, contentInfo := range authenticatedSafe { + + var safeContents []safeBag + bagContainer, err := pkcs7.ParsePKCS7(contentInfo.FullBytes) + if err != nil { + return nil, err + } + switch { + case bagContainer.ContentInfo == "Data": + if _, err = asn1.Unmarshal(bagContainer.Content.Data, &safeContents); err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + case bagContainer.ContentInfo == "EncryptedData": + data, err := decrypt(bagContainer.Content.EncryptedData.EncryptedContentInfo.ContentEncryptionAlgorithm, + bagContainer.Content.EncryptedData.EncryptedContentInfo.EncryptedContent, password) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + if _, err = asn1.Unmarshal(data, &safeContents); err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + default: + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for bags encoded in Data and EncryptedData types")) + } + + bags = append(bags, safeContents...) + } + return bags, nil + +} + +// Take in either two or one safeBags and return the certificates and or +// Private key within the bags +func parseBags(bags []safeBag, password []byte) (certs []*x509.Certificate, key crypto.Signer, err error) { + for _, bag := range bags { + bagid := bag.ID.String() + switch bagid { + case certBagID: + var CertBag certBag + if _, err = asn1.Unmarshal(bag.Value.Bytes, &CertBag); err != nil { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + certs, err = x509.ParseCertificates(CertBag.Data) + + if err != nil { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + + case pkcs8ShroudedBagID: + var pkinfo encryptedPrivateKeyInfo + if _, err := asn1.Unmarshal(bag.Value.Bytes, &pkinfo); err != nil { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + pkDecrypted, err := decrypt(pkinfo.AlgorithmIdentifier, pkinfo.EncryptedData, password) + if err != nil { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + // Checking if private key data has been properly decoded + var rv asn1.RawValue + if _, err = asn1.Unmarshal(pkDecrypted, &rv); err != nil { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + if key, err = derhelpers.ParsePrivateKeyDER(pkDecrypted); err != nil { + return nil, nil, err + } + + default: + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for certificate bags and PKCS #8 Shrouded Bags")) + } + } + return certs, key, nil +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go index 408d74d6c81..d70b49a10bc 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go @@ -1,7 +1,7 @@ // Package pkcs7 implements the subset of the CMS PKCS #7 datatype that is typically // used to package certificates and CRLs. Using openssl, every certificate converted // to PKCS #7 format from another encoding such as PEM conforms to this implementation. -// reference: https://www.openssl.org/docs/apps/crl2pkcs7.html) +// reference: https://www.openssl.org/docs/apps/crl2pkcs7.html // // PKCS #7 Data type, reference: https://tools.ietf.org/html/rfc2315 // @@ -16,10 +16,12 @@ // } // // There are 6 possible ContentTypes, data, signedData, envelopedData, -// signedAndEnvelopedData, digestedData, and encryptedData. Here onlysignedData is -// implemented, as the degenerate case of signedData without a signature is the typical -// format for transferring certificates and CRLS. The ContentType signedData has the -// form: +// signedAndEnvelopedData, digestedData, and encryptedData. Here signedData, Data, and encrypted +// Data are implemented, as the degenerate case of signedData without a signature is the typical +// format for transferring certificates and CRLS, and Data and encryptedData are used in PKCS #12 +// formats. +// The ContentType signedData has the form: +// // // signedData ::= SEQUENCE { // version Version, @@ -36,12 +38,21 @@ // usage. The ExtendedCertificatesAndCertificates type consists of a sequence of choices // between PKCS #6 extended certificates andx509 certificates. Any sequence consisting // of any number of extended certificates is not yet supported in this implementation +// +// The ContentType Data is simpy a raw octet string and is parsed directly into a Go []byte +// +// The ContentType encryptedData is the most complicated and its form can be gathered by +// the go type below. It essentially contains a raw octet string of encrypted data and an +// algorithm identifier for use in decrypting this data package pkcs7 import ( "crypto/x509" "crypto/x509/pkix" "encoding/asn1" + "errors" + + cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" ) // Types used for asn1 Unmarshaling @@ -55,24 +66,66 @@ type signedData struct { SignerInfos asn1.RawValue } -type content struct { - SignedData signedData -} - type initPKCS7 struct { Raw asn1.RawContent ContentType asn1.ObjectIdentifier - Content content `asn1:"tag:0"` + Content asn1.RawValue `asn1:"tag:0,explicit,optional"` } -// PKCS7 represents the ASN1 PKCS7 degenerate signedData content type +// Object identifiers strings of the three implemented PKCS7 types +const ( + ObjIDData = "1.2.840.113549.1.7.1" + ObjIDSignedData = "1.2.840.113549.1.7.2" + ObjIDEncryptedData = "1.2.840.113549.1.7.6" +) + +// PKCS7 represents the ASN1 PKCS #7 Content type. It contains one of three +// possible types of Content objects, as denoted by the object identifier in +// the ContentInfo field, the other two being nil. SignedData +// is the degenerate SignedData Content info without signature used +// to hold certificates and crls. Data is raw bytes, and EncryptedData +// is as defined in PKCS #7 standard type PKCS7 struct { + Raw asn1.RawContent + ContentInfo string + Content Content +} + +// Content implements three of the six possible PKCS7 data types. Only one is non-nil +type Content struct { + Data []byte + SignedData SignedData + EncryptedData EncryptedData +} + +// SignedData defines the typical carrier of certificates and crls +type SignedData struct { Raw asn1.RawContent Version int Certificates []*x509.Certificate Crl *pkix.CertificateList } +// Data contains raw bytes. Used as a subtype in PKCS12 +type Data struct { + Bytes []byte +} + +// EncryptedData contains encrypted data. Used as a subtype in PKCS12 +type EncryptedData struct { + Raw asn1.RawContent + Version int + EncryptedContentInfo EncryptedContentInfo +} + +// EncryptedContentInfo is a subtype of PKCS7EncryptedData +type EncryptedContentInfo struct { + Raw asn1.RawContent + ContentType asn1.ObjectIdentifier + ContentEncryptionAlgorithm pkix.AlgorithmIdentifier + EncryptedContent []byte `asn1:"tag:0,optional"` +} + // ParsePKCS7 attempts to parse the DER encoded bytes of a // PKCS7 structure func ParsePKCS7(raw []byte) (msg *PKCS7, err error) { @@ -80,29 +133,54 @@ func ParsePKCS7(raw []byte) (msg *PKCS7, err error) { var pkcs7 initPKCS7 _, err = asn1.Unmarshal(raw, &pkcs7) if err != nil { - return nil, err + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } msg = new(PKCS7) msg.Raw = pkcs7.Raw - msg.Version = pkcs7.Content.SignedData.Version - - if len(pkcs7.Content.SignedData.Certificates.Bytes) == 0 { - msg.Certificates = nil - } else { - msg.Certificates, err = x509.ParseCertificates(pkcs7.Content.SignedData.Certificates.Bytes) + msg.ContentInfo = pkcs7.ContentType.String() + switch { + case msg.ContentInfo == ObjIDData: + msg.ContentInfo = "Data" + _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &msg.Content.Data) if err != nil { - return nil, err + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } - } - - if len(pkcs7.Content.SignedData.Crls.Bytes) == 0 { - msg.Crl = nil - } else { - msg.Crl, err = x509.ParseDERCRL(pkcs7.Content.SignedData.Crls.Bytes) + case msg.ContentInfo == ObjIDSignedData: + msg.ContentInfo = "SignedData" + var signedData signedData + _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &signedData) if err != nil { - return nil, err + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + if len(signedData.Certificates.Bytes) != 0 { + msg.Content.SignedData.Certificates, err = x509.ParseCertificates(signedData.Certificates.Bytes) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } } + if len(signedData.Crls.Bytes) != 0 { + msg.Content.SignedData.Crl, err = x509.ParseDERCRL(signedData.Crls.Bytes) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + } + msg.Content.SignedData.Version = signedData.Version + msg.Content.SignedData.Raw = pkcs7.Content.Bytes + case msg.ContentInfo == ObjIDEncryptedData: + msg.ContentInfo = "EncryptedData" + var encryptedData EncryptedData + _, err = asn1.Unmarshal(pkcs7.Content.Bytes, &encryptedData) + if err != nil { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + } + if encryptedData.Version != 0 { + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Only support for PKCS #7 encryptedData version 0")) + } + msg.Content.EncryptedData = encryptedData + + default: + return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, errors.New("Attempt to parse PKCS# 7 Content not of type data, signed data or encrypted data")) } return msg, nil diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr.go index 1472f3b01ee..0bf0303c018 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr.go @@ -1,4 +1,4 @@ -// Package csr implements certificate requests for CF-SSL. +// Package csr implements certificate requests for CFSSL. package csr import ( @@ -10,6 +10,8 @@ import ( "crypto/x509/pkix" "encoding/pem" "errors" + "net" + "strings" cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" @@ -189,17 +191,20 @@ func ParseRequest(req *CertificateRequest) (csr, key []byte, err error) { var tpl = x509.CertificateRequest{ Subject: req.Name(), SignatureAlgorithm: req.KeyRequest.SigAlgo(), - DNSNames: req.Hosts, } + + for i := range req.Hosts { + if ip := net.ParseIP(req.Hosts[i]); ip != nil { + tpl.IPAddresses = append(tpl.IPAddresses, ip) + } else { + tpl.DNSNames = append(tpl.DNSNames, req.Hosts[i]) + } + } + csr, err = x509.CreateCertificateRequest(rand.Reader, &tpl, priv) if err != nil { log.Errorf("failed to generate a CSR: %v", err) - // The use of CertificateError was a matter of some - // debate; it is the one edge case in which a new - // error category specifically for CSRs might be - // useful, but it was deemed that one edge case did - // not a new category justify. - err = cferr.Wrap(cferr.CertificateError, cferr.BadRequest, err) + err = cferr.Wrap(cferr.CSRError, cferr.BadRequest, err) return } block := pem.Block{ @@ -234,3 +239,13 @@ func (g *Generator) ProcessRequest(req *CertificateRequest) (csr, key []byte, er } return } + +// IsNameEmpty returns true if the name has no identifying information in it. +func IsNameEmpty(n Name) bool { + empty := func(s string) bool { return strings.TrimSpace(s) == "" } + + if empty(n.C) && empty(n.ST) && empty(n.L) && empty(n.O) && empty(n.OU) { + return true + } + return false +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr_test.go index 72813a25986..8519f52d8ad 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr/csr_test.go @@ -97,7 +97,7 @@ func TestParseRequest(t *testing.T) { OU: "Systems Engineering", }, }, - Hosts: []string{"cloudflare.com", "www.cloudflare.com"}, + Hosts: []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1"}, KeyRequest: &kr, } @@ -304,16 +304,38 @@ func TestGenerator(t *testing.T) { }, }, CN: "cloudflare.com", - Hosts: []string{"cloudflare.com", "www.cloudflare.com"}, + Hosts: []string{"cloudflare.com", "www.cloudflare.com", "192.168.0.1"}, KeyRequest: &KeyRequest{ Algo: "rsa", Size: 2048, }, } - _, _, err := g.ProcessRequest(req) + csrBytes, _, err := g.ProcessRequest(req) if err != nil { - t.Fatalf("%v", err) + t.Fatal(err) + } + + block, _ := pem.Decode([]byte(csrBytes)) + if block == nil { + t.Fatalf("bad CSR in PEM") + } + + if block.Type != "CERTIFICATE REQUEST" { + t.Fatalf("bad CSR in PEM") + } + + csr, err := x509.ParseCertificateRequest(block.Bytes) + if err != nil { + t.Fatal(err) + } + + if len(csr.DNSNames) != 2 { + t.Fatal("SAN parsing error") + } + + if len(csr.IPAddresses) != 1 { + t.Fatal("SAN parsing error") } } @@ -371,3 +393,41 @@ func TestWeakCSR(t *testing.T) { t.Fatalf("Request should have failed.") } } + +var testEmpty = []struct { + name Name + ok bool +}{ + { + Name{}, + true, + }, + { + Name{C: "OK"}, + false, + }, + { + Name{ST: "OK"}, + false, + }, + { + Name{L: "OK"}, + false, + }, + { + Name{O: "OK"}, + false, + }, + { + Name{OU: "OK"}, + false, + }, +} + +func TestIsNameEmpty(t *testing.T) { + for i, c := range testEmpty { + if IsNameEmpty(c.name) != c.ok { + t.Fatalf("%d: expected IsNameEmpty to return %v, but have %v", i, c.ok, !c.ok) + } + } +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error.go index 5fe5ff32058..a88af6995a7 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error.go @@ -49,6 +49,9 @@ const ( // OCSPError indicates a problem with OCSP signing OCSPError // 8XXX + + // CSRError indicates a problem with CSR parsing + CSRError // 9XXX ) // None is a non-specified error. @@ -213,7 +216,7 @@ func New(category Category, reason Reason) *Error { case BadRequest: msg = "Invalid certificate request" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category CertificateError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category CertificateError.", reason)) } @@ -238,7 +241,7 @@ func New(category Category, reason Reason) *Error { case Unavailable: msg = "Private key is unavailable" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category PrivateKeyError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PrivateKeyError.", reason)) } case IntermediatesError: @@ -252,7 +255,7 @@ func New(category Category, reason Reason) *Error { case ParseFailed: msg = "Failed to parse intermediate certificate" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category IntermediatesError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category IntermediatesError.", reason)) } case RootError: @@ -266,7 +269,7 @@ func New(category Category, reason Reason) *Error { case ParseFailed: msg = "Failed to parse root certificate" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category RootError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category RootError.", reason)) } case PolicyError: @@ -280,7 +283,7 @@ func New(category Category, reason Reason) *Error { case InvalidRequest: msg = "Policy violation request" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category PolicyError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category PolicyError.", reason)) } case DialError: @@ -288,7 +291,7 @@ func New(category Category, reason Reason) *Error { case Unknown: msg = "Failed to dial remote server" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category DialError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category DialError.", reason)) } case APIClientError: @@ -304,12 +307,27 @@ func New(category Category, reason Reason) *Error { case ServerRequestFailed: msg = "API client error: Server request failed" default: - panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", + panic(fmt.Sprintf("Unsupported CFSSL error reason %d under category APIClientError.", reason)) } + case CSRError: + switch reason { + case Unknown: + msg = "CSR parsing failed due to unknown error" + case ReadFailed: + msg = "CSR file read failed" + case ParseFailed: + msg = "CSR Parsing failed" + case DecodeFailed: + msg = "CSR Decode failed" + case BadRequest: + msg = "CSR Bad request" + default: + panic(fmt.Sprintf("Unsupported CF-SSL error reason %d under category APIClientError.", reason)) + } default: - panic(fmt.Sprintf("Unsupported CF-SSL error type: %d.", + panic(fmt.Sprintf("Unsupported CFSSL error type: %d.", category)) } return &Error{ErrorCode: errorCode, Message: msg} @@ -342,10 +360,10 @@ func Wrap(category Category, reason Reason, err error) *Error { errorCode += unknownAuthority } } - case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError, APIClientError: + case PrivateKeyError, IntermediatesError, RootError, PolicyError, DialError, APIClientError, CSRError: // no-op, just use the error default: - panic(fmt.Sprintf("Unsupported CF-SSL error type: %d.", + panic(fmt.Sprintf("Unsupported CFSSL error type: %d.", category)) } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error_test.go index 4b54f6f46de..9221daca0e9 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors/error_test.go @@ -176,6 +176,31 @@ func TestNew(t *testing.T) { if code != 7500 { t.Fatal("Improper error code") } + + code = New(CSRError, Unknown).ErrorCode + if code != 9000 { + t.Fatal("Improper error code") + } + code = New(CSRError, ReadFailed).ErrorCode + if code != 9001 { + t.Fatal("Improper error code") + } + code = New(CSRError, DecodeFailed).ErrorCode + if code != 9002 { + t.Fatal("Improper error code") + } + code = New(CSRError, ParseFailed).ErrorCode + if code != 9003 { + t.Fatal("Improper error code") + } + code = New(CSRError, KeyMismatch).ErrorCode + if code != 9300 { + t.Fatal("Improper error code") + } + code = New(CSRError, BadRequest).ErrorCode + if code != 9300 { + t.Fatal("Improper error code") + } } func TestWrap(t *testing.T) { diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go new file mode 100644 index 00000000000..31928fad1d3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go @@ -0,0 +1,42 @@ +// Package derhelpers implements common functionality +// on DER encoded data +package derhelpers + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rsa" + "crypto/x509" + + cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" +) + +// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, or elliptic curve +// DER-encoded private key. The key must not be in PEM format. +func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { + generalKey, err := x509.ParsePKCS8PrivateKey(keyDER) + if err != nil { + generalKey, err = x509.ParsePKCS1PrivateKey(keyDER) + if err != nil { + generalKey, err = x509.ParseECPrivateKey(keyDER) + if err != nil { + // We don't include the actual error into + // the final error. The reason might be + // we don't want to leak any info about + // the private key. + return nil, cferr.New(cferr.PrivateKeyError, + cferr.ParseFailed) + } + } + } + + switch generalKey.(type) { + case *rsa.PrivateKey: + return generalKey.(*rsa.PrivateKey), nil + case *ecdsa.PrivateKey: + return generalKey.(*ecdsa.PrivateKey), nil + } + + // should never reach here + return nil, cferr.New(cferr.PrivateKeyError, cferr.ParseFailed) +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers.go index 587fe0e96a0..c39e0af0afa 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers.go @@ -1,5 +1,5 @@ // Package helpers implements utility functionality common to many -// CF-SSL packages. +// CFSSL packages. package helpers import ( @@ -10,11 +10,14 @@ import ( "crypto/x509" "encoding/pem" "errors" + //"fmt" "strings" "time" - pkcs7 "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs12" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs7" cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/derhelpers" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" ) @@ -128,6 +131,7 @@ func ParseCertificatesPEM(certsPEM []byte) ([]*x509.Certificate, error) { var cert []*x509.Certificate cert, certsPEM, err = ParseOneCertificateFromPEM(certsPEM) if err != nil { + return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed) } else if cert == nil { break @@ -141,6 +145,37 @@ func ParseCertificatesPEM(certsPEM []byte) ([]*x509.Certificate, error) { return certs, nil } +// ParseCertificatesDER parses a DER encoding of a certificate object and possibly private key, +// either PKCS #7, PKCS #12, or raw x509. +func ParseCertificatesDER(certsDER []byte, password string) ([]*x509.Certificate, crypto.Signer, error) { + var certs []*x509.Certificate + var key crypto.Signer + certsDER = bytes.TrimSpace(certsDER) + pkcs7data, err := pkcs7.ParsePKCS7(certsDER) + if err != nil { + pkcs12data, err := pkcs12.ParsePKCS12(certsDER, []byte(password)) + if err != nil { + certs, err = x509.ParseCertificates(certsDER) + if err != nil { + //fmt.Println("\n\n\n\n\n\nCRITICALZONE\n\n\n\n\n\n\n\n\n\n") + return nil, nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) + } + } else { + key = pkcs12data.PrivateKey + certs = pkcs12data.Certificates + } + } else { + if pkcs7data.ContentInfo != "SignedData" { + return nil, nil, cferr.Wrap(cferr.CertificateError, cferr.DecodeFailed, errors.New("Can only extract certificates from signed data content info")) + } + certs = pkcs7data.Content.SignedData.Certificates + } + if certs == nil { + return nil, key, cferr.New(cferr.CertificateError, cferr.DecodeFailed) + } + return certs, key, nil +} + // ParseSelfSignedCertificatePEM parses a PEM-encoded certificate and check if it is self-signed. func ParseSelfSignedCertificatePEM(certPEM []byte) (*x509.Certificate, error) { cert, err := ParseCertificatePEM(certPEM) @@ -189,9 +224,12 @@ func ParseOneCertificateFromPEM(certsPEM []byte) ([]*x509.Certificate, []byte, e if err != nil { return nil, rest, err } - certs := pkcs7data.Certificates + if pkcs7data.ContentInfo != "SignedData" { + return nil, rest, errors.New("Only PKCS #7 Signed Data Content Info supported for certificate parsing") + } + certs := pkcs7data.Content.SignedData.Certificates if certs == nil { - return nil, rest, errors.New("Pkcs#7 structure contains no certificates") + return nil, rest, errors.New("PKCS #7 structure contains no certificates") } return certs, rest, nil } @@ -208,37 +246,7 @@ func ParsePrivateKeyPEM(keyPEM []byte) (key crypto.Signer, err error) { return nil, err } - return ParsePrivateKeyDER(keyDER) -} - -// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, or elliptic curve -// DER-encoded private key. The key must not be in PEM format. -func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) { - generalKey, err := x509.ParsePKCS8PrivateKey(keyDER) - if err != nil { - generalKey, err = x509.ParsePKCS1PrivateKey(keyDER) - if err != nil { - generalKey, err = x509.ParseECPrivateKey(keyDER) - if err != nil { - // We don't include the actual error into - // the final error. The reason might be - // we don't want to leak any info about - // the private key. - return nil, cferr.New(cferr.PrivateKeyError, - cferr.ParseFailed) - } - } - } - - switch generalKey.(type) { - case *rsa.PrivateKey: - return generalKey.(*rsa.PrivateKey), nil - case *ecdsa.PrivateKey: - return generalKey.(*ecdsa.PrivateKey), nil - } - - // should never reach here - return nil, cferr.New(cferr.PrivateKeyError, cferr.ParseFailed) + return derhelpers.ParsePrivateKeyDER(keyDER) } // GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes. diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers_test.go index fe72994330b..a4a6471f0de 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/helpers_test.go @@ -14,24 +14,46 @@ import ( ) const ( - testCertFile = "testdata/cert.pem" - testBundleFile = "testdata/bundle.pem" - testExtraWSCertFile = "testdata/cert_with_whitespace.pem" - testExtraWSBundleFile = "testdata/bundle_with_whitespace.pem" - testMessedUpBundleFile = "testdata/messed_up_bundle.pem" - testMessedUpCertFile = "testdata/messedupcert.pem" - testEmptyCertFile = "testdata/emptycert.pem" - testPrivateRSAKey = "testdata/priv_rsa_key.pem" - testPrivateECDSAKey = "testdata/private_ecdsa_key.pem" - testUnsupportedECDSAKey = "testdata/secp256k1-key.pem" - testMessedUpPrivateKey = "testdata/messed_up_priv_key.pem" - testEncryptedPrivateKey = "testdata/enc_priv_key.pem" - testEmptyPem = "testdata/empty.pem" - testNoHeaderCert = "testdata/noheadercert.pem" - testSinglePKCS7 = "testdata/cert_pkcs7.pem" - testMultiplePKCS7 = "testdata/bundle_pkcs7.pem" + testCertFile = "testdata/cert.pem" + testCertDERFile = "testdata/cert.der" + testBundleFile = "testdata/bundle.pem" + testExtraWSCertFile = "testdata/cert_with_whitespace.pem" + testExtraWSBundleFile = "testdata/bundle_with_whitespace.pem" + testMessedUpBundleFile = "testdata/messed_up_bundle.pem" + testMessedUpCertFile = "testdata/messedupcert.pem" + testEmptyCertFile = "testdata/emptycert.pem" + testPrivateRSAKey = "testdata/priv_rsa_key.pem" + testPrivateECDSAKey = "testdata/private_ecdsa_key.pem" + testUnsupportedECDSAKey = "testdata/secp256k1-key.pem" + testMessedUpPrivateKey = "testdata/messed_up_priv_key.pem" + testEncryptedPrivateKey = "testdata/enc_priv_key.pem" + testEmptyPem = "testdata/empty.pem" + testNoHeaderCert = "testdata/noheadercert.pem" + testSinglePKCS7 = "testdata/cert_pkcs7.pem" + testMultiplePKCS7 = "testdata/bundle_pkcs7.pem" + testPKCS12EmptyPswd = "testdata/emptypasswordpkcs12.p12" + testPKCS12Passwordispassword = "testdata/passwordpkcs12.p12" + testPKCS12MultipleCerts = "testdata/multiplecerts.p12" ) +func TestParseCertificatesDER(t *testing.T) { + var password = []string{"password", "", "", "multiple"} + for i, testFile := range []string{testPKCS12Passwordispassword, testPKCS12EmptyPswd, testCertDERFile} { + testDER, err := ioutil.ReadFile(testFile) + if err != nil { + t.Fatal(err) + } + if _, _, err := ParseCertificatesDER(testDER, password[i]); err != nil { + t.Fatal(err) + } + // Incorrect Password for PKCS12 formatted files + if _, _, err := ParseCertificatesDER(testDER, "incorrectpassword"); err == nil && i != 2 { + t.Fatal(err) + } + } + +} + func TestKeyLength(t *testing.T) { expNil := 0 recNil := KeyLength(nil) diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/cert.der b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/cert.der new file mode 100644 index 0000000000000000000000000000000000000000..fa90568bffc85dc44fe9a0209c818bf24b311ff0 GIT binary patch literal 498 zcmXqLVti-N#2C4NnTe5!iIKs8n~hVe&70s)BRA zp^$+9NQ7CK)6mFV&j1Jw4dldm4UG&e4a|*<3=9lRqJUguDAyFoCEA?Exybf2GB@@z z7&LY=H8wKLUjDDo`P=qc`}drcV04R|B()#tiXVHO4E1VzCU-ANKRjotm_^c}e|}e7 zBur&4eczY&Ur^!J*{Q9kZ`RLKyLRNJP{27Dgs!76X0|SDA&wfUN-{fE=LAK%Yq7jTDlp)1Sb8W!9wq z%St=1`>`?2iCFQx=v(@`7Fol#UmF#puCho8{aD^r99yT;!TC7qk4$69i|^@DwZ|Xr zko(~JX`jh{C!gt==F4UEpFc9GIsQpn_3ns6j>&0MURbgiDdKsSsT>j`3LRn{KQMyT@ zzBl^dVKC?M2l?3haOOO~Ov`F*et5Qu_$va3aV}{#H823A^go6B!m{TqRhHWLxvw@yn^9 z=1rId1Sil-^l444D3i}4b#&zB%^z%8Q6F1CdZeU9<)Ik+6F8rC0i3f>p?fDj;14Qp zM{eL(LQg>KV{=qpFYIl8fBVlkxWi@=+MGCWt|b1MxjO4=U5Egd`faWM9$D-IQFxaA zByi%g;b=YFmJL=kBkDWd&@KgLBDDuS&K3~4bR#nc&Ws9lgc$&K(5Ia5=>{J-VXC-e6fPZED9eBv($uzL=xF(9qsnR}|%9Q{|lIXWGO;@|1 zpel7JTA$-lg2a2>JS9<5HCdTKTXzMe(g4j(JGz~F#*D)-OUZWeDQPQgYFPq}4dKr~ zmASsSu}^;-qMX)Kq8fCT4U_bPIr@OhNLhKjp;5@^H}2!N9e_3k@|zq0n+^=G-3L~X z2LjV<9X9Xy15?A#@dbu_PBkchW|(8fnIhA}j}!;3{Y7oA(U$m=FZVNIhMf)K`kUN3 zQJL`6hyY|eW_)WI{!KH7%S@&ayW0w^i)54~VFC=RC^ie1<0vL8>#~YXj+?w?;<%}PG?A|I- zQHKrat`CYdBFVi2BmVB*XW~~kSKjwi<-3Jw&EF1TKTl(br~DacP}stH)bmU<_Vs-z zsnahk`Y!e~%TZxYNqOO=l6Y|v;yvsc(us35deqW%>Htyrv}ZiwYCxjoPztxMCbMu* zB??!Na<8g*cxYC4#ku!{NiJTZ<4mack4jA(zn$=&a%#Z4OE&?Tcs$XRD`cRTl;0$E z1=&x76RS}BN+~wV#<3B#YwKS{qUUL^EyB9~Fd5)_(N9pABGfXplQ@LRxJE&~RZ8?T zH@F_pNZedG)VDWfT^3|5Y#GX5O&WMygCt5gdml=3+g2v@b91G>%`v{h53hX7 z-SLKTM|AvvOgZNy`!8F`8J|*j)=GhmoGtfN#pX#(I2mZUv}eqbhFOB?IK+l{1)%EX zi5gJnlrM5PRG~Lx3Iv9>z)BseIQ@Ignk!s8-xwddGZ}3lMD(DC@A&LNQU z5WqA#DaUlS15WqonYJSLTcq@+OgwCzDIV42pfB)-H>=%ZhL%OPE!h5^9Fc#%;x9fI zngaZaF>$)&VoG92uf--F7CNjjqAxf_4Gj}00ZacrG1MUKxbhMU{_AV2te3T%$CZRs zYf(F+iQjwM$b{{{)|aq_E2A5dh18#==OeCZ3aI$Dbq&9=4dYgC7Qxg*ypfx&lu8ef zUCwl-(HUKrw)q9I?|MYTY*xHZF_9M)L|*+_zv`@I+EuFJ)ny>OsS6=7NIsIo*>N=p zUn4(3U9ekfnQ_*!H2u>fJyRX&$h)9Am~MPjMeTJ;hS7-G^Y~3Ngz`o&1ZMtn6IdPD z9qILh(}3y>eJr}k-WCG#V>VN}bSrE(Z+bm~ly*OMI*>eL<3$6kL&S3bs2zfv?u54p0HONMO+SbwqEt*{qj4%N2-^&h#gZgw+1mGHzot)6Iv_cx zbA9eI=l*YkZs)d^^B>hkRog>@KNz-FYtH8L{5n~H2z z86lOagrt<<37|=*zkxqC?6I5~_Ln&mL26bjH8(<-u)E3!PvDuE&Cqez?B0341@4SW z+kx$#zyC3Pcvvhv0bqox$@(J*jwqQp%E#0;@f(H|_)$CFTv#x?W$1%T*szx)259sYyWX7Fy*L0s2p`aZ0n@fTJ!|q z=WA@9X^xs!>sgd~nMnsEW=Y@8W}-A|H3Xto54VkV^Lmr$qgRG&PISI)>_V!9n_=_z ztAqfylv|tE7z6h|kDXauZ#eLqR@ukR|AgD!Z(JJ*q|0llTi^vv=n> zTCLcIsJmc^lILWvB!ZFrJT`B$tND(7%qhHqa!@b^l=QCPGP_UvpQ6H|dh zB9KonQg>z)vgV-`p^okMc|Vch^SmK7&tE5u&|KYpvgh;z}kj9y)#>Gqx4N3 z|L)f2u1oE|kS2NaJ$0pno7MjMvU<_rJYx6QT9K#nUi@zfM-pX*FXJd9i#p;8HV==1 zps|WzL&$JxSyY@hYV$#PrZ8ZKjLmBlrFr=

;MvmDG&_acN{3|?=zOPgfi z??HSXdPWrbk#s1lWc*Eyc9jvRJKTzW{TR(CnJmHIatqMUad5OIoN=vpbh}sKh0z`< zy#v!)s7X3VNCEdBD&I3K24w$pg(p}f77$EiQTAujre?dP$~=K1AC!HSNh6)k-!b4L z|2lIea1rCaSolrrD6gktS12EfCtLOXdxFp3oWn6CFe3&DDuzgg_YDCF6)_eB6t5Qn zu)0$2|J)VxRa^QzE<3&p`!F#uAutIB1uG5%0vZJX1QfW+o}fU7ZMcNCswNS%Np04F T>E;9ouY>3iVWTE;0s;sC1D?Nf literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/multiplecerts.p12 b/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers/testdata/multiplecerts.p12 new file mode 100644 index 0000000000000000000000000000000000000000..bef8ca44f08b3fd5e660f103f2a90756f10ab288 GIT binary patch literal 3101 zcmV+&4C3=Jf(#h~0Ru3C3*QC_Duzgg_YDCD0ic2l&;)`D%rJrr$S{Hie+CIEhDe6@ z4FLxRpn?W)FoFhb0s#Opf(B&<2`Yw2hW8Bt2LUh~1_~;MNQU1l>fmyj!T|H9mK+$4Chuc5Jnc06cp&)jPUi zh$Z=wBlM;xmW(S!eaYjM@n=YDWfJ`~?LfcZmO)WiF(hxYY~Lns|4_F{mwA=L}`BEbsB z-JkAK%rB;pmja_NYqN1yVVui(jq`+_uExgXR{+)$54kMuiT~Tgm9A@OUugep}}5-r6@*f~9)t)q6OVS^a zC}y9z1zUMf?9*Ga8R5vh_h7O9O>!yw20{Cr?o{Kw$~zgpXccGXtAE;gPVlgRXp^9Y z=lMHFM@}AN^v&@Ll0{Sky8)x;q%9~F{-t`U3%>bo4zD{g?2UB7+15Br<;PzHJrBxO zooq|ctY7Lu*t@4P|lTH@Xeh+wX-^#+zrC%{A}7Al7{y==M^gm zBLy4_Dtftl!x<}rV}xY*QJxCki3|Yg@I;2>qQ!5M=U{@vjHWSyU4|g#6AWXcR=SVQ zc`A5zSKw`#?t0YDeNaEx9>5?jW~Mxek(Lt3EbxU@l<>={Jrfd7cLA16@f^e|gn1%r z-G6+uq9I}X&T#Gq49@(^_FDzeTL^;$=UV^ZglY_@$#Ta~v!v2}o;ngW2vUs3Fr#5?LlFJiWVnCjaNnBequLTwc$PBC zpq0#}wr<)drkH_Nr$Eh`CPuKo;IexxIE(IuR14|S#O3)XwTZms1C%hiseT;e3eLHv zv|xHzpmU4xH3fK!>RiNBRw>OH@bk6N=iNMm_LrrX*`KiE(AnhCpcX(i?4Ov7X?X>} z`1%HN^UB=atI>PdEuHKRBoy=Cxq;Rm(cOn>C@Gec@s-k0tdkVEH?fBM%$lrKYnDzt z{5KaGzU(oY1_sfw(m(=1^KIt_jF4xP@2AvQPQ1noZ+27Rg+I==j@(YLl}g2&k`1t> zQEuhY>JI52;=i%GZc13n|3u1=)F=?=jr;leWz2L)f@hAQJaFFeRkeCxRIG)qu6(?d z_d>MTH?sCtU_;GCxM-|Tyt{s7P?x#!+nqB7$#WBgW0(B~0WJn1A;GVW`x=x~L&DVe z1@y?t)?6J#kOhya&v(X$;FVmT6|x$3SPCpunR?`(zdz~U{t?}cs2ds;C^*S+1O*N)bR@KYF0^!7AQ59{nP~?wVk{tZm+kUwAo1LXL*Rx=MzNTpnkZx~qsx31m z1j2d@E^4r{2#`;2{^mpfN5d@@IKph5LRD1?J>yD1Y5f5-$Z1$4`V0G-E^bAy|5S|E z3ISyI-yTA~Fy~d@2S~veK?Ik@k;8H>PA{8RaznZs$(DZ&7dut7VP;A=FoFd^1_>&L zNQUaagB>ZN*F8THNY3;2;*S?c=;`n0!b$mv%~?+FKZh_-M@gBD zWj`uyTvln!>_m()608=x8s;X}^JK*N^@sRMFz-CD#`=hRRUbh1jdiDFrBv@61}huP zK=rBF5ptER+UN_jkYU8v@<%f!YytN#V*{RwZKC4M82{{NAr*#3E3g@H+tS}ZmcNw&qBYjjZEPLL$kotBEwNq*o4q>;XoE(#6|eCW?@tGPUKIQx!%nf z6Y^*kP-3g2J62y&d2|Xk5f0IH8wXw~e(7pUMAdC32?>6>7>t-Q0F|Hyyj1A$7%md- zz-w<3Gbx-*f$5>rAu@R6HGO5wr8$os+mcXL-|+tv0Q3XhamXZxICQn*#8J#1aT8FF zO&P&m2P8;#G`9?^Epc#dS!&%3yJF^hO=`MO)AMXCM! zKtZ}dS)EB4i=Ztb3RJ*F$4(Qe`A`}j&WcIHzF*vsxCEl#rLBE>iC_5q1}V{pB^%&j zX*&qwIXeb)%&*o4Nc`Tqi`6yC+)Z3zy^w{OvS*6+`O?O!Ra*l;(+=-J3aFUmrRz_7 z)oFCf0f)-}3~gI76^d56NX{LShC;=9@6_?Ru7m-0jz| zZ<@M11!h~qcdI;hJI+4LRFYWyWYMNZP!{xcLJcGh3A;$qE52KSVeHaJg}Ve z2!j>ahBl+gwp+})^}}Zj|3pG=qq|7r&ky{XfCn@K6QK&zl0#WHFy)DF6ACXPn7f+Q zCLE`?iNo>R=2&|3)CDSdvv9n}q@AG^^G|evBvAJe&Xo{Nq4@WIk|QodZoJj zJ9NA$$isDb!gPhv&3IhSrdscIMkId#66gXfd><@kDtYnPD?pGwTV0aKTPsQ_9-DmMZJ7kZ8>lZf|MTuRMYxjzZN zZG2EOZzf!=naOcOq$P8}${6xk4a!r@1=E)*bdN|M9zf@CzxloBDWLd< z3Ahm@tT|Bf#CkQa?6QBR2DLm7_;V0K)If2AvZpYa%bemDq;^?!@*~4Wi;Q>#@e-bH z?AB-(i{N|HD?df!_%(ZvR}sI3K@&0TY7V-Ot@bycrm17BHJ>^TQEAPi{lhcGq2GSfW{rKBKw5e&V>>y?eST-3 znT8Jsc>5iX(nVzeDow6JDsxmcC#Kb;xsPjcbiSh*>01VnT_vjf=BV|=hd=+NGXot)D3jy}V!q2HI30y1KkUsnlG8T*glKI>1nNlpN}>*Hv% z9e1Z3A6FJnbi}Xb&okx8IFuL8PUT2fj0^@3^#!Cwd*!6N}M(Zk6$L^*b}F})bE7$ z*7Ry@yL;Gqn`**cE(7dB@ej5oA>W5Zaf6aQq$5T#o(%_%B~7Lu@B2o*qB`gF0mgS8 zniK-}Mwr(nU?<2QUJOvdwtfb-_WdIet@2;KffQ90ALwC&W^$1Or}V4s*UVN9LmC7} zgtsfmxA2rCyk)2%Zn_?oCj+_i;x%2s%?2T^gr8G_(RxzuLkZtUSFnm++}QzUIhIJ5 z6ty_HNhq}H{IfuT?Nh2{GJ6tSy3kV2^>AoBD4-(^)h)QcC~4vK(Dao`PC-~;ae(qp z$k+s46hAC%GO?;qfQs!;>R6r2)hy`;^SmhKszOFPx6$zc%_LM+COnOq%~Hx(orr;Z zzRnT9u%8^z72#EDR)mP!`x_P{-CAT>b@(Tvg=4b0AY34YZ7(;bHa}Abk|>>4{TExc zWIYJJp??=w79@W9D%4Y6ouVkTcZ zv8}*b>3&vK5ImSV(8lmeKxRfK$NFLasTc=``G_W-GW9{~N8Yu>U{I90@z}+;4In3` z%=!-{ynVwe+4@VLElYkVSbsS8W$$qj%_kyI!aIIla8%Ywb#>WVbUuiY{$p#)xY`BJ zCM1cFwVFq>Qdca2bul-GUhWEK0p`hx*)lh()Km#Qp{}z5w#LSqGefH-^cKF7B^(CM zjZIaG0-<<93S=$KQ*Y8@TuT9x>@lay2ksOe+VTzJ+a*@++Z}btr ziiAMb@+ksMtMNaOV9~U)U^K1tSuAmOVi1P^utE<2p82zV2G7R-X#@JB4K(fqfqDRo z`lAgP4gOgFtLASECaxgFS<&=P*x-ZXxN!fOVA}%VgS?;WI!mgB^I=$UL~VX!3m5Xv zq(Ck%?=vYr1GDzcjuborG-)xyh_*gg?uq;Gf_hrlOKY9$F9F-rHCDN>JX-{JA2p6=jXdFU@9ZsnjRcPYdJ$Bnyodj1U%+v zeP&wn0cv>ivk+ilG+xUQu~X>QGh13p1*o?p(ZC#DQ1aJ7K8WrpdFuq+J4 zr9FHijXr*f=jV2vW+641ob~Hi%nL*a%>dY*tKXQHOsRHX>yUgRSE+6D^$EoEjYUY9 z5c`&}H)-DR`+%FgZHQ-&_JQGZ9i~u(QE(ODy7=BBSIjR|`-Q*pDn2Arub7%IX?)Qk zw*%Q1j~ZKy-wI`k$XealI{3x{^)uwIZ_}6kXn$fRq1o9)SPCU>8i@E+$i5dU)i}4H zjiJsqju1U|ZMvWG1idj|hSe1aP)GbHj;&>z%b!KYHTl0QV84`GVKsFB=6ATBTq1J( z+hC;10rP=`8>yi)P9%4A{g`XV%dwQe z3cY!sKcXw^+I@$lZ*;TcUTkd0qby=evI|J$n*%H=Nt>kqmHNy_)B# zFJR||_RrZ?vAHw^8`Z;eKD;{?cv+p2yn{#TE>65O%xk9$?~b#(bTMHLIkPV~*|%&^ zi3td`Ot*1(lt>9*1{$Y2)pljonF8>9Fyu#J)0DYa>w50=>``U+C`0Uo$D|Rfa$OHr z3EI5!*jPt?1F?xB1Hz2W10^DNq58Kd#?I!)%@ybq8gME4o{37Hgb-`#{`g1K>W_ErIWcof&=V6&`+U!YYQ)eP-hRr+rPxQ-mRc`U(`rz;zVx{iyU8zqymu85 zNcPj=)jdb7}F#0x+1-enH$4N)hXzVP}pY@I0ETSQ?nJ8PS85} zIXet|sr5N8u{@425UlW7%BgZ%e@>va2$!YX+jzCKIw@4q;&9))DXT%V==y~NAK4cz z6R{eP(m1Y}Ac&w7y4Kyxcn9P=;je@^T<_{FlRn07#=W7Zeq`=lDVWovi#@*qKvkQU z;Y_Gtc@nYQ%Y>fmZhr=z2VM2W#_w7F@McJwVHd`+lpJqDf!ADumC8mhSZ_#xyYwnUcS8V9ei?&Bh&+L=(x&>_>9>W zbof7iSU8*iEPE=NzRM9U4p{m1{k0k#*FCRMZ)@Q~43fEs5c#i;FisgRFh|vSKy|D6 z_UTv7U$^ba%F;JF87K%Dgb)G-p}oQk0{%ry1LokG+K!U49|xeC+L#{0WxuKT7@!Tvf+j literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/info/info.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/info/info.go new file mode 100644 index 00000000000..926a411ffbb --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/info/info.go @@ -0,0 +1,15 @@ +// Package info contains the definitions for the info endpoint +package info + +// Req is the request struct for an info API request. +type Req struct { + Label string `json:"label"` + Profile string `json:"profile"` +} + +// Resp is the response for an Info API request. +type Resp struct { + Certificate string `json:"certificate"` + Usage []string `json:"usages"` + ExpiryString string `json:"expiry"` +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca.go index db775375747..94ba26cdf59 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca.go @@ -23,24 +23,28 @@ import ( ) // validator contains the default validation logic for certificate -// requests to the API server. This follows the Baseline Requirements -// for the Issuance and Management of Publicly-Trusted Certificates, -// v.1.1.6, from the CA/Browser Forum -// (https://cabforum.org). Specifically, section 10.2.3 ("Information -// Requirements"), states: -// -// "Applicant information MUST include, but not be limited to, at least one -// Fully-Qualified Domain Name or IP address to be included in the Certificate’s -// SubjectAltName extension." +// authority certificates. The only requirement here is that the +// certificate have a non-empty subject field. func validator(req *csr.CertificateRequest) error { - if len(req.Hosts) == 0 { - return cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("missing hosts field")) + if req.CN != "" { + return nil } + + if len(req.Names) == 0 { + return cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("missing subject information")) + } + + for i := range req.Names { + if csr.IsNameEmpty(req.Names[i]) { + return cferr.Wrap(cferr.PolicyError, cferr.InvalidRequest, errors.New("missing subject information")) + } + } + return nil } // New creates a new root certificate from the certificate request. -func New(req *csr.CertificateRequest) (cert, key []byte, err error) { +func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) { if req.CA != nil { if req.CA.Expiry != "" { CAPolicy.Default.ExpiryString = req.CA.Expiry @@ -53,7 +57,7 @@ func New(req *csr.CertificateRequest) (cert, key []byte, err error) { } g := &csr.Generator{Validator: validator} - csr, key, err := g.ProcessRequest(req) + csrPEM, key, err = g.ProcessRequest(req) if err != nil { log.Errorf("failed to process request: %v", err) key = nil @@ -73,7 +77,7 @@ func New(req *csr.CertificateRequest) (cert, key []byte, err error) { } s.SetPolicy(CAPolicy) - signReq := signer.SignRequest{Hosts: req.Hosts, Request: string(csr)} + signReq := signer.SignRequest{Hosts: req.Hosts, Request: string(csrPEM)} cert, err = s.Sign(signReq) return diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca_test.go index 373ff3d46a4..94f74f0d0fb 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/initca/initca_test.go @@ -93,7 +93,7 @@ func TestInitCA(t *testing.T) { Size: param.keyLen, }, } - certBytes, keyBytes, err := New(req) + certBytes, _, keyBytes, err := New(req) if err != nil { t.Fatal("InitCA failed:", err) } @@ -169,35 +169,6 @@ func TestInitCA(t *testing.T) { } } -func TestNoHostname(t *testing.T) { - req := &csr.CertificateRequest{ - Names: []csr.Name{ - { - C: "US", - ST: "California", - L: "San Francisco", - O: "CloudFlare", - OU: "Systems Engineering", - }, - }, - CN: "cloudflare.com", - // Empty hosts - Hosts: []string{}, - KeyRequest: &csr.KeyRequest{ - Algo: "rsa", - Size: 2048, - }, - } - _, _, err := New(req) - if err == nil { - t.Fatal("InitCA should failed.") - } - - if !strings.Contains(err.Error(), `"code":5300`) { - t.Fatal(err) - } -} - func TestInvalidCryptoParams(t *testing.T) { var req *csr.CertificateRequest hostname := "cloudflare.com" @@ -219,7 +190,7 @@ func TestInvalidCryptoParams(t *testing.T) { Size: test.keyLen, }, } - _, _, err := New(req) + _, _, _, err := New(req) if err == nil { t.Fatal("InitCA with bad params should fail:", err) } @@ -229,3 +200,36 @@ func TestInvalidCryptoParams(t *testing.T) { } } } + +type validation struct { + r *csr.CertificateRequest + v bool +} + +var testValidations = []validation{ + {&csr.CertificateRequest{}, false}, + {&csr.CertificateRequest{ + CN: "test CA", + }, true}, + {&csr.CertificateRequest{ + Names: []csr.Name{csr.Name{}}, + }, false}, + {&csr.CertificateRequest{ + Names: []csr.Name{ + csr.Name{O: "Example CA"}, + }, + }, true}, +} + +func TestValidations(t *testing.T) { + for i, tv := range testValidations { + err := validator(tv.r) + if tv.v && err != nil { + t.Fatalf("%v", err) + } + + if !tv.v && err == nil { + t.Fatalf("%d: expected error, but no error was reported", i) + } + } +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config/config.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config/config.go new file mode 100644 index 00000000000..2f9eb307f5c --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config/config.go @@ -0,0 +1,28 @@ +// Package config in the ocsp directory provides configuration data for an OCSP +// signer. +package config + +import ( + "time" +) + +// Config contains configuration information required to set up an OCSP +// signer. If PKCS11.Module is non-empty, PKCS11 signing will be used. +// Otherwise signing from a key file will be used. +type Config struct { + CACertFile string + ResponderCertFile string + KeyFile string + Interval time.Duration + PKCS11 PKCS11Config +} + +// PKCS11Config contains information specific to setting up a PKCS11 OCSP +// signer. +type PKCS11Config struct { + Module string + Token string + PIN string + Label string +} + diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/ocsp_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/ocsp_test.go new file mode 100644 index 00000000000..8e2977efe5b --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/ocsp_test.go @@ -0,0 +1,151 @@ +package ocsp + +import ( + "io/ioutil" + "testing" + "time" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" +) + +const ( + serverCertFile = "testdata/ca.pem" + serverKeyFile = "testdata/ca-key.pem" + otherCertFile = "testdata/cert.pem" + brokenServerCert = "testdata/server_broken.crt" + brokenServerKey = "testdata/server_broken.key" + wrongServerCertFile = "testdata/server.crt" + wrongServerKeyFile = "testdata/server.key" + responseFile = "testdata/resp64.pem" + binResponseFile = "testdata/response.pem" + brokenResponseFile = "testdata/response_broken.pem" + mixResponseFile = "testdata/response_mix.pem" +) + +func TestNewSignerFromFile(t *testing.T) { + // arbitrary duration + dur, _ := time.ParseDuration("1ms") + + // nonexistent files + _, err := NewSignerFromFile("", "", "", dur) + if err == nil { + t.Fatal("Failed to issue error on improper file") + } + + _, err = NewSignerFromFile(serverCertFile, "", "", dur) + if err == nil { + t.Fatal("Failed to issue error on improper file") + } + + _, err = NewSignerFromFile(serverCertFile, otherCertFile, "", dur) + if err == nil { + t.Fatal("Failed to issue error on improper file") + } + + // malformed certs + _, err = NewSignerFromFile(brokenServerCert, otherCertFile, serverKeyFile, dur) + if err == nil { + t.Fatal("Didn't fail on malformed file") + } + + _, err = NewSignerFromFile(serverCertFile, brokenServerCert, serverKeyFile, dur) + if err == nil { + t.Fatal("Didn't fail on malformed file") + } + + _, err = NewSignerFromFile(serverCertFile, otherCertFile, brokenServerKey, dur) + if err == nil { + t.Fatal("Didn't fail on malformed file") + } + + // expected case + _, err = NewSignerFromFile(serverCertFile, otherCertFile, serverKeyFile, dur) + if err != nil { + t.Fatalf("Signer creation failed %v", err) + } +} + +func TestSign(t *testing.T) { + dur, _ := time.ParseDuration("1ms") + // expected case + s, err := NewSignerFromFile(serverCertFile, otherCertFile, serverKeyFile, dur) + if err != nil { + t.Fatalf("Signer creation failed: %v", err) + } + + _, err = s.Sign(SignRequest{}) + if err == nil { + t.Fatal("Signed request with nil certificate") + } + + certPEM, err := ioutil.ReadFile(otherCertFile) + if err != nil { + t.Fatal(err) + } + + cert, err := helpers.ParseCertificatePEM(certPEM) + if err != nil { + t.Fatal(err) + } + + req := SignRequest{ + Certificate: cert, + Status: "good", + } + + _, err = s.Sign(req) + if err != nil { + t.Fatal("Sign failed") + } + + sMismatch, err := NewSignerFromFile(wrongServerCertFile, otherCertFile, wrongServerKeyFile, dur) + _, err = sMismatch.Sign(req) + if err == nil { + t.Fatal("Signed a certificate from the wrong issuer") + } + + // incorrect status code + req.Status = "aalkjsfdlkafdslkjahds" + _, err = s.Sign(req) + if err == nil { + t.Fatal("Failed to fail on improper status code") + } + + // revoked + req.Status = "revoked" + _, err = s.Sign(req) + if err != nil { + t.Fatal("Error on revoked certificate") + } +} + +func TestNewSourceFromFile(t *testing.T) { + _, err := NewSourceFromFile("") + if err == nil { + t.Fatal("Didn't fail on non-file input") + } + + // expected case + _, err = NewSourceFromFile(responseFile) + if err != nil { + t.Fatal(err) + } + + // binary-formatted file + _, err = NewSourceFromFile(binResponseFile) + if err != nil { + t.Fatal(err) + } + + // the response file from before, with stuff deleted + _, err = NewSourceFromFile(brokenResponseFile) + if err != nil { + t.Fatal(err) + } + + // mix of a correct and malformed responses + _, err = NewSourceFromFile(mixResponseFile) + if err != nil { + t.Fatal(err) + } +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11.go new file mode 100644 index 00000000000..3d2f7f76ce8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11.go @@ -0,0 +1,42 @@ +// Package pkcs11 in the ocsp directory provides a way to construct a +// PKCS#11-based OCSP signer. It is only available in binaries built with the +// pkcs11 tag, i.e. `go build -tags pkcs11 ./cmd/cfssl`. +// +build pkcs11 + +package pkcs11 + +import ( + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp" + ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config" + "io/ioutil" +) + +// Enabled is set to true if PKCS #11 support is present. +const Enabled = true + +// New returns a new PKCS #11 signer. +func NewPKCS11Signer(cfg ocspConfig.Config) (ocsp.Signer, error) { + log.Debugf("Loading PKCS #11 module %s", cfg.PKCS11.Module) + certData, err := ioutil.ReadFile(cfg.CACertFile) + if err != nil { + return nil, errors.New(errors.CertificateError, errors.ReadFailed) + } + + cert, err := helpers.ParseCertificatePEM(certData) + if err != nil { + return nil, err + } + + PKCS11 := cfg.PKCS11 + priv, err := pkcs11key.New(PKCS11.Module, PKCS11.Token, PKCS11.PIN, + PKCS11.Label) + if err != nil { + return nil, errors.New(errors.PrivateKeyError, errors.ReadFailed) + } + + return ocsp.NewSigner(cert, cert, priv, cfg.Interval) +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11_stub.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11_stub.go new file mode 100644 index 00000000000..73c27511d3e --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11/pkcs11_stub.go @@ -0,0 +1,17 @@ +// +build !pkcs11 + +package pkcs11 + +import ( + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp" + ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config" +) + +// Enabled is set to true if PKCS #11 support is present. +const Enabled = false + +// NewPKCS11Signer returns a new PKCS #11 signer. +func NewPKCS11Signer(cfg ocspConfig.Config) (ocsp.Signer, error) { + return nil, errors.New(errors.PrivateKeyError, errors.Unavailable) +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem new file mode 100644 index 00000000000..5d4f8b557a2 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvKOCXwP8Y6x1YkjcimQafnP1bRCF/iWY+z4ffuTWA150RRpA +GnhwOen8muU5wxOEm1A2IkWhNfXQ9GYVdOnzXumTx9Go4Gm8/1nRCYG69GZbQAEr +pNGx/l4wReLVj2iizCf/xkcch5ZM/5zplXWZXCQiavmKz6M+1aSYdsGP0mrLu31c +yod2iJmlISt+nuP5yXkgoKxzGrKjP5qrs6XniVXrKMt+5g1Ta5blWUoft2pwM6yp +8+IAtxh+iYTIJc8dDHbVl9AjVfsfaYeS8SkHcIRyIuD8/3HgLmP/gMLDzuLXvH+W +slOEYqLGMkSo2JPOwLguggDyjt1rI2cEcFkgJwIDAQABAoIBAQCTAZW6+D87ag28 +f22nR+XBwBp2WVcivSggO8SNvkXuMDDKHW/xcQR8jZW3HIZMOSyxYOwe/0Zn595k +aB22lA9+Wuc45HIIGT8ZfGREVV5d0lqwYXkio+xjgAF8pQ6rCO89zLouSgK4w2/U +D/OU7yWJwfs0hK4hrGVuVywd+DBd2Fc7UfZ4oEcy89mwUIRVK8+eXrRCav6lGDrz +I+GmW6GL16U8lS8vsUNciYyNYCzgSIIa/yyiZO/Aje93yJRVpmujAK2p6/w/7vmK +OareeixlpNYpiY7Nk6o3w6sKEEVzf+AquDgeH5IkzD1nkYbd+JY7bdg1cgjz3kJg +IhsiIER5AoGBAOkZpicTIsiAMxz43bzMt1IMYu1ezAEw4Vk2sVEbSfFXdbO5J9gW +/Ou+AhwxhsDeO6vgh3mYkG+2s5U+ztk68X1BVIf87kYBQiz175XvxcLmDBFm5S6g +eyTCwsop9J4XlgQQ5HNm80G9oHnF50oujCqpUiC5xj5fEd8vULmua5jTAoGBAM8r +rTTpVBHKArDlzYF5EpyXDkcFT2uAgw9Xpc6xIl/UWQ+XU1qD5Te0fmjpdwo3VZTL +W2e8eg0U9O2skrxBcRLREnh1U2znCMSIGTkwYQ2JDjhz2Jjbh8r/NhvSdydql9wQ +LGyPOIpcURaD+ohOExF82EtEqWgNp4QfQHH70cbdAoGAPBoy7yxN8aishTHd6opW +Uj+DWnTw4PW7hQdHHQSOQj4syRRao6r5t8ccQCy89AnZFO4lwEKIK2XOVBMHvpcm +IQexRgb/YOl+KJ2ZEu3p7eDnB62iNi2G0ums0/eRbRnjwlSgsui+nBrKv9s5UbVC +ytUxqeJ8rSRSNVu70sSYVaUCgYALYUrSbT7A+2fKb9UqF4x+LY4LOK90KEsKvLXO +9Mv+l5uMz7M0dapRtQh8mtZ/KSr6UXFj8WaC8XPC2of072NWtUVeeJNsmARTR2ab +TZ0HMVAmqbZsLyL2c651OMpyz9gnrnvCOtvQPeH2aqmIc0F45HK9L7hejuF00IKp +wDt1wQKBgQC8sjlF/8e03m3AfLs2ZW/w0Rsggz52TgBdH24BMUmvd5McVZlH8uZq +zwx5ht3ppVjObG28JPEj8c/FtAmsUjURDD7EVdjb5bDxrMtH++8sHrXUuMMBeUxl +DN2IU+xL9MwMh5H0cyJbXnE+LWGpSefCccDnH5qlEjwNXE5/RggOrw== +-----END RSA PRIVATE KEY----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem new file mode 100644 index 00000000000..9775b857c0f --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/ca.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDvjCCAqigAwIBAgIIWhorb65IXvUwCwYJKoZIhvcNAQELMG0xCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2lu +ZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9y +bmlhMB4XDTE1MDQxOTE2MTAwMFoXDTIwMDQxNzE2MTAwMFowbTELMAkGA1UEBhMC +VVMxEzARBgNVBAoTCkNsb3VkRmxhcmUxHDAaBgNVBAsTE1N5c3RlbXMgRW5naW5l +ZXJpbmcxFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xEzARBgNVBAgTCkNhbGlmb3Ju +aWEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8o4JfA/xjrHViSNyK +ZBp+c/VtEIX+JZj7Ph9+5NYDXnRFGkAaeHA56fya5TnDE4SbUDYiRaE19dD0ZhV0 +6fNe6ZPH0ajgabz/WdEJgbr0ZltAASuk0bH+XjBF4tWPaKLMJ//GRxyHlkz/nOmV +dZlcJCJq+YrPoz7VpJh2wY/Sasu7fVzKh3aImaUhK36e4/nJeSCgrHMasqM/mquz +peeJVesoy37mDVNrluVZSh+3anAzrKnz4gC3GH6JhMglzx0MdtWX0CNV+x9ph5Lx +KQdwhHIi4Pz/ceAuY/+AwsPO4te8f5ayU4RiosYyRKjYk87AuC6CAPKO3WsjZwRw +WSAnAgMBAAGjZjBkMA4GA1UdDwEB/wQEAwIABjASBgNVHRMBAf8ECDAGAQH/AgEC +MB0GA1UdDgQWBBSrzjPP4Y5PLsqeyp6iddofBjoRmTAfBgNVHSMEGDAWgBSrzjPP +4Y5PLsqeyp6iddofBjoRmTALBgkqhkiG9w0BAQsDggEBAH7McpSm7+DeIZPQKYpF +kFUlNn3N4MRvek5lxOw6jLE1QmzG3lTB79g6iBiGKsYLPoJqNS6VxMoLrMC+qFhM +0QM5eIzRpdfYa83IDIYcbUYx7fLG/azX+FMFh/O5yPtS+bqbxGinxofRIyuKGs9r +dks6I5lGncRs0Liysp4mHJAjyj9G2W2onI3Y00BYhiOy4mYvZ5/S31KI4550HZ+p +dnexuC29CsWGkOTXTOS7+e7Zmbh8UjsYcA5YOojew+EjJfETPVO+Pn7WGg/+XrFX +8UOG3o9k8M0ePQof4R6FTJ+BQxtSkWWdp1HrMQbZ1TXfZx84XkmFdcmy8FjYiHbP +M+M= +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem new file mode 100644 index 00000000000..f3cad55e49f --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/cert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4TCCAsugAwIBAgIIEoDcqfKl/s4wCwYJKoZIhvcNAQELMG0xCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpDbG91ZEZsYXJlMRwwGgYDVQQLExNTeXN0ZW1zIEVuZ2lu +ZWVyaW5nMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRMwEQYDVQQIEwpDYWxpZm9y +bmlhMB4XDTE1MDQxOTE2MTkwMFoXDTE2MDQxODE2MTkwMFowXTELMAkGA1UEBhMC +VVMxEDAOBgNVBAoTB0V4YW1wbGUxDzANBgNVBAsTBlRoaW5nczEWMBQGA1UEBxMN +U2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5pYTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAK7jUnRUeD5QY9YPjbW6aiGkVWRWAebi4nZl++C+ +HEBHSyB0jXX+J93y97PuhgeguCuMM6KZU7C0tPZKjwdxBSqpXeyFpvcj+UWMjZjz +9FrBAzZ1DIYquqfYuKUtavoFv29IomRqzyZ4FrMJ2qy0RudnWMTqn4P6/7DrWos+ +oJMCpl/mdWl+YXMXypgW5JwM7ladx8GkEKQwGMtXrG9pop7qS6LNikN76tLPYWjR +DhrWLBe8gCGjuXkwvxw78CeeJNyWF+P/+x4lVsWphip3jX57SUx/bjaRjsWSfpMz +xHueHtuCrGffgCkFzYH1/Z60FZNxuHYqJeL4V3gcR8IIaZECAwEAAaOBmDCBlTAO +BgNVHQ8BAf8EBAMCAKAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwG +A1UdEwEB/wQCMAAwHQYDVR0OBBYEFBnFrxc1gkG2CYImTYKL0DAaGxRBMB8GA1Ud +IwQYMBaAFKvOM8/hjk8uyp7KnqJ12h8GOhGZMBYGA1UdEQQPMA2CC2V4YW1wbGUu +Y29tMAsGCSqGSIb3DQEBCwOCAQEAX31Jk7R9gDMw/gepIxxeKx9m+c7eOYDxjJ12 +bfXQVKNNPLZsO9M9r2/0BCTFsNTF2jh6ZTeIf7qy+Jw08YqTcO5m8jhiGzCjOYu5 +tiGxCUe+cYjXcCRk83+XGkVrQm3fQ0cVtic0yfm/fez3iv915jH0GYO5X8/d7bKa +0kWJ3uOjur6tenfnisypEsuYYjPRcQdXSG6/qgHEc4r279Z2ltjy1bFFr86hHUbj +DX7XNWH/MXFgqLzfQm5VzmqBj9om+0/tgTWdkgI1DK/Hnvm9A4YZfaxh4fxv7ITo +Ce8FWW13Wj55x64peb8ZiW1jUyoaJQcxQxFpRHIVu26nXApWtg== +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem new file mode 100644 index 00000000000..c5152dc779c --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/resp64.pem @@ -0,0 +1 @@ +MIICGAoBAKCCAhEwggINBgkrBgEFBQcwAQEEggH+MIIB+jCB46ADAgEAoV8wXTELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGUxDzANBgNVBAsTBlRoaW5nczEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzETMBEGA1UECBMKQ2FsaWZvcm5pYRcRMTUwNDIzMTkwODAwLTA0MDAwaDBmMDswCQYFKw4DAhoFAAQUKO/Z4m+OZ4ZSKS2J85Kr9UaI2LAEFKvOM8/hjk8uyp7KnqJ12h8GOhGZAgIBdaADAQH/GA8wMDAxMDEwMTAwMDAwMFqgERgPMDAwMTAxMDEwMDAwMDBaMA0GCSqGSIb3DQEBCwUAA4IBAQCBGs+8UNwUdkEBladnajZIV+sHtmao/mMTIvpyPqnmV2Ab9KfNWlSDSDuMtZYKS4VsEwtbZ+4kKWI8DugE6egjP3o64R7VP2aqrh41IORwccLGVsexILBpxg4h602JbhXM0sxgXoh5WAt9f1oy6PsHAt/XAuJGSo7yMNv3nHKNFwjExmZt21sNLYlWlljjtX92rlo/mBTWKO0js4YRNyeNQhchARbn9oL18jW0yAVqB9a8rees+EippbTfoktFf0cIhnmkiknPZSZ+dN2qHkxiXIujWlymZzUZcqRTNtrmmhlOdt35QSg7Vw8eyw2rl8ZU94zaI5DPWn1QYn0dk7l9 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response.pem new file mode 100644 index 0000000000000000000000000000000000000000..bd43e37bfd1890562dcd75c4fb8df9f6dcedc916 GIT binary patch literal 540 zcmXqLVv^uuWLVI|BxumY#LLF1&Bn;e%5K2O$kN34&!CC%mqFv>1YnJ6x3Xlh_$WMpV*WNKibYhYqvV31*u zW?&7plU19KnMsP3fki~){mn=Ded%pMn!25zC$0YK)^TG4i^%G8#^)dQ`RkpUcWU0E z(p&OuR)RB`m>5eJFf%g#m*5AQWC(^phJiuU0znKRpu;(}+C196^D;7WvobI@F)}iQ zPta&6-L@~gsr8#NN8XLh)1P!^WXf{+XM2Chvxzt`Yqx{CBFoY1TGM}-FSy-5IXr*T zhBKmDO*~?n8YEIyOFvJ2Cds8{cT|4Tzon7ZH`z{h%y-V;VlgQvnpawH{kADR)2G?| z^ehUotuQzLYN&B0ZCN?%+go>DdALoE^sE;YxRbY~;qV8Bf+@P0yfYWX*G9OUIurRq zHe>Bh<^2tdw>>)em!Es@-Zt;&brV`OxcujQl=<^U z^@fU5Va0~3YY~C>n5(x`^6io6zPnzeXO`)atmkv)n0}uidC_1E%SPpm$$L`xkAJb! NU-SNdcUg1PN&uLi!Pfu) literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem new file mode 100644 index 00000000000..29a64c66661 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_broken.pem @@ -0,0 +1 @@ +MIICGAoBAKCCAhEwggINBgkrBgEFBQcwAQEEggH+OZ4ZSKS2J85Kr9UaI2LAEFKvOM8/hjk8uyp7KnqJ12h8GOhGZAgIBdaADAQH/GA8wMDAxMDEwMTAwMDAwMFqgERgPMDAwMTAxMDEwMDAwMDBaMA0GCSqGSIb3DQEBCwUAA4IBAQCBGs+8UNwUdkEBladnajZIV+sHtmao/mMTIvpyPqnmV2Ab9KfNWlSDSDuMtZYKS4VsEwtbZ+4kKWI8DugE6egjP3o64R7VP2aqrh41IORwccLGVsexILBpxg4h602JbhXM0sxgXoh5WAt9f1oy6PsHAt/XAuJGSo7yMNv3nHKNFwjExmZt21sNLYlWlljjtX92rlo/mBTWKO0js4YRNyeNQhchARbn9oL18jW0yAVqB9a8rees+EippbTfoktFf0cIhnmkiknPZSZ+dN2qHkxiXIujWlymZzUZcqRTNtrmmhlOdt35QSg7Vw8eyw2rl8ZU94zaI5DPWn1QYn0dk7l9 \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_mix.pem b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/response_mix.pem new file mode 100644 index 0000000000000000000000000000000000000000..43249fb0aeb8001000e55d8fc0bcdf265c48ef69 GIT binary patch literal 1260 zcmZXPeQXnD9LIOvR$$8*%cc%-L4z-o3VZH$U0XoobG>VOyWaKf+G|e@xxU@??XK;$ zyS7H1B@hS%mqA1b!70(ifC33DF%n;*#E3+rF$#z#LgI|kfGJAARTi}(*S6i`pio#W~94&5kQcxCUOHbk?Y{uOLLtjq~oQH;0d%BEHQV6 zyUc^8a0p!nmbQzY!9`R}Dirf6v>)`fN$;SUS2C)sqql>hHdr*+7n0PwU1dp4Wb}lF z4uXL;Up(03l=7LhR#r389RsKp;24HFFe?CS01g09KpL!XWp-PZcAD<&?&umCy?pMX zwo~2`d~nUS-)0Y8b!|O+v}@?lC*z-fx6`-w^nud{Uap>BXZ{dzuG{9mer}hb%^p2-+X>wBcyoFigwA_djxK z-%|F(+V(pRn-8=R?zu`~1%s*VS*{-6aXVR}4-9Mkd@T14I zD@H#vu9mU;iGJSjJHa-<4PoIhXFrvKv=Bjt556)kF@9+NJ69-2c);D%# zmUEjgZ8DF19{XZ=;lMnz@bt{)(H`IaU+((rr~A&{OO$Fy8(&5P-*!HEyuS40@b+(x z4DHxw{UE!rf4}wG%<|8`;jUw=jwMbe`#=1B-PqyFH@8o15?^C!+UbTG0U4(gDwHA1 zG)Ks}G9gngB9Jg(fTCpCV`;r3ELkUkPe2mN6x1SiBg#`=7UtX#4O4`|IwKLbMv>4* z$XtYg8c%=-9urU_?he<;25kAZxy}>$pe6}cHPN61mI(YiUt_s2=Bm<^SdR(TtQ6(4 z@dm}S1a+(LBv>YZxpYYorxFEgF&0b&Sw3uVB;8>7oZ%y(;pHJ*W16du91-W{P3n&Q%2IHzj^P={w0O~MOA{>&voJ#2y zDpM@R`Lvd+xY8g&D{3K^$*F!ZBwCUjR`TR(nJ8V&3i*0LY=p%`Dadn`a-pE)eaXtW iH4u_*5yPIU8?9)&7G6(n=EyyG8D1+Gv4 literal 0 HcmV?d00001 diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.crt new file mode 100644 index 00000000000..9e4deb0e995 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.crt @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAWoCCQDidF+uNJR6czANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB +VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 +cyBQdHkgTHRkMB4XDTEyMDUwMTIyNTUxN1oXDTEzMDUwMTIyNTUxN1owRTELMAkG +A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtpjl +nodhz31kLEJoeLSkRmrv8l7exkGtO0REtIbirj9BBy64ZXVBE7khKGO2cnM8U7yj +w7Ntfh+IvCjZVA3d2XqHS3Pjrt4HmU/cGCONE8+NEXoqdzLUDPOix1qDDRBvXs81 +KAV2qh6CYHZbdqixhDerjvJcD4Nsd7kExEZfHuECAwEAATANBgkqhkiG9w0BAQUF +AAOBgQCyOqs7+qpMrYCgL6OamDeCVojLoEp036PsnaYWf2NPmsVXdpYW40Foyyjp +iv5otkxO5rxtGPv7o2J1eMBpCuSkydvoz3Ey/QwGqbBwEXQ4xYCgra336gqW2KQt ++LnDCkE8f5oBhCIisExc2i8PDvsRsY70g/2gs983ImJjVR8sDw== +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.key b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.key new file mode 100644 index 00000000000..ab101624c3f --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server.key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQC2mOWeh2HPfWQsQmh4tKRGau/yXt7GQa07RES0huKuP0EHLrhl +dUETuSEoY7ZyczxTvKPDs21+H4i8KNlUDd3ZeodLc+Ou3geZT9wYI40Tz40Reip3 +MtQM86LHWoMNEG9ezzUoBXaqHoJgdlt2qLGEN6uO8lwPg2x3uQTERl8e4QIDAQAB +AoGAVxnsPojZ8X4g8LPk3d9dlXGhb/4tSmk9102jcHH/Y5ssy95Pe6ZJGr1uwbN+ +7m1l05PikpHeoxEryoW51cyfjDVkXUT0zPp2JC38DUA/0A8qWav/aENM64wg1I0P +Dil8FywzZEonRNJst53+9cxFye70ely5br/tWxEp4/MsM1kCQQDqV4Lwn8BXOeKg +xOwNmcL+0XPedvSPBSPUoGJCzu12rH6Z+UHXipXsqRNSyQ+KGlur14y0kCh5uiVA +jmWYVEEjAkEAx3keAo1nFsVW35EPt5LIbh6L6ty7GrvGRvOVeSd6YLtixMety24k +hpt1cEv2xlFnbjbBbMkr9eUiUNpttLT6KwJBANGKaLoSjqEwUFYjX1OV/wdtcGcn +BOzx0qUouFQ2xZ0NBrNVbyt1bzPLx0yKHkwF35ybw+Qc1yRpby/3ZB6+j/MCQFLl +vtcItOL9uBDJVGLSGYHKKBO/D/MYPlqWOHRVN8KjnXRyF4QHjh5y1OeKalAY3Ict +Mk1nfWF/jDdVz2neHGkCQHHBR4Xt1/euDku+14z5aLpphTEQVuRD2vQoeKi/W/CY +OgNmKj1DzucnCS6yRCrF8Q0Pn8l054a3Wdbl1gqI/gA= +-----END RSA PRIVATE KEY----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt new file mode 100644 index 00000000000..09f3f52a442 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.crt @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtpjl +nodhz31kLEJoeLSkRmrv8l7exkGtO0REtIbirj9BBy64ZXVBE7khKGO2cnM8U7yj +w7Ntfh+IvCjZVA3d2XqHS3Pjrt4HmU/cGCONE8+NEXoqdzLUDPOix1qDDRBvXs81 +KAV2qh6CYHZbdqixhDerjvJcD4Nsd7kExEZfHuECAwEAATANBgkqhkiG9w0BAQUF +AAOBgQCyOqs7+qpMrYCgL6OamDeCVojLoEp036PsnaYWf2NPmsVXdpYW40Foyyjp +iv5otkxO5rxtGPv7o2J1eMBpCuSkydvoz3Ey/QwGqbBwEXQ4xYCgra336gqW2KQt ++LnDCkE8f5oBhCIisExc2i8PDvsRsY70g/2gs983ImJjVR8sDw== +-----END CERTIFICATE----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key new file mode 100644 index 00000000000..98e860f7340 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/testdata/server_broken.key @@ -0,0 +1,8 @@ +-----BEGIN RSA PRIVATE KEY----- +jmWYVEEjAkEAx3keAo1nFsVW35EPt5LIbh6L6ty7GrvGRvOVeSd6YLtixMety24k +hpt1cEv2xlFnbjbBbMkr9eUiUNpttLT6KwJBANGKaLoSjqEwUFYjX1OV/wdtcGcn +BOzx0qUouFQ2xZ0NBrNVbyt1bzPLx0yKHkwF35ybw+Qc1yRpby/3ZB6+j/MCQFLl +vtcItOL9uBDJVGLSGYHKKBO/D/MYPlqWOHRVN8KjnXRyF4QHjh5y1OeKalAY3Ict +Mk1nfWF/jDdVz2neHGkCQHHBR4Xt1/euDku+14z5aLpphTEQVuRD2vQoeKi/W/CY +OgNmKj1DzucnCS6yRCrF8Q0Pn8l054a3Wdbl1gqI/gA= +-----END RSA PRIVATE KEY----- diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/universal/universal.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/universal/universal.go new file mode 100644 index 00000000000..76b82b4c8f1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/universal/universal.go @@ -0,0 +1,16 @@ +package universal + +import ( + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp" + ocspConfig "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/config" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/ocsp/pkcs11" +) + +// NewSignerFromConfig generates a new OCSP signer from a config object. +func NewSignerFromConfig(cfg ocspConfig.Config) (ocsp.Signer, error) { + if cfg.PKCS11.Module != "" { + return pkcs11.NewPKCS11Signer(cfg) + } + return ocsp.NewSignerFromFile(cfg.CACertFile, cfg.ResponderCertFile, + cfg.KeyFile, cfg.Interval) +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke.go new file mode 100644 index 00000000000..3056925d4cd --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke.go @@ -0,0 +1,281 @@ +// Package revoke provides functionality for checking the validity of +// a cert. Specifically, the temporal validity of the certificate is +// checked first, then any CRL in the cert is checked. OCSP is not +// supported at this time. +package revoke + +import ( + "bytes" + "crypto" + "crypto/x509" + "crypto/x509/pkix" + "encoding/base64" + "encoding/pem" + "errors" + "io/ioutil" + "net/http" + neturl "net/url" + "time" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/golang.org/x/crypto/ocsp" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" +) + +// HardFail determines whether the failure to check the revocation +// status of a certificate (i.e. due to network failure) causes +// verification to fail (a hard failure). +var HardFail = false + +// TODO (kyle): figure out a good mechanism for OCSP; this requires +// presenting both the certificate and the issuer, and we don't have a +// good way at this time of getting the issuer. + +// CRLSet associates a PKIX certificate list with the URL the CRL is +// fetched from. +var CRLSet = map[string]*pkix.CertificateList{} + +// We can't handle LDAP certificates, so this checks to see if the +// URL string points to an LDAP resource so that we can ignore it. +func ldapURL(url string) bool { + u, err := neturl.Parse(url) + if err != nil { + log.Warningf("error parsing url %s: %v", url, err) + return false + } + if u.Scheme == "ldap" { + return true + } + return false +} + +// revCheck should check the certificate for any revocations. It +// returns a pair of booleans: the first indicates whether the certificate +// is revoked, the second indicates whether the revocations were +// successfully checked.. This leads to the following combinations: +// +// false, false: an error was encountered while checking revocations. +// +// false, true: the certificate was checked successfully and +// it is not revoked. +// +// true, true: the certificate was checked successfully and +// it is revoked. +// +// true, false: failure to check revocation status causes +// verification to fail +func revCheck(cert *x509.Certificate) (revoked, ok bool) { + for _, url := range cert.CRLDistributionPoints { + if ldapURL(url) { + log.Infof("skipping LDAP CRL: %s", url) + continue + } + + if revoked, ok := certIsRevokedCRL(cert, url); !ok { + log.Warning("error checking revocation via CRL") + if HardFail { + return true, false + } + return false, false + } else if revoked { + log.Info("certificate is revoked via CRL") + return true, true + } + + if revoked, ok := certIsRevokedOCSP(cert, HardFail); !ok { + log.Warning("error checking revocation via OCSP") + if HardFail { + return true, false + } + return false, false + } else if revoked { + log.Info("certificate is revoked via OCSP") + return true, true + } + } + + return false, true +} + +// fetchCRL fetches and parses a CRL. +func fetchCRL(url string) (*pkix.CertificateList, error) { + resp, err := http.Get(url) + if err != nil { + return nil, err + } else if resp.StatusCode >= 300 { + return nil, errors.New("failed to retrieve CRL") + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body.Close() + + return x509.ParseCRL(body) +} + +// check a cert against a specific CRL. Returns the same bool pair +// as revCheck. +func certIsRevokedCRL(cert *x509.Certificate, url string) (revoked, ok bool) { + crl, ok := CRLSet[url] + if ok && crl == nil { + ok = false + delete(CRLSet, url) + } + + var shouldFetchCRL = true + if ok { + if !crl.HasExpired(time.Now()) { + shouldFetchCRL = false + } + } + + if shouldFetchCRL { + var err error + crl, err = fetchCRL(url) + if err != nil { + log.Warningf("failed to fetch CRL: %v", err) + return false, false + } + CRLSet[url] = crl + } + + for _, revoked := range crl.TBSCertList.RevokedCertificates { + if cert.SerialNumber.Cmp(revoked.SerialNumber) == 0 { + log.Info("Serial number match: intermediate is revoked.") + return true, true + } + } + + return false, true +} + +// VerifyCertificate ensures that the certificate passed in hasn't +// expired and checks the CRL for the server. +func VerifyCertificate(cert *x509.Certificate) (revoked, ok bool) { + if !time.Now().Before(cert.NotAfter) { + log.Infof("Certificate expired %s\n", cert.NotAfter) + return true, true + } else if !time.Now().After(cert.NotBefore) { + log.Infof("Certificate isn't valid until %s\n", cert.NotBefore) + return true, true + } + + return revCheck(cert) +} + +func fetchRemote(url string) (*x509.Certificate, error) { + resp, err := http.Get(url) + if err != nil { + return nil, err + } + + in, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + resp.Body.Close() + + p, _ := pem.Decode(in) + if p != nil { + return helpers.ParseCertificatePEM(in) + } + + return x509.ParseCertificate(in) +} + +var ocspOpts = ocsp.RequestOptions{ + Hash: crypto.SHA1, +} + +func certIsRevokedOCSP(leaf *x509.Certificate, strict bool) (revoked, ok bool) { + var err error + + ocspURLs := leaf.OCSPServer + if len(ocspURLs) == 0 { + // OCSP not enabled for this certificate. + return false, true + } + + var issuer *x509.Certificate + for _, issuingCert := range leaf.IssuingCertificateURL { + issuer, err = fetchRemote(issuingCert) + if err != nil { + continue + } + break + } + + if issuer == nil { + return + } + + ocspRequest, err := ocsp.CreateRequest(leaf, issuer, &ocspOpts) + if err != nil { + return + } + + for _, server := range ocspURLs { + resp, err := sendOCSPRequest(server, ocspRequest, issuer) + if err != nil { + if strict { + return + } + continue + } + + // There wasn't an error fetching the OCSP status. + ok = true + + if resp.Status != ocsp.Good { + // The certificate was revoked. + revoked = true + } + + return + } + return +} + +var ocspUnauthorised = []byte{0x30, 0x03, 0x0a, 0x01, 0x06} +var ocspMalformed = []byte{0x30, 0x03, 0x0a, 0x01, 0x01} + +// sendOCSPRequest attempts to request an OCSP response from the +// server. The error only indicates a failure to *fetch* the +// certificate, and *does not* mean the certificate is valid. +func sendOCSPRequest(server string, req []byte, issuer *x509.Certificate) (ocspResponse *ocsp.Response, err error) { + var resp *http.Response + if len(req) > 256 { + buf := bytes.NewBuffer(req) + resp, err = http.Post(server, "application/ocsp-request", buf) + } else { + reqURL := server + "/" + base64.StdEncoding.EncodeToString(req) + resp, err = http.Get(reqURL) + } + + if err != nil { + return + } + + if resp.StatusCode != http.StatusOK { + return + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return + } + resp.Body.Close() + + if bytes.Equal(body, ocspUnauthorised) { + return + } + + if bytes.Equal(body, ocspMalformed) { + return + } + + return ocsp.ParseResponse(body, issuer) +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke_test.go new file mode 100644 index 00000000000..02e5baa0675 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke/revoke_test.go @@ -0,0 +1,223 @@ +package revoke + +import ( + "crypto/x509" + //"crypto/x509/pkix" + "encoding/pem" + "fmt" + "os" + "testing" + "time" +) + +// The first three test cases represent known revoked, expired, and good +// certificates that were checked on the date listed in the log. The +// good certificate will eventually need to be replaced. + +// If there is a soft-fail, the test will pass to mimic the default +// behaviour used in this software. However, it will print a warning +// to indicate that this is the case. + +// 2014/05/22 14:18:17 Certificate expired 2014-04-04 14:14:20 +0000 UTC +// 2014/05/22 14:18:17 Revoked certificate: misc/intermediate_ca/ActalisServerAuthenticationCA.crt +var expiredCert = mustParse(`-----BEGIN CERTIFICATE----- +MIIEXTCCA8agAwIBAgIEBycURTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTA3MDQwNDE0MTUxNFoXDTE0MDQwNDE0MTQyMFowejELMAkG +A1UEBhMCSVQxFzAVBgNVBAoTDkFjdGFsaXMgUy5wLkEuMScwJQYDVQQLEx5DZXJ0 +aWZpY2F0aW9uIFNlcnZpY2UgUHJvdmlkZXIxKTAnBgNVBAMTIEFjdGFsaXMgU2Vy +dmVyIEF1dGhlbnRpY2F0aW9uIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv6P0bhXbUQkVW8ox0HJ+sP5+j6pTwS7yg/wGEUektB/G1duQiT1v21fo +LANr6F353jILQDCpHIfal3MhbSsHEMKU7XaqsyLWV93bcIKbIloS/eXDfkog6KB3 +u0JHgrtNz584Jg/OLm9feffNbCJ38TiLo0/UWkAQ6PQWaOwZEgyKjVI5F3swoTB3 +g0LZAzegvkU00Kfp13cSg+cJeU4SajwtfQ+g6s6dlaekaHy/0ef46PfiHHRuhEhE +JWIpDtUN2ywTT33MSSUe5glDIiXYfcamJQrebzGsHEwyqI195Yaxb+FLNND4n3HM +e7EI2OrLyT+r/WMvQbl+xNihwtv+HwIDAQABo4IBbzCCAWswEgYDVR0TAQH/BAgw +BgEB/wIBADBTBgNVHSAETDBKMEgGCSsGAQQBsT4BADA7MDkGCCsGAQUFBwIBFi1o +dHRwOi8vd3d3LnB1YmxpYy10cnVzdC5jb20vQ1BTL09tbmlSb290Lmh0bWwwDgYD +VR0PAQH/BAQDAgEGMIGJBgNVHSMEgYEwf6F5pHcwdTELMAkGA1UEBhMCVVMxGDAW +BgNVBAoTD0dURSBDb3Jwb3JhdGlvbjEnMCUGA1UECxMeR1RFIEN5YmVyVHJ1c3Qg +U29sdXRpb25zLCBJbmMuMSMwIQYDVQQDExpHVEUgQ3liZXJUcnVzdCBHbG9iYWwg +Um9vdIICAaUwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL3d3dy5wdWJsaWMtdHJ1 +c3QuY29tL2NnaS1iaW4vQ1JMLzIwMTgvY2RwLmNybDAdBgNVHQ4EFgQUpi6OuXYt +oxHC3cTezVLuraWpAFEwDQYJKoZIhvcNAQEFBQADgYEAAtjJBwjsvw7DBs+v7BQz +gSGeg6nbYUuPL7+1driT5XsUKJ7WZjiwW2zW/WHZ+zGo1Ev8Dc574RpSrg/EIlfH +TpBiBuFgiKtJksKdoxPZGSI8FitwcgeW+y8wotmm0CtDzWN27g2kfSqHb5eHfZY5 +sESPRwHkcMUNdAp37FLweUw= +-----END CERTIFICATE-----`) + +// 2014/05/22 14:18:31 Serial number match: intermediate is revoked. +// 2014/05/22 14:18:31 certificate is revoked via CRL +// 2014/05/22 14:18:31 Revoked certificate: misc/intermediate_ca/MobileArmorEnterpriseCA.crt +var revokedCert = mustParse(`-----BEGIN CERTIFICATE----- +MIIEEzCCAvugAwIBAgILBAAAAAABGMGjftYwDQYJKoZIhvcNAQEFBQAwcTEoMCYG +A1UEAxMfR2xvYmFsU2lnbiBSb290U2lnbiBQYXJ0bmVycyBDQTEdMBsGA1UECxMU +Um9vdFNpZ24gUGFydG5lcnMgQ0ExGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +CzAJBgNVBAYTAkJFMB4XDTA4MDMxODEyMDAwMFoXDTE4MDMxODEyMDAwMFowJTEj +MCEGA1UEAxMaTW9iaWxlIEFybW9yIEVudGVycHJpc2UgQ0EwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCaEjeDR73jSZVlacRn5bc5VIPdyouHvGIBUxyS +C6483HgoDlWrWlkEndUYFjRPiQqJFthdJxfglykXD+btHixMIYbz/6eb7hRTdT9w +HKsfH+wTBIdb5AZiNjkg3QcCET5HfanJhpREjZWP513jM/GSrG3VwD6X5yttCIH1 +NFTDAr7aqpW/UPw4gcPfkwS92HPdIkb2DYnsqRrnKyNValVItkxJiotQ1HOO3YfX +ivGrHIbJdWYg0rZnkPOgYF0d+aIA4ZfwvdW48+r/cxvLevieuKj5CTBZZ8XrFt8r +JTZhZljbZvnvq/t6ZIzlwOj082f+lTssr1fJ3JsIPnG2lmgTAgMBAAGjgfcwgfQw +DgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFIZw +ns4uzXdLX6xDRXUzFgZxWM7oME0GA1UdIARGMEQwQgYJKwYBBAGgMgE8MDUwMwYI +KwYBBQUHAgIwJxolaHR0cDovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5 +LzA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0L1Jv +b3RTaWduUGFydG5lcnMuY3JsMB8GA1UdIwQYMBaAFFaE7LVxpedj2NtRBNb65vBI +UknOMA0GCSqGSIb3DQEBBQUAA4IBAQBZvf+2xUJE0ekxuNk30kPDj+5u9oI3jZyM +wvhKcs7AuRAbcxPtSOnVGNYl8By7DPvPun+U3Yci8540y143RgD+kz3jxIBaoW/o +c4+X61v6DBUtcBPEt+KkV6HIsZ61SZmc/Y1I2eoeEt6JYoLjEZMDLLvc1cK/+wpg +dUZSK4O9kjvIXqvsqIOlkmh/6puSugTNao2A7EIQr8ut0ZmzKzMyZ0BuQhJDnAPd +Kz5vh+5tmytUPKA8hUgmLWe94lMb7Uqq2wgZKsqun5DAWleKu81w7wEcOrjiiB+x +jeBHq7OnpWm+ccTOPCE6H4ZN4wWVS7biEBUdop/8HgXBPQHWAdjL +-----END CERTIFICATE-----`) + +// 2014/05/22 14:18:51 added misc/intermediate_ca/GandiProSSLCA.crt to intermediate bundle +var goodstring = (`-----BEGIN CERTIFICATE----- +MIIEnjCCA4agAwIBAgIQPBkQvAZ54yVvTfQWo16zFDANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNMDgxMDIzMDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA8MQswCQYD +VQQGEwJGUjESMBAGA1UEChMJR0FOREkgU0FTMRkwFwYDVQQDExBHYW5kaSBQcm8g +U1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw5nFDd2ffWY4 +OxZxUVj2uQ49ms1N68h471Kq5j3R9OkVJYwObJqozTZvnlcmJ/QG5lZY9+RXDNyU +V1EKVL92l4vHkngDhhTQaoIB0sNeJMdnCzzjebnmN3VTbSTniQhYEZPg1554Zo+2 +U39kHBCPKZbwNk11EP4f7U7goyatkNJl0b28zEjbfGvJbPNE6vfaiBfM06spAHft +gJbCC2lzmv9L5R+KlixFFk3P8IkZInLnrGZ6iP0XIckVI8ENoMxu0SXb5JnfF8OS +QKdqBZKFBMbNJCCBQjXiv50hQEvVTX/INrqoMUfOVV1OT2HmuhPEBdoU0tU75mwm +VArKuQAdwwIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWW +nUvSw0UwHQYDVR0OBBYEFMGxMoDxE5IUL21nMJIYqnw5VRQ+MA4GA1UdDwEB/wQE +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQEC +AhowRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VU +Ti1VU0VSRmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEF +BQcwAoYxaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVy +X0NBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTAN +BgkqhkiG9w0BAQUFAAOCAQEAjSvVDlj6cT/RDFCrOvqpd1gZD7rzKzDGpfi3IciU +cjatYny806bAaAxRqL56e3O4rRMr+Jw1sHGpcqfKkm3YBW0CyJAum4vI07lYjZpn +9ihcWeatDX4gp/6Pm862lGITpB6TLriX1G7EYdnjOudIajawz64vnyTdvzmC18BV ++wC3A9f57mnqzm5SghMSeGlF78y9vPUXWPfBx9JY4Ga/r+U59djQrgbKY93sgyXD +3LS+K6NqGCKt58LcXQq75/e0OnHoJ3tiPMiB1IuYoIRCXevitc1ynVyP/m5wuZqB +wHHiX3Eo2RFMBCfSE7mSUoSwgHWtp1tHh0IvL8H7dmKjZQ== +-----END CERTIFICATE-----`) + +var goodCert = mustParse(goodstring) + +func mustParse(pemData string) *x509.Certificate { + block, _ := pem.Decode([]byte(pemData)) + if block == nil { + panic("Invalid PEM data.") + } else if block.Type != "CERTIFICATE" { + panic("Invalid PEM type.") + } + + cert, err := x509.ParseCertificate([]byte(block.Bytes)) + if err != nil { + panic(err.Error()) + } + return cert +} + +func TestRevoked(t *testing.T) { + if revoked, ok := VerifyCertificate(revokedCert); !ok { + fmt.Fprintf(os.Stderr, "Warning: soft fail checking revocation") + } else if !revoked { + t.Fatalf("revoked certificate should have been marked as revoked") + } +} + +func TestExpired(t *testing.T) { + if revoked, ok := VerifyCertificate(expiredCert); !ok { + fmt.Fprintf(os.Stderr, "Warning: soft fail checking revocation") + } else if !revoked { + t.Fatalf("expired certificate should have been marked as revoked") + } +} + +func TestGood(t *testing.T) { + if revoked, ok := VerifyCertificate(goodCert); !ok { + fmt.Fprintf(os.Stderr, "Warning: soft fail checking revocation") + } else if revoked { + t.Fatalf("good certificate should not have been marked as revoked") + } + +} + +func TestLdap(t *testing.T) { + ldapCert := mustParse(goodstring) + ldapCert.CRLDistributionPoints = append(ldapCert.CRLDistributionPoints, "ldap://myldap.example.com") + if revoked, ok := VerifyCertificate(ldapCert); revoked || !ok { + t.Fatalf("ldap certificate should have been recognized") + } +} + +func TestLdapURLErr(t *testing.T) { + if ldapURL(":") { + t.Fatalf("bad url does not cause error") + } +} + +func TestCertNotYetValid(t *testing.T) { + notReadyCert := expiredCert + notReadyCert.NotBefore = time.Date(3000, time.January, 1, 1, 1, 1, 1, time.Local) + notReadyCert.NotAfter = time.Date(3005, time.January, 1, 1, 1, 1, 1, time.Local) + if revoked, _ := VerifyCertificate(expiredCert); !revoked { + t.Fatalf("not yet verified certificate should have been marked as revoked") + } +} + +func TestCRLFetchError(t *testing.T) { + ldapCert := mustParse(goodstring) + ldapCert.CRLDistributionPoints[0] = "" + if revoked, ok := VerifyCertificate(ldapCert); ok || revoked { + t.Fatalf("Fetching error not encountered") + } + HardFail = true + if revoked, ok := VerifyCertificate(ldapCert); ok || !revoked { + t.Fatalf("Fetching error not encountered, hardfail not registered") + } + HardFail = false +} + +func TestBadCRLSet(t *testing.T) { + ldapCert := mustParse(goodstring) + ldapCert.CRLDistributionPoints[0] = "" + CRLSet[""] = nil + certIsRevokedCRL(ldapCert, "") + if _, ok := CRLSet[""]; ok { + t.Fatalf("key emptystring should be deleted from CRLSet") + } + delete(CRLSet, "") + +} + +func TestCachedCRLSet(t *testing.T) { + VerifyCertificate(goodCert) + if revoked, ok := VerifyCertificate(goodCert); !ok || revoked { + t.Fatalf("Previously fetched CRL's should be read smoothly and unrevoked") + } +} + +func TestRemoteFetchError(t *testing.T) { + + badurl := ":" + + if _, err := fetchRemote(badurl); err == nil { + t.Fatalf("fetching bad url should result in non-nil error") + } + +} + +func TestNoOCSPServers(t *testing.T) { + badIssuer := goodCert + badIssuer.IssuingCertificateURL = []string{" "} + certIsRevokedOCSP(badIssuer, true) + noOCSPCert := goodCert + noOCSPCert.OCSPServer = make([]string, 0) + if revoked, ok := certIsRevokedOCSP(noOCSPCert, true); revoked || !ok { + t.Fatalf("OCSP falsely registered as enabled for this certificate") + } +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/broad.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/broad.go new file mode 100644 index 00000000000..6f49e3022f3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/broad.go @@ -0,0 +1,84 @@ +package scan + +import ( + "crypto/x509" + "net" + "sync" + "time" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cf-tls/tls" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler" +) + +// Broad contains scanners for large swaths of TLS hosts on the internet. +var Broad = &Family{ + Description: "Large scale scans of TLS hosts", + Scanners: map[string]*Scanner{ + "IntermediateCAs": { + "Scans a CIDR IP range for unknown Intermediate CAs", + intermediateCAScan, + }, + }, +} + +func incrementBytes(bytes []byte) { + lsb := len(bytes) - 1 + bytes[lsb]++ + if bytes[lsb] == 0 { + incrementBytes(bytes[:lsb]) + } +} + +var ( + caBundleFile = "/etc/cfssl/ca-bundle.crt" + intBundleFile = "/etc/cfssl/int-bundle.crt" + numWorkers = 32 + timeout = time.Second +) + +// intermediateCAScan scans for new intermediate CAs not in the trust store. +func intermediateCAScan(host string) (grade Grade, output Output, err error) { + cidr, port, _ := net.SplitHostPort(host) + _, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + return Skipped, nil, nil + } + b, err := bundler.NewBundler(caBundleFile, intBundleFile) + if err != nil { + return + } + var wg sync.WaitGroup + wg.Add(numWorkers) + dialer := &net.Dialer{Timeout: timeout} + config := &tls.Config{InsecureSkipVerify: true} + addrs := make(chan string) + chains := make(chan []*x509.Certificate, numWorkers) + go func() { + for chain := range chains { + b.Bundle(chain, nil, bundler.Force) + } + }() + for i := 0; i < numWorkers; i++ { + go func() { + for addr := range addrs { + conn, err := tls.DialWithDialer(dialer, Network, addr, config) + if err != nil { + continue + } + conn.Close() + if conn.ConnectionState().HandshakeComplete { + chains <- conn.ConnectionState().PeerCertificates + } + } + wg.Done() + }() + } + for ip := ipnet.IP.To16(); ipnet.Contains(ip); incrementBytes(ip) { + addrs <- net.JoinHostPort(ip.String(), port) + } + close(addrs) + wg.Wait() + close(chains) + grade = Good + return +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/pki.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/pki.go index 77b81aa42af..b829f1bf083 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/pki.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/pki.go @@ -1,84 +1,160 @@ package scan import ( + "bytes" "crypto/x509" - "net" - "sync" + "fmt" "time" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cf-tls/tls" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/bundler" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/revoke" ) -// PKI contains scanners to test application layer HTTP(S) features +// PKI contains scanners for the Public Key Infrastructure. var PKI = &Family{ Description: "Scans for the Public Key Infrastructure", Scanners: map[string]*Scanner{ - "IntermediateCAs": { - "Scans a CIDR IP range for unknown Intermediate CAs", - intermediateCAScan, + "ChainExpiration": { + "Host's chain hasn't expired and won't expire in the next 30 days", + chainExpiration, + }, + "ChainValidation": { + "All certificates in host's chain are valid", + chainValidation, + }, + "MultipleCerts": { + "Host serves same certificate chain across all IPs", + multipleCerts, }, }, } -func incrementBytes(bytes []byte) { - lsb := len(bytes) - 1 - bytes[lsb]++ - if bytes[lsb] == 0 { - incrementBytes(bytes[:lsb]) +// getChain is a helper function that retreives the host's certificate chain. +func getChain(host string, config *tls.Config) (chain []*x509.Certificate, err error) { + var conn *tls.Conn + conn, err = tls.DialWithDialer(Dialer, Network, host, config) + if err != nil { + return + } + + err = conn.Close() + if err != nil { + return + } + + chain = conn.ConnectionState().PeerCertificates + if len(chain) == 0 { + err = fmt.Errorf("%s returned empty certificate chain", host) } + return } -var ( - caBundleFile = "/etc/cfssl/ca-bundle.crt" - intBundleFile = "/etc/cfssl/int-bundle.crt" - numWorkers = 32 - timeout = time.Second -) +type expiration time.Time + +func (e expiration) String() string { + return time.Time(e).Format("Jan 2 15:04:05 2006 MST") +} -// intermediateCAScan scans for new intermediate CAs not in the trust store. -func intermediateCAScan(host string) (grade Grade, output Output, err error) { - cidr, port, _ := net.SplitHostPort(host) - _, ipnet, err := net.ParseCIDR(cidr) +func chainExpiration(host string) (grade Grade, output Output, err error) { + chain, err := getChain(host, defaultTLSConfig(host)) if err != nil { - return Skipped, nil, nil + return + } + + e := helpers.ExpiryTime(chain) + if e == nil { + return + } + expirationTime := *e + output = expirationTime + + if time.Now().After(expirationTime) { + return } - b, err := bundler.NewBundler(caBundleFile, intBundleFile) + + // Warn if cert will expire in the next 30 days + if time.Now().Add(time.Hour * 24 * 30).After(expirationTime) { + grade = Warning + return + } + + grade = Good + return +} + +func chainValidation(host string) (grade Grade, output Output, err error) { + chain, err := getChain(host, defaultTLSConfig(host)) if err != nil { return } - var wg sync.WaitGroup - wg.Add(numWorkers) - dialer := &net.Dialer{Timeout: timeout} - config := &tls.Config{InsecureSkipVerify: true} - addrs := make(chan string) - chains := make(chan []*x509.Certificate, numWorkers) - go func() { - for chain := range chains { - b.Bundle(chain, nil, bundler.Force) + + var warnings []string + + for i := 0; i < len(chain)-1; i++ { + cert, parent := chain[i], chain[i+1] + + revoked, ok := revoke.VerifyCertificate(cert) + if !ok { + warnings = append(warnings, fmt.Sprintf("couldn't check if %s is revoked", cert.Subject.CommonName)) + } + if revoked { + err = fmt.Errorf("%s is revoked", cert.Subject.CommonName) + return + } + + if !parent.IsCA { + err = fmt.Errorf("%s is not a CA", parent.Subject.CommonName) + return + } + + if !bytes.Equal(cert.AuthorityKeyId, parent.SubjectKeyId) { + err = fmt.Errorf("%s AuthorityKeyId differs from %s SubjectKeyId", cert.Subject.CommonName, parent.Subject.CommonName) + return + } + + if err = cert.CheckSignatureFrom(parent); err != nil { + return + } + + switch cert.SignatureAlgorithm { + case x509.ECDSAWithSHA1: + warnings = append(warnings, fmt.Sprintf("%s is signed by ECDSAWithSHA1", cert.Subject.CommonName)) + case x509.SHA1WithRSA: + warnings = append(warnings, fmt.Sprintf("%s is signed by RSAWithSHA1", cert.Subject.CommonName)) } - }() - for i := 0; i < numWorkers; i++ { - go func() { - for addr := range addrs { - conn, err := tls.DialWithDialer(dialer, Network, addr, config) - if err != nil { - continue - } - conn.Close() - if conn.ConnectionState().HandshakeComplete { - chains <- conn.ConnectionState().PeerCertificates - } - } - wg.Done() - }() } - for ip := ipnet.IP.To16(); ipnet.Contains(ip); incrementBytes(ip) { - addrs <- net.JoinHostPort(ip.String(), port) + + if len(warnings) == 0 { + grade = Good + } else { + grade = Warning + output = warnings } - close(addrs) - wg.Wait() - close(chains) - grade = Good + return +} + +func multipleCerts(host string) (grade Grade, output Output, err error) { + config := defaultTLSConfig(host) + + firstChain, err := getChain(host, config) + if err != nil { + return + } + + grade, _, err = multiscan(host, func(addrport string) (g Grade, o Output, e error) { + g = Good + chain, e1 := getChain(addrport, config) + if e1 != nil { + return + } + + if !chain[0].Equal(firstChain[0]) { + e = fmt.Errorf("%s not equal to %s", chain[0].Subject.CommonName, firstChain[0].Subject.CommonName) + g = Bad + return + } + return + }) return } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common.go index 79c06198805..f36779c7d2b 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common.go @@ -1,7 +1,6 @@ package scan import ( - "fmt" "net" "regexp" "time" @@ -11,7 +10,6 @@ import ( ) var ( - // Network is the default network to use. Network = "tcp" // Dialer is the default dialer to use, with a 1s timeout. @@ -24,8 +22,8 @@ type Grade int const ( // Bad describes a host with serious misconfiguration or vulnerability. Bad Grade = iota - // Legacy describes a host with non-ideal configuration that maintains support for legacy clients. - Legacy + // Warning describes a host with non-ideal configuration that maintains support for Warning clients. + Warning // Good describes host performing the expected state-of-the-art. Good // Skipped descibes the "grade" of a scan that has been skipped. @@ -37,8 +35,8 @@ func (g Grade) String() string { switch g { case Bad: return "Bad" - case Legacy: - return "Legacy" + case Warning: + return "Warning" case Good: return "Good" case Skipped: @@ -49,8 +47,41 @@ func (g Grade) String() string { } // Output is the result of a scan, to be stored for potential use by later Scanners. -type Output interface { - fmt.Stringer +type Output interface{} + +type scanFunc func(string) (Grade, Output, error) + +// multiscan scans all DNS addresses returned for the host, returning the lowest grade +// and the concatenation of all the output. +func multiscan(host string, scan scanFunc) (grade Grade, output Output, err error) { + domain, port, _ := net.SplitHostPort(host) + var addrs []string + addrs, err = net.LookupHost(domain) + if err != nil { + return + } + + grade = Good + out := make(map[string]Output) + + for _, addr := range addrs { + var g Grade + var o Output + + g, o, err = scan(net.JoinHostPort(addr, port)) + if err != nil { + grade = Bad + return + } + + if g < grade { + grade = g + } + + out[addr] = o + } + output = out + return } // Scanner describes a type of scan to perform on a host. @@ -58,7 +89,7 @@ type Scanner struct { // Description describes the nature of the scan to be performed. Description string `json:"description"` // scan is the function that scans the given host and provides a Grade and Output. - scan func(host string) (Grade, Output, error) + scan scanFunc } // Scan performs the scan to be performed on the given host and stores its result. @@ -88,13 +119,14 @@ var Default = FamilySet{ "TLSHandshake": TLSHandshake, "TLSSession": TLSSession, "PKI": PKI, + "Broad": Broad, } // ScannerResult contains the result for a single scan. type ScannerResult struct { Grade string `json:"grade"` Output Output `json:"output,omitempty"` - Error error `json:"error,omitempty"` + Error string `json:"error,omitempty"` } // FamilyResult contains a scan response for a single Family @@ -126,11 +158,16 @@ func (fs FamilySet) RunScans(host, family, scanner string) (map[string]FamilyRes for scannerName, scanner := range family.Scanners { if scannerRegexp.MatchString(scannerName) { grade, output, err := scanner.Scan(host) - scannerResults[scannerName] = ScannerResult{ + + result := ScannerResult{ Grade: grade.String(), Output: output, - Error: err, } + if err != nil { + result.Error = err.Error() + } + + scannerResults[scannerName] = result } } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common_test.go index c57adfee28b..b916f6ca027 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/scan_common_test.go @@ -5,26 +5,20 @@ import ( "testing" ) -type OutputString string - -func (os OutputString) String() string { - return string(os) -} - var TestingScanner = &Scanner{ Description: "Tests common scan functions", scan: func(host string) (Grade, Output, error) { switch host { case "bad.example.com:443": - return Bad, OutputString("bad.com"), nil - case "legacy.example.com:443": - return Legacy, OutputString("legacy.com"), nil + return Bad, "bad.com", nil + case "Warning.example.com:443": + return Warning, "Warning.com", nil case "good.example.com:443": - return Good, OutputString("good.com"), nil + return Good, "good.com", nil case "skipped.example.com:443/0": - return Skipped, OutputString("skipped"), nil + return Skipped, "skipped", nil default: - return Grade(-1), OutputString("invalid"), fmt.Errorf("scan: invalid grade") + return Grade(-1), "invalid", fmt.Errorf("scan: invalid grade") } }, } @@ -46,22 +40,22 @@ func TestCommon(t *testing.T) { var err error grade, output, err = TestingScanner.Scan("bad.example.com:443") - if grade != Bad || output.String() != "bad.com" || err != nil { + if grade != Bad || output.(string) != "bad.com" || err != nil { t.FailNow() } - grade, output, err = TestingScanner.Scan("legacy.example.com:443") - if grade != Legacy || output.String() != "legacy.com" || err != nil { + grade, output, err = TestingScanner.Scan("Warning.example.com:443") + if grade != Warning || output.(string) != "Warning.com" || err != nil { t.FailNow() } grade, output, err = TestingScanner.Scan("good.example.com:443") - if grade != Good || output.String() != "good.com" || err != nil { + if grade != Good || output.(string) != "good.com" || err != nil { t.FailNow() } grade, output, err = TestingScanner.Scan("skipped.example.com:443/0") - if grade != Skipped || output.String() != "skipped" || err != nil { + if grade != Skipped || output.(string) != "skipped" || err != nil { t.FailNow() } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_handshake.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_handshake.go index ee50aab7703..c16f003decf 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_handshake.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_handshake.go @@ -99,6 +99,7 @@ func (cvList cipherVersionList) MarshalJSON() ([]byte, error) { func cipherSuiteScan(host string) (grade Grade, output Output, err error) { var cvList cipherVersionList allCiphers := allCiphersIDs() + var vers uint16 for vers = tls.VersionTLS12; vers >= tls.VersionSSL30; vers-- { ciphers := make([]uint16, len(allCiphers)) @@ -109,7 +110,7 @@ func cipherSuiteScan(host string) (grade Grade, output Output, err error) { break } if vers == tls.VersionSSL30 { - grade = Legacy + grade = Warning } cipherID := ciphers[cipherIndex] for i, c := range cvList { @@ -123,11 +124,16 @@ func cipherSuiteScan(host string) (grade Grade, output Output, err error) { ciphers = append(ciphers[:cipherIndex], ciphers[cipherIndex+1:]...) } } - if grade != Legacy && len(cvList) > 0 { - grade = Good - } else { + + if len(cvList) == 0 { err = errors.New("couldn't negotiate any cipher suites") + return } + + if grade != Warning { + grade = Good + } + output = cvList return } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_session.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_session.go index ebae8ac5e7c..185886ae866 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_session.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/scan/tls_session.go @@ -1,11 +1,6 @@ package scan -import ( - "errors" - "net" - - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cf-tls/tls" -) +import "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cf-tls/tls" // TLSSession contains tests of host TLS Session Resumption via // Session Tickets and Session IDs @@ -21,36 +16,29 @@ var TLSSession = &Family{ // SessionResumeScan tests that host is able to resume sessions across all addresses. func sessionResumeScan(host string) (grade Grade, output Output, err error) { - var hostname, port string - hostname, port, err = net.SplitHostPort(host) - if err != nil { - return - } - ips, err := net.LookupIP(hostname) - if err != nil { - return - } config := defaultTLSConfig(host) config.ClientSessionCache = tls.NewLRUClientSessionCache(1) - var conn *tls.Conn - conn, err = tls.DialWithDialer(Dialer, Network, host, config) + + conn, err := tls.DialWithDialer(Dialer, Network, host, config) if err != nil { return } - conn.Close() + if err = conn.Close(); err != nil { + return + } - for _, ip := range ips { - host = net.JoinHostPort(ip.String(), port) - conn, err = tls.Dial(Network, host, config) - if err != nil { + return multiscan(host, func(addrport string) (g Grade, o Output, e error) { + g = Good + conn, e1 := tls.DialWithDialer(Dialer, Network, addrport, config) + if e1 != nil { return } conn.Close() + + o = conn.ConnectionState().DidResume if !conn.ConnectionState().DidResume { - err = errors.New("did not resume") - return + grade = Bad } - } - grade = Good - return + return + }) } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/selfsign/selfsign.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/selfsign/selfsign.go index 5e876981911..2ca4d190ad0 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/selfsign/selfsign.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/selfsign/selfsign.go @@ -28,13 +28,13 @@ func parseCertificateRequest(priv crypto.Signer, csrBytes []byte) (template *x50 csr, err := x509.ParseCertificateRequest(csrBytes) if err != nil { - err = cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err) return } err = signer.CheckSignature(csr, csr.SignatureAlgorithm, csr.RawTBSCertificateRequest, csr.Signature) if err != nil { - err = cferr.Wrap(cferr.CertificateError, cferr.KeyMismatch, err) + err = cferr.Wrap(cferr.CSRError, cferr.KeyMismatch, err) return } @@ -61,7 +61,7 @@ func Sign(priv crypto.Signer, csrPEM []byte, profile *config.SigningProfile) ([] p, _ := pem.Decode(csrPEM) if p == nil || p.Type != "CERTIFICATE REQUEST" { - return nil, cferr.New(cferr.CertificateError, cferr.BadRequest) + return nil, cferr.New(cferr.CSRError, cferr.BadRequest) } template, err := parseCertificateRequest(priv, p.Bytes) @@ -108,7 +108,7 @@ func Sign(priv crypto.Signer, csrPEM []byte, profile *config.SigningProfile) ([] now := time.Now() serialNumber, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) if err != nil { - err = cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) + err = cferr.Wrap(cferr.CSRError, cferr.Unknown, err) return nil, err } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local/local.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local/local.go index 274efa1db85..9f569b5e959 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local/local.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local/local.go @@ -1,7 +1,8 @@ -// Package local implements certificate signature functionality for CF-SSL. +// Package local implements certificate signature functionality for CFSSL. package local import ( + "bytes" "crypto" "crypto/rand" "crypto/x509" @@ -14,6 +15,7 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer" ) @@ -168,9 +170,9 @@ func OverrideHosts(template *x509.Certificate, hosts []string) { // certificate or certificate request with the signing profile, // specified by profileName. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { - profile := s.policy.Profiles[req.Profile] - if profile == nil { - profile = s.policy.Default + profile, err := signer.Profile(s, req.Profile) + if err != nil { + return } serialSeq := "" @@ -180,11 +182,11 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { block, _ := pem.Decode([]byte(req.Request)) if block == nil { - return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed) + return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) } if block.Type != "CERTIFICATE REQUEST" { - return nil, cferr.Wrap(cferr.CertificateError, + return nil, cferr.Wrap(cferr.CSRError, cferr.BadRequest, errors.New("not a certificate or csr")) } @@ -226,6 +228,28 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { return s.sign(&safeTemplate, profile, serialSeq) } +// Info return a populated info.Resp struct or an error. +func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) { + cert, err := s.Certificate(req.Label, req.Profile) + if err != nil { + return + } + + profile, err := signer.Profile(s, req.Profile) + if err != nil { + return + } + + resp = new(info.Resp) + if cert.Raw != nil { + resp.Certificate = string(bytes.TrimSpace(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}))) + } + resp.Usage = profile.Usage + resp.ExpiryString = profile.ExpiryString + + return +} + // SigAlgo returns the RSA signer's signature algorithm. func (s *Signer) SigAlgo() x509.SignatureAlgorithm { return s.sigAlgo diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/pkcs11/pkcs11.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/pkcs11/pkcs11.go index 09f1b478c77..77bfdf85963 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/pkcs11/pkcs11.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/pkcs11/pkcs11.go @@ -5,8 +5,8 @@ package pkcs11 import ( "io/ioutil" - "github.com/cloudflare/cfssl/crypto/pkcs11key" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/crypto/pkcs11key" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote.go index 3e0002fd87e..b0cc20894aa 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote.go @@ -8,7 +8,7 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer" ) @@ -38,29 +38,39 @@ func NewSigner(policy *config.Signing) (*Signer, error) { // csr, and profileName are used as with a local signing operation, and // the label is used to select a signing root in a multi-root CA. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { - return s.remoteOp(req, req.Profile, "sign") + resp, err := s.remoteOp(req, req.Profile, "sign") + if err != nil { + return + } + if cert, ok := resp.([]byte); ok { + return cert, nil + } + return } -// Info sends an info request to the remote CFSSL server, receiving a signed -// certificate or an error in response. -func (s *Signer) Info(req client.InfoReq) (cert []byte, err error) { - return s.remoteOp(req, req.Profile, "info") +// Info sends an info request to the remote CFSSL server, receiving an +// Resp struct or an error in response. +func (s *Signer) Info(req info.Req) (resp *info.Resp, err error) { + respInterface, err := s.remoteOp(req, req.Profile, "info") + if err != nil { + return + } + if resp, ok := respInterface.(*info.Resp); ok { + return resp, nil + } + return } // Helper function to perform a remote sign or info request. -func (s *Signer) remoteOp(req interface{}, profile, target string) (cert []byte, err error) { +func (s *Signer) remoteOp(req interface{}, profile, target string) (resp interface{}, err error) { jsonData, err := json.Marshal(req) if err != nil { return nil, cferr.Wrap(cferr.APIClientError, cferr.JSONError, err) } - var p *config.SigningProfile - if s.policy.Profiles != nil && profile != "" { - p = s.policy.Profiles[profile] - } - - if p == nil { - p = s.policy.Default + p, err := signer.Profile(s, profile) + if err != nil { + return } server := client.NewServer(p.RemoteServer) @@ -69,19 +79,20 @@ func (s *Signer) remoteOp(req interface{}, profile, target string) (cert []byte, errors.New("failed to connect to remote")) } - // There's no server-side auth provider for the "info" method - // TODO: Revert this change once there is an AuthInfo provider. - if p.Provider != nil && target != "info" { - cert, err = server.AuthReq(jsonData, nil, p.Provider, target) + // There's no auth provider for the "info" method + if target == "info" { + resp, err = server.Info(jsonData) + } else if p.Provider != nil { + resp, err = server.AuthReq(jsonData, nil, p.Provider, target) } else { - cert, err = server.Req(jsonData, target) + resp, err = server.Req(jsonData, target) } if err != nil { return nil, err } - return []byte(cert), nil + return } // SigAlgo returns the RSA signer's signature algorithm. @@ -90,19 +101,6 @@ func (s *Signer) SigAlgo() x509.SignatureAlgorithm { return x509.UnknownSignatureAlgorithm } -// Certificate returns the signer's certificate. -func (s *Signer) Certificate(label, profile string) (*x509.Certificate, error) { - certStr, err := s.Info(client.InfoReq{Label: label, Profile: profile}) - if err != nil { - return nil, err - } - cert, err := helpers.ParseCertificatePEM(certStr) - if err != nil { - return nil, err - } - return cert, nil -} - // SetPolicy sets the signer's signature policy. func (s *Signer) SetPolicy(policy *config.Signing) { s.policy = policy diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote_test.go index 56bb3f7c747..f491e0e0816 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/remote/remote_test.go @@ -11,11 +11,11 @@ import ( "time" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/client" - "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info" + apiinfo "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/api/info" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/local" @@ -83,8 +83,8 @@ func TestRemoteInfo(t *testing.T) { // override with test server address, ignore url prefix "http://" remoteConfig.Signing.OverrideRemotes(remoteServer.URL[7:]) s := newRemoteSigner(t, remoteConfig.Signing) - req := client.InfoReq{} - certBytes, err := s.Info(req) + req := info.Req{} + resp, err := s.Info(req) if err != nil { t.Fatal("remote info failed:", err) } @@ -95,8 +95,8 @@ func TestRemoteInfo(t *testing.T) { t.Fatal("fail to read test CA cert:", err) } - if bytes.Compare(caBytes, certBytes) != 0 { - t.Fatal("Get a different CA cert through info api.", len(certBytes), len(caBytes)) + if bytes.Compare(caBytes, []byte(resp.Certificate)) != 0 { + t.Fatal("Get a different CA cert through info api.", len(resp.Certificate), len(caBytes)) } } @@ -305,7 +305,7 @@ func newHandler(t *testing.T, caFile, caKeyFile, op string) (http.Handler, error if op == "sign" { return NewSignHandlerFromSigner(s) } else if op == "info" { - return info.NewHandler(s) + return apiinfo.NewHandler(s) } t.Fatal("Bad op code") @@ -340,7 +340,7 @@ func NewSignHandlerFromSigner(s signer.Signer) (h http.Handler, err error) { Handler: &SignHandler{ signer: s, }, - Method: "POST", + Methods: []string{"POST"}, }, nil } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/signer.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/signer.go index a7ea4a41941..db3dde9f912 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/signer.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/signer.go @@ -1,4 +1,4 @@ -// Package signer implements certificate signature functionality for CF-SSL. +// Package signer implements certificate signature functionality for CFSSL. package signer import ( @@ -21,6 +21,7 @@ import ( "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/csr" cferr "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/errors" + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/info" ) // MaxPathLen is the default path length for a new CA certificate. @@ -87,13 +88,31 @@ func SplitHosts(hostList string) []string { // A Signer contains a CA's certificate and private key for signing // certificates, a Signing policy to refer to and a SignatureAlgorithm. type Signer interface { - Certificate(label, profile string) (*x509.Certificate, error) + Info(info.Req) (*info.Resp, error) Policy() *config.Signing SetPolicy(*config.Signing) SigAlgo() x509.SignatureAlgorithm Sign(req SignRequest) (cert []byte, err error) } +// Profile gets the specific profile from the signer +func Profile(s Signer, profile string) (*config.SigningProfile, error) { + var p *config.SigningProfile + policy := s.Policy() + if policy != nil && policy.Profiles != nil && profile != "" { + p = policy.Profiles[profile] + } + + if p == nil && policy != nil { + p = policy.Default + } + + if p == nil { + return nil, cferr.Wrap(cferr.APIClientError, cferr.ClientHTTPError, errors.New("profile must not be nil")) + } + return p, nil +} + // DefaultSigAlgo returns an appropriate X.509 signature algorithm given // the CA's private key. func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm { @@ -132,13 +151,13 @@ func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm { func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certificate, err error) { csr, err := x509.ParseCertificateRequest(csrBytes) if err != nil { - err = cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) + err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err) return } err = CheckSignature(csr, csr.SignatureAlgorithm, csr.RawTBSCertificateRequest, csr.Signature) if err != nil { - err = cferr.Wrap(cferr.CertificateError, cferr.KeyMismatch, err) + err = cferr.Wrap(cferr.CSRError, cferr.KeyMismatch, err) return } diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/universal/universal_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/universal/universal_test.go index 897888bc4ef..075bd6d014e 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/universal/universal_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/signer/universal/universal_test.go @@ -1 +1,42 @@ package universal + +import ( + "testing" + "time" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/config" +) + +var expiry = 1 * time.Minute +var validLocalConfig = &config.Config{ + Signing: &config.Signing{ + Profiles: map[string]*config.SigningProfile{ + "valid": { + Usage: []string{"digital signature"}, + Expiry: expiry, + }, + }, + Default: &config.SigningProfile{ + Usage: []string{"digital signature"}, + Expiry: expiry, + }, + }, +} + +func TestNewSigner(t *testing.T) { + h := map[string]string{ + "key-file": "../local/testdata/ca_key.pem", + "cert-file": "../local/testdata/ca.pem", + } + + r := &Root{ + Config: h, + ForceRemote: false, + } + + _, err := NewSigner(*r, validLocalConfig.Signing) + if err != nil { + t.Fatal(err) + } + +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/filter.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/filter.go index 28f01bf9db0..94060455fd3 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/filter.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/filter.go @@ -1,4 +1,4 @@ -// Package ubiquity contains the ubiquity scoring logic for CF-SSL bundling. +// Package ubiquity contains the ubiquity scoring logic for CFSSL bundling. package ubiquity // Ubiquity is addressed as selecting the chains that are most likely being accepted for different client systems. diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/sha1.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/sha1.go new file mode 100644 index 00000000000..978094ba273 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/sha1.go @@ -0,0 +1,153 @@ +package ubiquity + +import ( + "crypto/x509" + "fmt" + "time" + + "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" +) + +// DeprecationSeverity encodes the severity of a deprecation policy +type DeprecationSeverity int + +const ( + // None indicates there is no deprecation + None DeprecationSeverity = iota + // Low indicates the deprecation policy won't affect user experience + Low + // Medium indicates the deprecation policy will affect user experience + // either in a minor way or for a limited scope of users. + Medium + // High indicates the deprecation policy will strongly affect user experience + High +) + +// SHA1DeprecationPolicy encodes how a platform deprecates the support of SHA1 +type SHA1DeprecationPolicy struct { + // the name of platform + Platform string `json:"platform"` + // policy severity, policies of the same platform will only trigger the one of highest severity + Severity DeprecationSeverity `json:"severity"` + // a human readable message describing the deprecation effects + Description string `json:"description"` + // the date when the policy is effective. zero value means effective immediately + EffectiveDate time.Time `json:"effective_date"` + // the expiry deadline indicates the latest date which a end-entity + // certificate with SHA1 can be valid through. + ExpiryDeadline time.Time `json:"expiry_deadline"` + // the date beyond which SHA1 cert should not be issued. + NeverIssueAfter time.Time `json:"never_issue_after"` +} + +// SHA1DeprecationPolicys ia a list of various SHA1DeprecationPolicy's +// proposed by major browser producers +var SHA1DeprecationPolicys = []SHA1DeprecationPolicy{ + // Chrome: + // if the leaf certificate expires between 01-01-2016 and 01-01-2017 + // and the chain (excluding root) contains SHA-1 cert, show "minor errors". + SHA1DeprecationPolicy{ + Platform: "Google Chrome", + Description: "shows the SSL connection has minor problems", + Severity: Medium, + ExpiryDeadline: time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + // Chrome: + // if the leaf certificate expires after Jan. 1st 2017 + // and the chain (excluding root) contains SHA-1 cert, show "untrusted SSL". + SHA1DeprecationPolicy{ + Platform: "Google Chrome", + Description: "shows the SSL connection is untrusted", + Severity: High, + ExpiryDeadline: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + // Mozilla Firefox: + // if the leaf certificate expires after Jan. 1st 2017, and + // the chain (excluding root) contains SHA-1 cert, show a warning in the developer console. + SHA1DeprecationPolicy{ + Platform: "Mozilla Firefox", + Description: "gives warning in the developer console", + Severity: Low, + ExpiryDeadline: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + // Mozilla Firefox: + // if a new certificate is issued after Jan. 1st 2016, and + // it is a SHA-1 cert, reject it. + SHA1DeprecationPolicy{ + Platform: "Mozilla Firefox", + Description: "shows the SSL connection is untrusted", + Severity: Medium, + EffectiveDate: time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC), + NeverIssueAfter: time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + // Mozilla Firefox: + // deprecate all valid SHA-1 cert chain on Jan. 1st 2017 + SHA1DeprecationPolicy{ + Platform: "Mozilla Firefox", + Description: "shows the SSL connection is untrusted", + Severity: High, + EffectiveDate: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + ExpiryDeadline: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + }, + // Microsoft Windows: + // deprecate all valid SHA-1 cert chain on Jan. 1st 2017 + SHA1DeprecationPolicy{ + Platform: "Microsoft Windows Vista and later", + Description: "shows the SSL connection is untrusted", + Severity: High, + EffectiveDate: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + ExpiryDeadline: time.Date(2017, time.January, 1, 0, 0, 0, 0, time.UTC), + }, +} + +// Flag returns whether the policy flags the cert chain as deprecated for matching its deprecation criteria +func (p SHA1DeprecationPolicy) Flag(chain []*x509.Certificate) bool { + leaf := chain[0] + if time.Now().After(p.EffectiveDate) { + + // Reject newly issued leaf certificate with SHA-1 after the specified deadline. + if !p.NeverIssueAfter.IsZero() && leaf.NotBefore.After(p.NeverIssueAfter) { + // Check hash algorithm of non-root leaf cert. + if len(chain) > 1 && helpers.HashAlgoString(leaf.SignatureAlgorithm) == "SHA1" { + return true + } + } + + // Reject certificate chain with SHA-1 that are still valid after expiry deadline. + if !p.ExpiryDeadline.IsZero() && leaf.NotAfter.After(p.ExpiryDeadline) { + // Check hash algorithm of non-root certs. + for i, cert := range chain { + if i < len(chain)-1 { + if helpers.HashAlgoString(cert.SignatureAlgorithm) == "SHA1" { + return true + } + } + } + } + } + + return false +} + +// SHA1DeprecationMessages returns a list of human-readable messages. Each message describes +// how one platform rejects the chain based on SHA1 deprecation policies. +func SHA1DeprecationMessages(chain []*x509.Certificate) []string { + // record the most severe deprecation policy by each platform + selectedPolicies := map[string]SHA1DeprecationPolicy{} + for _, policy := range SHA1DeprecationPolicys { + if policy.Flag(chain) { + // only keep the policy with highest severity + if selectedPolicies[policy.Platform].Severity < policy.Severity { + selectedPolicies[policy.Platform] = policy + } + } + } + // build the message list + list := []string{} + for _, policy := range selectedPolicies { + if policy.Severity > None { + list = append(list, fmt.Sprintf("%s %s due to SHA-1 deprecation", policy.Platform, policy.Description)) + } + } + return list +} diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/testdata/ca.pem.metadata b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/testdata/ca.pem.metadata new file mode 100644 index 00000000000..fcec6a33d87 --- /dev/null +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/testdata/ca.pem.metadata @@ -0,0 +1,15 @@ +[ +{ + "name":"Browser Everywhere", + "weight": 0, + "hash_algo": "SHA2", + "key_algo": "ECDSA256" +}, +{ + "name":"Pineapple", + "weight": 1, + "hash_algo": "SHA2", + "key_algo": "ECDSA521", + "keystore": "pineapple.pem" +} +] diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_platform.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_platform.go index 850802fc240..08a9e6ea180 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_platform.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_platform.go @@ -12,7 +12,6 @@ import ( "io/ioutil" "path" "path/filepath" - "time" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/helpers" "github.com/letsencrypt/boulder/Godeps/_workspace/src/github.com/cloudflare/cfssl/log" @@ -36,57 +35,18 @@ func (s CertSet) Add(cert *x509.Certificate) { s[SHA1RawPublicKey(cert)] = true } -// CryptoDeprecationPolicy encodes how a platform plans to deprecate the support of a crypto hash/key algorithm. -type CryptoDeprecationPolicy struct { - // The name of target algorithm to be deprecated. - Target string `json:"target"` - // The date when the policy is effective. - EffectiveDate time.Time `json:"effective_date"` - // The expiry deadline indicates the latest date which a end-entity certificate with the deprecating - // algorithm can be valid through. - ExpiryDeadline time.Time `json:"expiry_deadline"` -} - // A Platform contains ubiquity information on supported crypto algorithms and root certificate store name. type Platform struct { - Name string `json:"name"` - Weight int `json:"weight"` - HashAlgo string `json:"hash_algo"` - KeyAlgo string `json:"key_algo"` - KeyStoreFile string `json:"keystore"` - HashDeprecation *CryptoDeprecationPolicy `json:"hash_algo_expiry"` + Name string `json:"name"` + Weight int `json:"weight"` + HashAlgo string `json:"hash_algo"` + KeyAlgo string `json:"key_algo"` + KeyStoreFile string `json:"keystore"` KeyStore CertSet HashUbiquity HashUbiquity KeyAlgoUbiquity KeyAlgoUbiquity } -// Deprecate returns whether the platform rejects the cert chain due to ceased support of a crypto hash algorithm. -func (p Platform) Deprecate(chain []*x509.Certificate) bool { - if p.HashDeprecation == nil { - return false - } - now := time.Now() - leaf := chain[0] - - // Currently we implement the logic that Chrome browsers use to stop supporting SHA-1. To our understanding, - // Microsoft and Mozilla use basically the same logic to cease support of SHA-1 as well. - - if now.After(p.HashDeprecation.EffectiveDate) { - if leaf.NotAfter.After(p.HashDeprecation.ExpiryDeadline) { - // Check hash algorithm of non-root cert. - for i, cert := range chain { - if i < len(chain)-1 { - if helpers.HashAlgoString(cert.SignatureAlgorithm) == p.HashDeprecation.Target { - return true - } - } - } - } - } - - return false -} - // Trust returns whether the platform has the root cert in the trusted store. func (p Platform) Trust(root *x509.Certificate) bool { // the key store is empty iff the platform doesn't carry a root store and trust whatever root store @@ -216,17 +176,6 @@ func UntrustedPlatforms(root *x509.Certificate) []string { return ret } -// DeprecatedSHA1Platforms returns a list of platforms which rejects the cert chain based on deprecation of SHA1. -func DeprecatedSHA1Platforms(chain []*x509.Certificate) []string { - ret := []string{} - for _, platform := range Platforms { - if platform.Deprecate(chain) && platform.HashDeprecation.Target == "SHA1" { - ret = append(ret, platform.Name) - } - } - return ret -} - // CrossPlatformUbiquity returns a ubiquity score (persumably relecting the market share in percentage) // based on whether the given chain can be verified with the different platforms' root certificate stores. func CrossPlatformUbiquity(chain []*x509.Certificate) int { @@ -241,7 +190,7 @@ func CrossPlatformUbiquity(chain []*x509.Certificate) int { // 2. the chain satisfy the minimal constraints on hash function and key algorithm. root := chain[len(chain)-1] for _, platform := range Platforms { - if platform.Trust(root) && !platform.Deprecate(chain) { + if platform.Trust(root) { switch { case platform.HashUbiquity <= ChainHashUbiquity(chain) && platform.KeyAlgoUbiquity <= ChainKeyAlgoUbiquity(chain): totalWeight += platform.Weight diff --git a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_test.go b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_test.go index d8d6770e879..1cd73f85c18 100644 --- a/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_test.go +++ b/Godeps/_workspace/src/github.com/cloudflare/cfssl/ubiquity/ubiquity_test.go @@ -2,6 +2,7 @@ package ubiquity import ( "crypto/x509" + "fmt" "io/ioutil" "testing" "time" @@ -10,13 +11,14 @@ import ( ) const ( - rsa1024 = "testdata/rsa1024sha1.pem" - rsa2048 = "testdata/rsa2048sha2.pem" - rsa3072 = "testdata/rsa3072sha2.pem" - rsa4096 = "testdata/rsa4096sha2.pem" - ecdsa256 = "testdata/ecdsa256sha2.pem" - ecdsa384 = "testdata/ecdsa384sha2.pem" - ecdsa521 = "testdata/ecdsa521sha2.pem" + rsa1024 = "testdata/rsa1024sha1.pem" + rsa2048 = "testdata/rsa2048sha2.pem" + rsa3072 = "testdata/rsa3072sha2.pem" + rsa4096 = "testdata/rsa4096sha2.pem" + ecdsa256 = "testdata/ecdsa256sha2.pem" + ecdsa384 = "testdata/ecdsa384sha2.pem" + ecdsa521 = "testdata/ecdsa521sha2.pem" + caMetadata = "testdata/ca.pem.metadata" ) var rsa1024Cert, rsa2048Cert, rsa3072Cert, rsa4096Cert, ecdsa256Cert, ecdsa384Cert, ecdsa521Cert *x509.Certificate @@ -26,6 +28,7 @@ func readCert(filename string) *x509.Certificate { cert, _ := helpers.ParseCertificatePEM(bytes) return cert } + func init() { rsa1024Cert = readCert(rsa1024) rsa2048Cert = readCert(rsa2048) @@ -176,6 +179,55 @@ func TestChainKeyAlgoUbiquity(t *testing.T) { } +func TestChainExpiryUbiquity(t *testing.T) { + // rsa1024Cert expires at year 2024 + // rsa2048Cert expires at year 2019 + // ecdsa256Cert expires at year 2019 + chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert} + chain2 := []*x509.Certificate{ecdsa256Cert, rsa1024Cert} + if CompareExpiryUbiquity(chain1, chain2) >= 0 { + t.Fatal("Incorrect chain expiry ubiquity") + } + + if CompareExpiryUbiquity(chain2, chain1) <= 0 { + t.Fatal("Incorrect chain expiry ubiquity") + } + + if CompareExpiryUbiquity(chain1, chain1) != 0 { + t.Fatal("Incorrect chain expiry ubiquity") + } +} + +func TestCompareChainExpiry(t *testing.T) { + // rsa1024Cert expires at 2024 + // rsa2048Cert expires at 2019 + // ecdsa256Cert expires at 2019 + // both chain expires at year 2019. + chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert} + chain2 := []*x509.Certificate{ecdsa256Cert, rsa1024Cert} + if CompareChainExpiry(chain1, chain2) != 0 { + t.Fatal("Incorrect chain expiry") + } + + if CompareExpiryUbiquity(chain1, chain1) != 0 { + t.Fatal("Incorrect chain expiry") + } +} + +func TestCompareChainLength(t *testing.T) { + chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert} + chain2 := []*x509.Certificate{rsa1024Cert} + chain3 := []*x509.Certificate{rsa2048Cert} + // longer chain is ranked lower + if CompareChainLength(chain1, chain2) >= 0 { + t.Fatal("Incorrect chain length comparison") + } + + if CompareChainLength(chain2, chain3) != 0 { + t.Fatal("Incorrect chain length comparison") + } +} + func TestPlatformKeyStoreUbiquity(t *testing.T) { cert1 := rsa1024Cert cert2 := rsa2048Cert @@ -184,14 +236,17 @@ func TestPlatformKeyStoreUbiquity(t *testing.T) { // "Macrosoft" has all three certs. // "Godzilla" has two certs, cert1 and cert2. // "Pinapple" has cert1. + // "Colorful" has no key store data, default to trust any cert // All platforms support the same crypto suite. platformA := Platform{Name: "MacroSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/macrosoft.pem"} platformB := Platform{Name: "Godzilla", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/godzilla.pem"} platformC := Platform{Name: "Pineapple", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/pineapple.pem"} + platformD := Platform{Name: "Colorful", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: ""} platformA.ParseAndLoad() platformB.ParseAndLoad() platformC.ParseAndLoad() - Platforms = []Platform{platformA, platformB, platformC} + platformD.ParseAndLoad() + Platforms = []Platform{platformA, platformB, platformC, platformD} // chain1 with root cert1 (RSA1024, SHA1), has the largest platform coverage. // chain2 with root cert2 (RSA2048, SHA2), has the second largest coverage. // chain3 with root cert3 (ECDSA256, SHA2), has the least coverage. @@ -204,6 +259,50 @@ func TestPlatformKeyStoreUbiquity(t *testing.T) { if CrossPlatformUbiquity(chain2) < CrossPlatformUbiquity(chain3) { t.Fatal("Incorrect cross platform ubiquity") } + + if ComparePlatformUbiquity(chain1, chain2) < 0 { + t.Fatal("Incorrect cross platform ubiquity") + } + + if ComparePlatformUbiquity(chain2, chain3) < 0 { + t.Fatal("Incorrect cross platform ubiquity") + } + + // test UntrustedPlatforms() + u1 := UntrustedPlatforms(cert1) + if len(u1) != 0 { + t.Fatal("Incorrect UntrustedPlatforms") + } + u2 := UntrustedPlatforms(cert2) + if len(u2) != 1 { + t.Fatal("Incorrect UntrustedPlatforms") + } + u3 := UntrustedPlatforms(cert3) + if len(u3) != 2 { + t.Fatal("Incorrect UntrustedPlatforms") + } + +} + +func TestEmptyPlatformList(t *testing.T) { + Platforms = []Platform{} + cert := rsa1024Cert + chain := []*x509.Certificate{cert} + if CrossPlatformUbiquity(chain) != 0 { + t.Fatal("Incorrect cross platform ubiquity when Platforms is empty") + } + // test UntrustedPlatforms() + u1 := UntrustedPlatforms(cert) + if len(u1) != 0 { + t.Fatal("Incorrect UntrustedPlatforms when Platforms is empty") + } +} + +func TestLoadPlatforms(t *testing.T) { + err := LoadPlatforms(caMetadata) + if err != nil { + t.Fatal(err) + } } func TestPlatformCryptoUbiquity(t *testing.T) { @@ -215,9 +314,11 @@ func TestPlatformCryptoUbiquity(t *testing.T) { platformA := Platform{Name: "TinySoft", Weight: 100, HashAlgo: "SHA1", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem"} platformB := Platform{Name: "SmallSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem"} platformC := Platform{Name: "LargeSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/macrosoft.pem"} + platformD := Platform{Name: "MediumSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA384", KeyStoreFile: "testdata/macrosoft.pem"} platformA.ParseAndLoad() platformB.ParseAndLoad() platformC.ParseAndLoad() + platformD.ParseAndLoad() Platforms = []Platform{platformA, platformB, platformC} // chain1 with root cert1 (RSA1024, SHA1), has the largest platform coverage. // chain2 with root cert2 (RSA2048, SHA2), has the second largest coverage. @@ -231,49 +332,13 @@ func TestPlatformCryptoUbiquity(t *testing.T) { if CrossPlatformUbiquity(chain2) < CrossPlatformUbiquity(chain3) { t.Fatal("Incorrect cross platform ubiquity") } -} -func TestPlatformCryptoDeprecation(t *testing.T) { - cert1 := rsa1024Cert - cert2 := rsa2048Cert - pweight1 := 1 - pweight2 := 10 - pweight3 := 100 - Jan1st2014 := time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC) - Jan1st2100 := time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC) - DeprecationPolicy2014 := &CryptoDeprecationPolicy{Target: "SHA1", EffectiveDate: Jan1st2014, ExpiryDeadline: Jan1st2014} - DeprecationPolicy2100 := &CryptoDeprecationPolicy{Target: "SHA2", EffectiveDate: Jan1st2100, ExpiryDeadline: Jan1st2014} - // All platforms have the same trust store but are with various crypto suite and deprecation policy. - // platformA supports SHA1 only and has no deprecation plan of SHA1. - // platformB supports SHA1/SHA2 and will deprecate SHA1 at year 2100. - // platformC supports SHA1/SHA2 and will deprecate SHA1 at year 2014. - platformA := Platform{Name: "TinySoft", Weight: pweight1, HashAlgo: "SHA1", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem"} - platformB := Platform{Name: "SmallSoft", Weight: pweight2, HashAlgo: "SHA2", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem", HashDeprecation: DeprecationPolicy2100} - platformC := Platform{Name: "LargeSoft", Weight: pweight3, HashAlgo: "SHA2", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem", HashDeprecation: DeprecationPolicy2014} - platformA.ParseAndLoad() - platformB.ParseAndLoad() - platformC.ParseAndLoad() - Platforms = []Platform{platformA, platformB, platformC} - // chain1 is accepted by platform A, B and C. It's not rejected by platFormC because root cert is not subject to SHA1 deprecation. - chain1 := []*x509.Certificate{cert1} - // chain2 is accepted by platform A, B. It's rejected by platFormC because leaf cert is subject to SHA1 deprecation. - chain2 := []*x509.Certificate{cert1, cert1} - // chain3 is accepted by platformB and platFormC. It's rejected by platformA due to A's inablity to support SHA2. - chain3 := []*x509.Certificate{cert2, cert1} - - if CrossPlatformUbiquity(chain1) != pweight1+pweight2+pweight3 { - t.Fatal("Incorrect cross platform ubiquity: ", CrossPlatformUbiquity(chain1)) - } - if CrossPlatformUbiquity(chain2) != pweight1+pweight2 { - t.Fatal("Incorrect cross platform ubiquity: ", CrossPlatformUbiquity(chain2)) - } - if CrossPlatformUbiquity(chain3) != pweight2+pweight3 { - t.Fatal("Incorrect cross platform ubiquity: ", CrossPlatformUbiquity(chain3)) + if ComparePlatformUbiquity(chain1, chain2) < 0 { + t.Fatal("Incorrect cross platform ubiquity") } - dplatforms := DeprecatedSHA1Platforms(chain2) - if len(dplatforms) != 1 || dplatforms[0] != "LargeSoft" { - t.Fatal("Incorrect deprecation checking: ", dplatforms) + if ComparePlatformUbiquity(chain1, chain2) < 0 { + t.Fatal("Incorrect cross platform ubiquity") } } @@ -327,6 +392,23 @@ func TestCompareSHA2Homogeneity(t *testing.T) { } } +func TestFilterTrivial(t *testing.T) { + var chain []*x509.Certificate + var chains [][]*x509.Certificate + ret := Filter(chains, CompareChainHashPriority) + if len(ret) != 0 { + t.Fatal("Incorrect filtering") + } + + chain = []*x509.Certificate{rsa2048Cert} + chains = [][]*x509.Certificate{chain} + + ret = Filter(chains, CompareChainHashPriority) + if len(ret) != 1 { + t.Fatal("Incorrect filtering") + } +} + func TestFilterChainHashPriority(t *testing.T) { var chain1, chain2 []*x509.Certificate chain1 = []*x509.Certificate{rsa2048Cert} // SHA256 @@ -342,6 +424,7 @@ func TestFilterChainHashPriority(t *testing.T) { if ret[0][0] != ecdsa384Cert { t.Fatal("Incorrect chain hash priority filtering") } + } func TestFilterChainKeyAlgoPriority(t *testing.T) { @@ -411,3 +494,155 @@ func TestFilterChainKeyAlgoUbiquity(t *testing.T) { t.Fatal("Incorrect chain key algo priority filtering") } } + +func TestFlagBySHA1DeprecationPolicy(t *testing.T) { + cert1 := rsa1024Cert + cert2 := rsa2048Cert + Jan1st2014 := time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC) + Jan1st2100 := time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC) + policy1 := SHA1DeprecationPolicy{ + Description: "SHA1 should be gone years ago", + ExpiryDeadline: Jan1st2014, + } + policy2 := SHA1DeprecationPolicy{ + Description: "SHA1 is perfect for another century", + ExpiryDeadline: Jan1st2100, + } + policy3 := SHA1DeprecationPolicy{ + Description: "effectively one century later, reject SHA1 expires on 2014", + EffectiveDate: Jan1st2100, + ExpiryDeadline: Jan1st2014, + } + policy4 := SHA1DeprecationPolicy{ + Description: "no more new SHA1 cert", + NeverIssueAfter: Jan1st2014, + } + // chain1 is accepted univerally. It's not flagged because root cert is not subject to SHA1 deprecation. + chain1 := []*x509.Certificate{cert1} + if policy1.Flag(chain1) || policy2.Flag(chain1) || policy3.Flag(chain1) || policy4.Flag(chain1) { + t.Fatal("Incorrect SHA1 deprecation") + } + + // chain2 is accepted by policy2 and policy3. It's flagged by policy1 and policy4 + chain2 := []*x509.Certificate{cert1, cert1} + if !policy1.Flag(chain2) || policy2.Flag(chain2) || policy3.Flag(chain2) || !policy4.Flag(chain2) { + t.Fatal("Incorrect SHA1 deprecation") + } + + // chain3 is accepted by universally since the leaf cert and the intermediate are signed by SHA-256 + chain3 := []*x509.Certificate{cert2, cert2, cert1} + if policy1.Flag(chain3) || policy2.Flag(chain3) || policy3.Flag(chain3) || policy4.Flag(chain3) { + t.Fatal("Incorrect SHA1 deprecation") + } +} + +func TestSHA1DeprecationMessages(t *testing.T) { + cert1 := rsa1024Cert + cert2 := rsa2048Cert + chain1 := []*x509.Certificate{cert1} + chain2 := []*x509.Certificate{cert1, cert1} + chain3 := []*x509.Certificate{cert2, cert1, cert1} + chain4 := []*x509.Certificate{cert2, cert2, cert1} + messages := []string{} + + Jan1st2014 := time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC) + Jan1st2100 := time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC) + policy1 := SHA1DeprecationPolicy{ + Platform: "Browser A", + Description: "minor warning", + Severity: Low, + ExpiryDeadline: Jan1st2014, + } + policy2 := SHA1DeprecationPolicy{ + Platform: "Browser A", + Description: "minor warning", + Severity: Medium, + ExpiryDeadline: Jan1st2014, + } + policy3 := SHA1DeprecationPolicy{ + Platform: "Browser B", + Description: "reject", + Severity: High, + NeverIssueAfter: Jan1st2014, + } + policy4 := SHA1DeprecationPolicy{ + Platform: "Browser C", + Description: "reject but not now", + Severity: High, + NeverIssueAfter: Jan1st2014, + EffectiveDate: Jan1st2100, + } + + // The only policy has severity low + SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1} + messages = SHA1DeprecationMessages(chain1) + // chain1 with only root is not subject to deprecation + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain2 has SHA-1 leaf cert, subject to deprecation + messages = SHA1DeprecationMessages(chain2) + if len(messages) != 1 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain3 has SHA-1 intermediate cert, subject to deprecation + messages = SHA1DeprecationMessages(chain3) + if len(messages) != 1 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain4 has no SHA-1 leaf or intermediate, not subject to deprecation + messages = SHA1DeprecationMessages(chain4) + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + + // A second policy that has higher severity , so it should takes effect and override lower one. + SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1, policy2} + // chain1 only has root cert, not subject to deprecation policy + messages = SHA1DeprecationMessages(chain1) + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain2 has a SHA-1 leaf cert, will have a message from policy2 + messages = SHA1DeprecationMessages(chain2) + if len(messages) != 1 || + messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain3 has a SHA-1 intermediate cert, will have a message from policy2 + messages = SHA1DeprecationMessages(chain3) + if len(messages) != 1 || + messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain4 is not subject to any deprecation policy + messages = SHA1DeprecationMessages(chain4) + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + + // Add two policies. One tests for newly issued leaf certificate after a deadline, the other is the same, + // but takes effect at the 22nd century. + SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1, policy2, policy3, policy4} + // chain1 only has root cert, not subject to any deprecation policy + messages = SHA1DeprecationMessages(chain1) + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain2 now is flagged by two policies: policy2 and policy3 + messages = SHA1DeprecationMessages(chain2) + if len(messages) != 2 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain3 is not flagged by policy3 but policy2 + messages = SHA1DeprecationMessages(chain3) + if len(messages) != 1 || + messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) { + t.Fatal("Incorrect SHA1 deprecation reporting") + } + // chain4 is not subject to any deprecation policy + messages = SHA1DeprecationMessages(chain4) + if len(messages) != 0 { + t.Fatal("Incorrect SHA1 deprecation reporting") + } +} diff --git a/Godeps/_workspace/src/github.com/dgryski/go-rc2/LICENSE b/Godeps/_workspace/src/github.com/dgryski/go-rc2/LICENSE new file mode 100644 index 00000000000..160d24da6b1 --- /dev/null +++ b/Godeps/_workspace/src/github.com/dgryski/go-rc2/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Damian Gryski + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/dgryski/go-rc2/bench_test.go b/Godeps/_workspace/src/github.com/dgryski/go-rc2/bench_test.go new file mode 100644 index 00000000000..639b4cb9c9c --- /dev/null +++ b/Godeps/_workspace/src/github.com/dgryski/go-rc2/bench_test.go @@ -0,0 +1,40 @@ +package rc2 + +import ( + "testing" + + ebfe "github.com/ebfe/rc2" +) + +func BenchmarkEncrypt(b *testing.B) { + r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Encrypt(src[:], src[:]) + } +} +func BenchmarkEbfeEncrypt(b *testing.B) { + r, _ := ebfe.NewCipher([]byte{0, 0, 0, 0, 0, 0, 0, 0}) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Encrypt(src[:], src[:]) + } +} +func BenchmarkDecrypt(b *testing.B) { + r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Decrypt(src[:], src[:]) + } +} +func BenchmarkEbfeDecrypt(b *testing.B) { + r, _ := ebfe.NewCipher([]byte{0, 0, 0, 0, 0, 0, 0, 0}) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Decrypt(src[:], src[:]) + } +} diff --git a/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2.go b/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2.go new file mode 100644 index 00000000000..d33a4988871 --- /dev/null +++ b/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2.go @@ -0,0 +1,270 @@ +// Package rc2 implements the RC2 cipher +/* +https://www.ietf.org/rfc/rfc2268.txt +http://people.csail.mit.edu/rivest/pubs/KRRR98.pdf + +This code is licensed under the MIT license. +*/ +package rc2 + +import ( + "crypto/cipher" + "encoding/binary" +) + +// The rc2 block size in bytes +const BlockSize = 8 + +type rc2Cipher struct { + k [64]uint16 +} + +// New returns a new rc2 cipher with the given key and effective key length t1 +func New(key []byte, t1 int) (cipher.Block, error) { + // TODO(dgryski): error checking for key length + return &rc2Cipher{ + k: expandKey(key, t1), + }, nil +} + +func (_ *rc2Cipher) BlockSize() int { return BlockSize } + +var piTable = [256]byte{ + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, + 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, + 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, + 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, + 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, + 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, + 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, + 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, + 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, + 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, + 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad, +} + +func expandKey(key []byte, t1 int) [64]uint16 { + + l := make([]byte, 128) + copy(l, key) + + var t = len(key) + var t8 = (t1 + 7) / 8 + var tm = byte(255 % uint(1<<(8+uint(t1)-8*uint(t8)))) + + for i := len(key); i < 128; i++ { + l[i] = piTable[l[i-1]+l[uint8(i-t)]] + } + + l[128-t8] = piTable[l[128-t8]&tm] + + for i := 127 - t8; i >= 0; i-- { + l[i] = piTable[l[i+1]^l[i+t8]] + } + + var k [64]uint16 + + for i := range k { + k[i] = uint16(l[2*i]) + uint16(l[2*i+1])*256 + } + + return k +} + +func rotl16(x uint16, b uint) uint16 { + return (x >> (16 - b)) | (x << b) +} + +func (c *rc2Cipher) Encrypt(dst, src []byte) { + + r0 := binary.LittleEndian.Uint16(src[0:]) + r1 := binary.LittleEndian.Uint16(src[2:]) + r2 := binary.LittleEndian.Uint16(src[4:]) + r3 := binary.LittleEndian.Uint16(src[6:]) + + var j int + + for j <= 16 { + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = rotl16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = rotl16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = rotl16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = rotl16(r3, 5) + j++ + + } + + r0 = r0 + c.k[r3&63] + r1 = r1 + c.k[r0&63] + r2 = r2 + c.k[r1&63] + r3 = r3 + c.k[r2&63] + + for j <= 40 { + + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = rotl16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = rotl16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = rotl16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = rotl16(r3, 5) + j++ + + } + + r0 = r0 + c.k[r3&63] + r1 = r1 + c.k[r0&63] + r2 = r2 + c.k[r1&63] + r3 = r3 + c.k[r2&63] + + for j <= 60 { + + // mix r0 + r0 = r0 + c.k[j] + (r3 & r2) + ((^r3) & r1) + r0 = rotl16(r0, 1) + j++ + + // mix r1 + r1 = r1 + c.k[j] + (r0 & r3) + ((^r0) & r2) + r1 = rotl16(r1, 2) + j++ + + // mix r2 + r2 = r2 + c.k[j] + (r1 & r0) + ((^r1) & r3) + r2 = rotl16(r2, 3) + j++ + + // mix r3 + r3 = r3 + c.k[j] + (r2 & r1) + ((^r2) & r0) + r3 = rotl16(r3, 5) + j++ + } + + binary.LittleEndian.PutUint16(dst[0:], r0) + binary.LittleEndian.PutUint16(dst[2:], r1) + binary.LittleEndian.PutUint16(dst[4:], r2) + binary.LittleEndian.PutUint16(dst[6:], r3) +} + +func (c *rc2Cipher) Decrypt(dst, src []byte) { + + r0 := binary.LittleEndian.Uint16(src[0:]) + r1 := binary.LittleEndian.Uint16(src[2:]) + r2 := binary.LittleEndian.Uint16(src[4:]) + r3 := binary.LittleEndian.Uint16(src[6:]) + + j := 63 + + for j >= 44 { + // unmix r3 + r3 = rotl16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = rotl16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = rotl16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = rotl16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + } + + r3 = r3 - c.k[r2&63] + r2 = r2 - c.k[r1&63] + r1 = r1 - c.k[r0&63] + r0 = r0 - c.k[r3&63] + + for j >= 20 { + // unmix r3 + r3 = rotl16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = rotl16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = rotl16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = rotl16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + + } + + r3 = r3 - c.k[r2&63] + r2 = r2 - c.k[r1&63] + r1 = r1 - c.k[r0&63] + r0 = r0 - c.k[r3&63] + + for j >= 0 { + + // unmix r3 + r3 = rotl16(r3, 16-5) + r3 = r3 - c.k[j] - (r2 & r1) - ((^r2) & r0) + j-- + + // unmix r2 + r2 = rotl16(r2, 16-3) + r2 = r2 - c.k[j] - (r1 & r0) - ((^r1) & r3) + j-- + + // unmix r1 + r1 = rotl16(r1, 16-2) + r1 = r1 - c.k[j] - (r0 & r3) - ((^r0) & r2) + j-- + + // unmix r0 + r0 = rotl16(r0, 16-1) + r0 = r0 - c.k[j] - (r3 & r2) - ((^r3) & r1) + j-- + + } + + binary.LittleEndian.PutUint16(dst[0:], r0) + binary.LittleEndian.PutUint16(dst[2:], r1) + binary.LittleEndian.PutUint16(dst[4:], r2) + binary.LittleEndian.PutUint16(dst[6:], r3) +} diff --git a/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2_test.go b/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2_test.go new file mode 100644 index 00000000000..237c3d1591b --- /dev/null +++ b/Godeps/_workspace/src/github.com/dgryski/go-rc2/rc2_test.go @@ -0,0 +1,89 @@ +package rc2 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func TestEncryptDecrypt(t *testing.T) { + + // TODO(dgryski): add the rest of the test vectors from the RFC + var tests = []struct { + key string + plain string + cipher string + t1 int + }{ + { + "0000000000000000", + "0000000000000000", + "ebb773f993278eff", + 63, + }, + { + "ffffffffffffffff", + "ffffffffffffffff", + "278b27e42e2f0d49", + 64, + }, + { + "3000000000000000", + "1000000000000001", + "30649edf9be7d2c2", + 64, + }, + { + "88", + "0000000000000000", + "61a8a244adacccf0", + 64, + }, + { + "88bca90e90875a", + "0000000000000000", + "6ccf4308974c267f", + 64, + }, + { + "88bca90e90875a7f0f79c384627bafb2", + "0000000000000000", + "1a807d272bbe5db1", + 64, + }, + { + "88bca90e90875a7f0f79c384627bafb2", + "0000000000000000", + "2269552ab0f85ca6", + 128, + }, + { + "88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e", + "0000000000000000", + "5b78d3a43dfff1f1", + 129, + }, + } + + for _, tt := range tests { + k, _ := hex.DecodeString(tt.key) + p, _ := hex.DecodeString(tt.plain) + c, _ := hex.DecodeString(tt.cipher) + + b, _ := New(k, tt.t1) + + var dst [8]byte + + b.Encrypt(dst[:], p) + + if !bytes.Equal(dst[:], c) { + t.Errorf("encrypt failed: got % 2x wanted % 2x\n", dst, c) + } + + b.Decrypt(dst[:], c) + + if !bytes.Equal(dst[:], p) { + t.Errorf("decrypt failed: got % 2x wanted % 2x\n", dst, p) + } + } +} diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/.gitignore b/Godeps/_workspace/src/github.com/miekg/pkcs11/.gitignore new file mode 100644 index 00000000000..6e92f57d464 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/.gitignore @@ -0,0 +1 @@ +tags diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/LICENSE b/Godeps/_workspace/src/github.com/miekg/pkcs11/LICENSE new file mode 100644 index 00000000000..ce25d13ab84 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013 Miek Gieben. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Miek Gieben nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/README.md b/Godeps/_workspace/src/github.com/miekg/pkcs11/README.md new file mode 100644 index 00000000000..6e7e550c212 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/README.md @@ -0,0 +1,48 @@ +# PKCS#11 + +This is a Go implementation of the PKCS#11 API. It wraps the library closely, but uses Go idiom +were it makes sense. It has been tested with SoftHSM. + +## SoftHSM + +* Make it use a custom configuration file + + export SOFTHSM_CONF=$PWD/softhsm.conf + +* Then use `softhsm` to init it + + softhsm --init-token --slot 0 --label test --pin 1234 + +* Then use `libsofthsm.so` as the pkcs11 module: + + p := pkcs11.New("/usr/lib/softhsm/libsofthsm.so") + +## Examples + +A skeleton program would look somewhat like this (yes, pkcs#11 is verbose): + + p := pkcs11.New("/usr/lib/softhsm/libsofthsm.so") + p.Initialize() + defer p.Destroy() + defer p.Finalize() + slots, _ := p.GetSlotList(true) + session, _ := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION) + defer p.CloseSession(session) + p.Login(session, pkcs11.CKU_USER, "1234") + defer p.Logout(session) + p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)}) + hash, err := p.Digest(session, []byte("this is a string")) + for _, d := range hash { + fmt.Printf("%x", d) + } + fmt.Println() + +Further examples are included in the tests. + +# TODO + +* Fix/double check endian stuff, see types.go NewAttribute(); +* Kill C.Sizeof in that same function. +* Look at the memory copying in fast functions (sign, hash etc). +* Fix inconsistencies in naming? +* Add tests -- there are way too few diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/const.go b/Godeps/_workspace/src/github.com/miekg/pkcs11/const.go new file mode 100644 index 00000000000..79a25e345db --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/const.go @@ -0,0 +1,561 @@ +// Copyright 2013 Miek Gieben. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs11 + +const ( + CKU_SO uint = 0 + CKU_USER uint = 1 + CKU_CONTEXT_SPECIFIC uint = 2 +) + +const ( + CKO_DATA uint = 0x00000000 + CKO_CERTIFICATE uint = 0x00000001 + CKO_PUBLIC_KEY uint = 0x00000002 + CKO_PRIVATE_KEY uint = 0x00000003 + CKO_SECRET_KEY uint = 0x00000004 + CKO_HW_FEATURE uint = 0x00000005 + CKO_DOMAIN_PARAMETERS uint = 0x00000006 + CKO_MECHANISM uint = 0x00000007 + CKO_OTP_KEY uint = 0x00000008 + CKO_VENDOR_DEFINED uint = 0x80000000 +) + +// Generated with: awk '/#define CK[AFKMR]/{ print $2 "=" $3 }' pkcs11t.h + +// All the flag (CKF_), attribute (CKA_), error code (CKR_), key type (CKK_) and +// mechanism (CKM_) constants as defined in PKCS#11. +const ( + CKF_TOKEN_PRESENT = 0x00000001 + CKF_REMOVABLE_DEVICE = 0x00000002 + CKF_HW_SLOT = 0x00000004 + CKF_RNG = 0x00000001 + CKF_WRITE_PROTECTED = 0x00000002 + CKF_LOGIN_REQUIRED = 0x00000004 + CKF_USER_PIN_INITIALIZED = 0x00000008 + CKF_RESTORE_KEY_NOT_NEEDED = 0x00000020 + CKF_CLOCK_ON_TOKEN = 0x00000040 + CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100 + CKF_DUAL_CRYPTO_OPERATIONS = 0x00000200 + CKF_TOKEN_INITIALIZED = 0x00000400 + CKF_SECONDARY_AUTHENTICATION = 0x00000800 + CKF_USER_PIN_COUNT_LOW = 0x00010000 + CKF_USER_PIN_FINAL_TRY = 0x00020000 + CKF_USER_PIN_LOCKED = 0x00040000 + CKF_USER_PIN_TO_BE_CHANGED = 0x00080000 + CKF_SO_PIN_COUNT_LOW = 0x00100000 + CKF_SO_PIN_FINAL_TRY = 0x00200000 + CKF_SO_PIN_LOCKED = 0x00400000 + CKF_SO_PIN_TO_BE_CHANGED = 0x00800000 + CKF_RW_SESSION = 0x00000002 + CKF_SERIAL_SESSION = 0x00000004 + CKK_RSA = 0x00000000 + CKK_DSA = 0x00000001 + CKK_DH = 0x00000002 + CKK_ECDSA = 0x00000003 + CKK_EC = 0x00000003 + CKK_X9_42_DH = 0x00000004 + CKK_KEA = 0x00000005 + CKK_GENERIC_SECRET = 0x00000010 + CKK_RC2 = 0x00000011 + CKK_RC4 = 0x00000012 + CKK_DES = 0x00000013 + CKK_DES2 = 0x00000014 + CKK_DES3 = 0x00000015 + CKK_CAST = 0x00000016 + CKK_CAST3 = 0x00000017 + CKK_CAST5 = 0x00000018 + CKK_CAST128 = 0x00000018 + CKK_RC5 = 0x00000019 + CKK_IDEA = 0x0000001A + CKK_SKIPJACK = 0x0000001B + CKK_BATON = 0x0000001C + CKK_JUNIPER = 0x0000001D + CKK_CDMF = 0x0000001E + CKK_AES = 0x0000001F + CKK_BLOWFISH = 0x00000020 + CKK_TWOFISH = 0x00000021 + CKK_SECURID = 0x00000022 + CKK_HOTP = 0x00000023 + CKK_ACTI = 0x00000024 + CKK_CAMELLIA = 0x00000025 + CKK_ARIA = 0x00000026 + CKK_VENDOR_DEFINED = 0x80000000 + CKF_ARRAY_ATTRIBUTE = 0x40000000 + CKA_CLASS = 0x00000000 + CKA_TOKEN = 0x00000001 + CKA_PRIVATE = 0x00000002 + CKA_LABEL = 0x00000003 + CKA_APPLICATION = 0x00000010 + CKA_VALUE = 0x00000011 + CKA_OBJECT_ID = 0x00000012 + CKA_CERTIFICATE_TYPE = 0x00000080 + CKA_ISSUER = 0x00000081 + CKA_SERIAL_NUMBER = 0x00000082 + CKA_AC_ISSUER = 0x00000083 + CKA_OWNER = 0x00000084 + CKA_ATTR_TYPES = 0x00000085 + CKA_TRUSTED = 0x00000086 + CKA_CERTIFICATE_CATEGORY = 0x00000087 + CKA_JAVA_MIDP_SECURITY_DOMAIN = 0x00000088 + CKA_URL = 0x00000089 + CKA_HASH_OF_SUBJECT_PUBLIC_KEY = 0x0000008A + CKA_HASH_OF_ISSUER_PUBLIC_KEY = 0x0000008B + CKA_CHECK_VALUE = 0x00000090 + CKA_KEY_TYPE = 0x00000100 + CKA_SUBJECT = 0x00000101 + CKA_ID = 0x00000102 + CKA_SENSITIVE = 0x00000103 + CKA_ENCRYPT = 0x00000104 + CKA_DECRYPT = 0x00000105 + CKA_WRAP = 0x00000106 + CKA_UNWRAP = 0x00000107 + CKA_SIGN = 0x00000108 + CKA_SIGN_RECOVER = 0x00000109 + CKA_VERIFY = 0x0000010A + CKA_VERIFY_RECOVER = 0x0000010B + CKA_DERIVE = 0x0000010C + CKA_START_DATE = 0x00000110 // Use time.Time as a value. + CKA_END_DATE = 0x00000111 // Use time.Time as a value. + CKA_MODULUS = 0x00000120 + CKA_MODULUS_BITS = 0x00000121 + CKA_PUBLIC_EXPONENT = 0x00000122 // Use []byte slice as a value. + CKA_PRIVATE_EXPONENT = 0x00000123 + CKA_PRIME_1 = 0x00000124 + CKA_PRIME_2 = 0x00000125 + CKA_EXPONENT_1 = 0x00000126 + CKA_EXPONENT_2 = 0x00000127 + CKA_COEFFICIENT = 0x00000128 + CKA_PRIME = 0x00000130 + CKA_SUBPRIME = 0x00000131 + CKA_BASE = 0x00000132 + CKA_PRIME_BITS = 0x00000133 + CKA_SUBPRIME_BITS = 0x00000134 + CKA_SUB_PRIME_BITS = CKA_SUBPRIME_BITS + CKA_VALUE_BITS = 0x00000160 + CKA_VALUE_LEN = 0x00000161 + CKA_EXTRACTABLE = 0x00000162 + CKA_LOCAL = 0x00000163 + CKA_NEVER_EXTRACTABLE = 0x00000164 + CKA_ALWAYS_SENSITIVE = 0x00000165 + CKA_KEY_GEN_MECHANISM = 0x00000166 + CKA_MODIFIABLE = 0x00000170 + CKA_ECDSA_PARAMS = 0x00000180 + CKA_EC_PARAMS = 0x00000180 + CKA_EC_POINT = 0x00000181 + CKA_SECONDARY_AUTH = 0x00000200 + CKA_AUTH_PIN_FLAGS = 0x00000201 + CKA_ALWAYS_AUTHENTICATE = 0x00000202 + CKA_WRAP_WITH_TRUSTED = 0x00000210 + CKA_WRAP_TEMPLATE = (CKF_ARRAY_ATTRIBUTE | 0x00000211) + CKA_UNWRAP_TEMPLATE = (CKF_ARRAY_ATTRIBUTE | 0x00000212) + CKA_OTP_FORMAT = 0x00000220 + CKA_OTP_LENGTH = 0x00000221 + CKA_OTP_TIME_INTERVAL = 0x00000222 + CKA_OTP_USER_FRIENDLY_MODE = 0x00000223 + CKA_OTP_CHALLENGE_REQUIREMENT = 0x00000224 + CKA_OTP_TIME_REQUIREMENT = 0x00000225 + CKA_OTP_COUNTER_REQUIREMENT = 0x00000226 + CKA_OTP_PIN_REQUIREMENT = 0x00000227 + CKA_OTP_COUNTER = 0x0000022E + CKA_OTP_TIME = 0x0000022F + CKA_OTP_USER_IDENTIFIER = 0x0000022A + CKA_OTP_SERVICE_IDENTIFIER = 0x0000022B + CKA_OTP_SERVICE_LOGO = 0x0000022C + CKA_OTP_SERVICE_LOGO_TYPE = 0x0000022D + CKA_HW_FEATURE_TYPE = 0x00000300 + CKA_RESET_ON_INIT = 0x00000301 + CKA_HAS_RESET = 0x00000302 + CKA_PIXEL_X = 0x00000400 + CKA_PIXEL_Y = 0x00000401 + CKA_RESOLUTION = 0x00000402 + CKA_CHAR_ROWS = 0x00000403 + CKA_CHAR_COLUMNS = 0x00000404 + CKA_COLOR = 0x00000405 + CKA_BITS_PER_PIXEL = 0x00000406 + CKA_CHAR_SETS = 0x00000480 + CKA_ENCODING_METHODS = 0x00000481 + CKA_MIME_TYPES = 0x00000482 + CKA_MECHANISM_TYPE = 0x00000500 + CKA_REQUIRED_CMS_ATTRIBUTES = 0x00000501 + CKA_DEFAULT_CMS_ATTRIBUTES = 0x00000502 + CKA_SUPPORTED_CMS_ATTRIBUTES = 0x00000503 + CKA_ALLOWED_MECHANISMS = (CKF_ARRAY_ATTRIBUTE | 0x00000600) + CKA_VENDOR_DEFINED = 0x80000000 + CKM_RSA_PKCS_KEY_PAIR_GEN = 0x00000000 + CKM_RSA_PKCS = 0x00000001 + CKM_RSA_9796 = 0x00000002 + CKM_RSA_X_509 = 0x00000003 + CKM_MD2_RSA_PKCS = 0x00000004 + CKM_MD5_RSA_PKCS = 0x00000005 + CKM_SHA1_RSA_PKCS = 0x00000006 + CKM_RIPEMD128_RSA_PKCS = 0x00000007 + CKM_RIPEMD160_RSA_PKCS = 0x00000008 + CKM_RSA_PKCS_OAEP = 0x00000009 + CKM_RSA_X9_31_KEY_PAIR_GEN = 0x0000000A + CKM_RSA_X9_31 = 0x0000000B + CKM_SHA1_RSA_X9_31 = 0x0000000C + CKM_RSA_PKCS_PSS = 0x0000000D + CKM_SHA1_RSA_PKCS_PSS = 0x0000000E + CKM_DSA_KEY_PAIR_GEN = 0x00000010 + CKM_DSA = 0x00000011 + CKM_DSA_SHA1 = 0x00000012 + CKM_DH_PKCS_KEY_PAIR_GEN = 0x00000020 + CKM_DH_PKCS_DERIVE = 0x00000021 + CKM_X9_42_DH_KEY_PAIR_GEN = 0x00000030 + CKM_X9_42_DH_DERIVE = 0x00000031 + CKM_X9_42_DH_HYBRID_DERIVE = 0x00000032 + CKM_X9_42_MQV_DERIVE = 0x00000033 + CKM_SHA256_RSA_PKCS = 0x00000040 + CKM_SHA384_RSA_PKCS = 0x00000041 + CKM_SHA512_RSA_PKCS = 0x00000042 + CKM_SHA256_RSA_PKCS_PSS = 0x00000043 + CKM_SHA384_RSA_PKCS_PSS = 0x00000044 + CKM_SHA512_RSA_PKCS_PSS = 0x00000045 + CKM_SHA224_RSA_PKCS = 0x00000046 + CKM_SHA224_RSA_PKCS_PSS = 0x00000047 + CKM_RC2_KEY_GEN = 0x00000100 + CKM_RC2_ECB = 0x00000101 + CKM_RC2_CBC = 0x00000102 + CKM_RC2_MAC = 0x00000103 + CKM_RC2_MAC_GENERAL = 0x00000104 + CKM_RC2_CBC_PAD = 0x00000105 + CKM_RC4_KEY_GEN = 0x00000110 + CKM_RC4 = 0x00000111 + CKM_DES_KEY_GEN = 0x00000120 + CKM_DES_ECB = 0x00000121 + CKM_DES_CBC = 0x00000122 + CKM_DES_MAC = 0x00000123 + CKM_DES_MAC_GENERAL = 0x00000124 + CKM_DES_CBC_PAD = 0x00000125 + CKM_DES2_KEY_GEN = 0x00000130 + CKM_DES3_KEY_GEN = 0x00000131 + CKM_DES3_ECB = 0x00000132 + CKM_DES3_CBC = 0x00000133 + CKM_DES3_MAC = 0x00000134 + CKM_DES3_MAC_GENERAL = 0x00000135 + CKM_DES3_CBC_PAD = 0x00000136 + CKM_CDMF_KEY_GEN = 0x00000140 + CKM_CDMF_ECB = 0x00000141 + CKM_CDMF_CBC = 0x00000142 + CKM_CDMF_MAC = 0x00000143 + CKM_CDMF_MAC_GENERAL = 0x00000144 + CKM_CDMF_CBC_PAD = 0x00000145 + CKM_DES_OFB64 = 0x00000150 + CKM_DES_OFB8 = 0x00000151 + CKM_DES_CFB64 = 0x00000152 + CKM_DES_CFB8 = 0x00000153 + CKM_MD2 = 0x00000200 + CKM_MD2_HMAC = 0x00000201 + CKM_MD2_HMAC_GENERAL = 0x00000202 + CKM_MD5 = 0x00000210 + CKM_MD5_HMAC = 0x00000211 + CKM_MD5_HMAC_GENERAL = 0x00000212 + CKM_SHA_1 = 0x00000220 + CKM_SHA_1_HMAC = 0x00000221 + CKM_SHA_1_HMAC_GENERAL = 0x00000222 + CKM_RIPEMD128 = 0x00000230 + CKM_RIPEMD128_HMAC = 0x00000231 + CKM_RIPEMD128_HMAC_GENERAL = 0x00000232 + CKM_RIPEMD160 = 0x00000240 + CKM_RIPEMD160_HMAC = 0x00000241 + CKM_RIPEMD160_HMAC_GENERAL = 0x00000242 + CKM_SHA256 = 0x00000250 + CKM_SHA256_HMAC = 0x00000251 + CKM_SHA256_HMAC_GENERAL = 0x00000252 + CKM_SHA224 = 0x00000255 + CKM_SHA224_HMAC = 0x00000256 + CKM_SHA224_HMAC_GENERAL = 0x00000257 + CKM_SHA384 = 0x00000260 + CKM_SHA384_HMAC = 0x00000261 + CKM_SHA384_HMAC_GENERAL = 0x00000262 + CKM_SHA512 = 0x00000270 + CKM_SHA512_HMAC = 0x00000271 + CKM_SHA512_HMAC_GENERAL = 0x00000272 + CKM_SECURID_KEY_GEN = 0x00000280 + CKM_SECURID = 0x00000282 + CKM_HOTP_KEY_GEN = 0x00000290 + CKM_HOTP = 0x00000291 + CKM_ACTI = 0x000002A0 + CKM_ACTI_KEY_GEN = 0x000002A1 + CKM_CAST_KEY_GEN = 0x00000300 + CKM_CAST_ECB = 0x00000301 + CKM_CAST_CBC = 0x00000302 + CKM_CAST_MAC = 0x00000303 + CKM_CAST_MAC_GENERAL = 0x00000304 + CKM_CAST_CBC_PAD = 0x00000305 + CKM_CAST3_KEY_GEN = 0x00000310 + CKM_CAST3_ECB = 0x00000311 + CKM_CAST3_CBC = 0x00000312 + CKM_CAST3_MAC = 0x00000313 + CKM_CAST3_MAC_GENERAL = 0x00000314 + CKM_CAST3_CBC_PAD = 0x00000315 + CKM_CAST5_KEY_GEN = 0x00000320 + CKM_CAST128_KEY_GEN = 0x00000320 + CKM_CAST5_ECB = 0x00000321 + CKM_CAST128_ECB = 0x00000321 + CKM_CAST5_CBC = 0x00000322 + CKM_CAST128_CBC = 0x00000322 + CKM_CAST5_MAC = 0x00000323 + CKM_CAST128_MAC = 0x00000323 + CKM_CAST5_MAC_GENERAL = 0x00000324 + CKM_CAST128_MAC_GENERAL = 0x00000324 + CKM_CAST5_CBC_PAD = 0x00000325 + CKM_CAST128_CBC_PAD = 0x00000325 + CKM_RC5_KEY_GEN = 0x00000330 + CKM_RC5_ECB = 0x00000331 + CKM_RC5_CBC = 0x00000332 + CKM_RC5_MAC = 0x00000333 + CKM_RC5_MAC_GENERAL = 0x00000334 + CKM_RC5_CBC_PAD = 0x00000335 + CKM_IDEA_KEY_GEN = 0x00000340 + CKM_IDEA_ECB = 0x00000341 + CKM_IDEA_CBC = 0x00000342 + CKM_IDEA_MAC = 0x00000343 + CKM_IDEA_MAC_GENERAL = 0x00000344 + CKM_IDEA_CBC_PAD = 0x00000345 + CKM_GENERIC_SECRET_KEY_GEN = 0x00000350 + CKM_CONCATENATE_BASE_AND_KEY = 0x00000360 + CKM_CONCATENATE_BASE_AND_DATA = 0x00000362 + CKM_CONCATENATE_DATA_AND_BASE = 0x00000363 + CKM_XOR_BASE_AND_DATA = 0x00000364 + CKM_EXTRACT_KEY_FROM_KEY = 0x00000365 + CKM_SSL3_PRE_MASTER_KEY_GEN = 0x00000370 + CKM_SSL3_MASTER_KEY_DERIVE = 0x00000371 + CKM_SSL3_KEY_AND_MAC_DERIVE = 0x00000372 + CKM_SSL3_MASTER_KEY_DERIVE_DH = 0x00000373 + CKM_TLS_PRE_MASTER_KEY_GEN = 0x00000374 + CKM_TLS_MASTER_KEY_DERIVE = 0x00000375 + CKM_TLS_KEY_AND_MAC_DERIVE = 0x00000376 + CKM_TLS_MASTER_KEY_DERIVE_DH = 0x00000377 + CKM_TLS_PRF = 0x00000378 + CKM_SSL3_MD5_MAC = 0x00000380 + CKM_SSL3_SHA1_MAC = 0x00000381 + CKM_MD5_KEY_DERIVATION = 0x00000390 + CKM_MD2_KEY_DERIVATION = 0x00000391 + CKM_SHA1_KEY_DERIVATION = 0x00000392 + CKM_SHA256_KEY_DERIVATION = 0x00000393 + CKM_SHA384_KEY_DERIVATION = 0x00000394 + CKM_SHA512_KEY_DERIVATION = 0x00000395 + CKM_SHA224_KEY_DERIVATION = 0x00000396 + CKM_PBE_MD2_DES_CBC = 0x000003A0 + CKM_PBE_MD5_DES_CBC = 0x000003A1 + CKM_PBE_MD5_CAST_CBC = 0x000003A2 + CKM_PBE_MD5_CAST3_CBC = 0x000003A3 + CKM_PBE_MD5_CAST5_CBC = 0x000003A4 + CKM_PBE_MD5_CAST128_CBC = 0x000003A4 + CKM_PBE_SHA1_CAST5_CBC = 0x000003A5 + CKM_PBE_SHA1_CAST128_CBC = 0x000003A5 + CKM_PBE_SHA1_RC4_128 = 0x000003A6 + CKM_PBE_SHA1_RC4_40 = 0x000003A7 + CKM_PBE_SHA1_DES3_EDE_CBC = 0x000003A8 + CKM_PBE_SHA1_DES2_EDE_CBC = 0x000003A9 + CKM_PBE_SHA1_RC2_128_CBC = 0x000003AA + CKM_PBE_SHA1_RC2_40_CBC = 0x000003AB + CKM_PKCS5_PBKD2 = 0x000003B0 + CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0 + CKM_WTLS_PRE_MASTER_KEY_GEN = 0x000003D0 + CKM_WTLS_MASTER_KEY_DERIVE = 0x000003D1 + CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC = 0x000003D2 + CKM_WTLS_PRF = 0x000003D3 + CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE = 0x000003D4 + CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE = 0x000003D5 + CKM_KEY_WRAP_LYNKS = 0x00000400 + CKM_KEY_WRAP_SET_OAEP = 0x00000401 + CKM_CMS_SIG = 0x00000500 + CKM_KIP_DERIVE = 0x00000510 + CKM_KIP_WRAP = 0x00000511 + CKM_KIP_MAC = 0x00000512 + CKM_CAMELLIA_KEY_GEN = 0x00000550 + CKM_CAMELLIA_ECB = 0x00000551 + CKM_CAMELLIA_CBC = 0x00000552 + CKM_CAMELLIA_MAC = 0x00000553 + CKM_CAMELLIA_MAC_GENERAL = 0x00000554 + CKM_CAMELLIA_CBC_PAD = 0x00000555 + CKM_CAMELLIA_ECB_ENCRYPT_DATA = 0x00000556 + CKM_CAMELLIA_CBC_ENCRYPT_DATA = 0x00000557 + CKM_CAMELLIA_CTR = 0x00000558 + CKM_ARIA_KEY_GEN = 0x00000560 + CKM_ARIA_ECB = 0x00000561 + CKM_ARIA_CBC = 0x00000562 + CKM_ARIA_MAC = 0x00000563 + CKM_ARIA_MAC_GENERAL = 0x00000564 + CKM_ARIA_CBC_PAD = 0x00000565 + CKM_ARIA_ECB_ENCRYPT_DATA = 0x00000566 + CKM_ARIA_CBC_ENCRYPT_DATA = 0x00000567 + CKM_SKIPJACK_KEY_GEN = 0x00001000 + CKM_SKIPJACK_ECB64 = 0x00001001 + CKM_SKIPJACK_CBC64 = 0x00001002 + CKM_SKIPJACK_OFB64 = 0x00001003 + CKM_SKIPJACK_CFB64 = 0x00001004 + CKM_SKIPJACK_CFB32 = 0x00001005 + CKM_SKIPJACK_CFB16 = 0x00001006 + CKM_SKIPJACK_CFB8 = 0x00001007 + CKM_SKIPJACK_WRAP = 0x00001008 + CKM_SKIPJACK_PRIVATE_WRAP = 0x00001009 + CKM_SKIPJACK_RELAYX = 0x0000100a + CKM_KEA_KEY_PAIR_GEN = 0x00001010 + CKM_KEA_KEY_DERIVE = 0x00001011 + CKM_FORTEZZA_TIMESTAMP = 0x00001020 + CKM_BATON_KEY_GEN = 0x00001030 + CKM_BATON_ECB128 = 0x00001031 + CKM_BATON_ECB96 = 0x00001032 + CKM_BATON_CBC128 = 0x00001033 + CKM_BATON_COUNTER = 0x00001034 + CKM_BATON_SHUFFLE = 0x00001035 + CKM_BATON_WRAP = 0x00001036 + CKM_ECDSA_KEY_PAIR_GEN = 0x00001040 + CKM_EC_KEY_PAIR_GEN = 0x00001040 + CKM_ECDSA = 0x00001041 + CKM_ECDSA_SHA1 = 0x00001042 + CKM_ECDH1_DERIVE = 0x00001050 + CKM_ECDH1_COFACTOR_DERIVE = 0x00001051 + CKM_ECMQV_DERIVE = 0x00001052 + CKM_JUNIPER_KEY_GEN = 0x00001060 + CKM_JUNIPER_ECB128 = 0x00001061 + CKM_JUNIPER_CBC128 = 0x00001062 + CKM_JUNIPER_COUNTER = 0x00001063 + CKM_JUNIPER_SHUFFLE = 0x00001064 + CKM_JUNIPER_WRAP = 0x00001065 + CKM_FASTHASH = 0x00001070 + CKM_AES_KEY_GEN = 0x00001080 + CKM_AES_ECB = 0x00001081 + CKM_AES_CBC = 0x00001082 + CKM_AES_MAC = 0x00001083 + CKM_AES_MAC_GENERAL = 0x00001084 + CKM_AES_CBC_PAD = 0x00001085 + CKM_AES_CTR = 0x00001086 + CKM_BLOWFISH_KEY_GEN = 0x00001090 + CKM_BLOWFISH_CBC = 0x00001091 + CKM_TWOFISH_KEY_GEN = 0x00001092 + CKM_TWOFISH_CBC = 0x00001093 + CKM_DES_ECB_ENCRYPT_DATA = 0x00001100 + CKM_DES_CBC_ENCRYPT_DATA = 0x00001101 + CKM_DES3_ECB_ENCRYPT_DATA = 0x00001102 + CKM_DES3_CBC_ENCRYPT_DATA = 0x00001103 + CKM_AES_ECB_ENCRYPT_DATA = 0x00001104 + CKM_AES_CBC_ENCRYPT_DATA = 0x00001105 + CKM_DSA_PARAMETER_GEN = 0x00002000 + CKM_DH_PKCS_PARAMETER_GEN = 0x00002001 + CKM_X9_42_DH_PARAMETER_GEN = 0x00002002 + CKM_VENDOR_DEFINED = 0x80000000 + CKF_HW = 0x00000001 + CKF_ENCRYPT = 0x00000100 + CKF_DECRYPT = 0x00000200 + CKF_DIGEST = 0x00000400 + CKF_SIGN = 0x00000800 + CKF_SIGN_RECOVER = 0x00001000 + CKF_VERIFY = 0x00002000 + CKF_VERIFY_RECOVER = 0x00004000 + CKF_GENERATE = 0x00008000 + CKF_GENERATE_KEY_PAIR = 0x00010000 + CKF_WRAP = 0x00020000 + CKF_UNWRAP = 0x00040000 + CKF_DERIVE = 0x00080000 + CKF_EC_F_P = 0x00100000 + CKF_EC_F_2M = 0x00200000 + CKF_EC_ECPARAMETERS = 0x00400000 + CKF_EC_NAMEDCURVE = 0x00800000 + CKF_EC_UNCOMPRESS = 0x01000000 + CKF_EC_COMPRESS = 0x02000000 + CKF_EXTENSION = 0x80000000 + CKR_OK = 0x00000000 + CKR_CANCEL = 0x00000001 + CKR_HOST_MEMORY = 0x00000002 + CKR_SLOT_ID_INVALID = 0x00000003 + CKR_GENERAL_ERROR = 0x00000005 + CKR_FUNCTION_FAILED = 0x00000006 + CKR_ARGUMENTS_BAD = 0x00000007 + CKR_NO_EVENT = 0x00000008 + CKR_NEED_TO_CREATE_THREADS = 0x00000009 + CKR_CANT_LOCK = 0x0000000A + CKR_ATTRIBUTE_READ_ONLY = 0x00000010 + CKR_ATTRIBUTE_SENSITIVE = 0x00000011 + CKR_ATTRIBUTE_TYPE_INVALID = 0x00000012 + CKR_ATTRIBUTE_VALUE_INVALID = 0x00000013 + CKR_DATA_INVALID = 0x00000020 + CKR_DATA_LEN_RANGE = 0x00000021 + CKR_DEVICE_ERROR = 0x00000030 + CKR_DEVICE_MEMORY = 0x00000031 + CKR_DEVICE_REMOVED = 0x00000032 + CKR_ENCRYPTED_DATA_INVALID = 0x00000040 + CKR_ENCRYPTED_DATA_LEN_RANGE = 0x00000041 + CKR_FUNCTION_CANCELED = 0x00000050 + CKR_FUNCTION_NOT_PARALLEL = 0x00000051 + CKR_FUNCTION_NOT_SUPPORTED = 0x00000054 + CKR_KEY_HANDLE_INVALID = 0x00000060 + CKR_KEY_SIZE_RANGE = 0x00000062 + CKR_KEY_TYPE_INCONSISTENT = 0x00000063 + CKR_KEY_NOT_NEEDED = 0x00000064 + CKR_KEY_CHANGED = 0x00000065 + CKR_KEY_NEEDED = 0x00000066 + CKR_KEY_INDIGESTIBLE = 0x00000067 + CKR_KEY_FUNCTION_NOT_PERMITTED = 0x00000068 + CKR_KEY_NOT_WRAPPABLE = 0x00000069 + CKR_KEY_UNEXTRACTABLE = 0x0000006A + CKR_MECHANISM_INVALID = 0x00000070 + CKR_MECHANISM_PARAM_INVALID = 0x00000071 + CKR_OBJECT_HANDLE_INVALID = 0x00000082 + CKR_OPERATION_ACTIVE = 0x00000090 + CKR_OPERATION_NOT_INITIALIZED = 0x00000091 + CKR_PIN_INCORRECT = 0x000000A0 + CKR_PIN_INVALID = 0x000000A1 + CKR_PIN_LEN_RANGE = 0x000000A2 + CKR_PIN_EXPIRED = 0x000000A3 + CKR_PIN_LOCKED = 0x000000A4 + CKR_SESSION_CLOSED = 0x000000B0 + CKR_SESSION_COUNT = 0x000000B1 + CKR_SESSION_HANDLE_INVALID = 0x000000B3 + CKR_SESSION_PARALLEL_NOT_SUPPORTED = 0x000000B4 + CKR_SESSION_READ_ONLY = 0x000000B5 + CKR_SESSION_EXISTS = 0x000000B6 + CKR_SESSION_READ_ONLY_EXISTS = 0x000000B7 + CKR_SESSION_READ_WRITE_SO_EXISTS = 0x000000B8 + CKR_SIGNATURE_INVALID = 0x000000C0 + CKR_SIGNATURE_LEN_RANGE = 0x000000C1 + CKR_TEMPLATE_INCOMPLETE = 0x000000D0 + CKR_TEMPLATE_INCONSISTENT = 0x000000D1 + CKR_TOKEN_NOT_PRESENT = 0x000000E0 + CKR_TOKEN_NOT_RECOGNIZED = 0x000000E1 + CKR_TOKEN_WRITE_PROTECTED = 0x000000E2 + CKR_UNWRAPPING_KEY_HANDLE_INVALID = 0x000000F0 + CKR_UNWRAPPING_KEY_SIZE_RANGE = 0x000000F1 + CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT = 0x000000F2 + CKR_USER_ALREADY_LOGGED_IN = 0x00000100 + CKR_USER_NOT_LOGGED_IN = 0x00000101 + CKR_USER_PIN_NOT_INITIALIZED = 0x00000102 + CKR_USER_TYPE_INVALID = 0x00000103 + CKR_USER_ANOTHER_ALREADY_LOGGED_IN = 0x00000104 + CKR_USER_TOO_MANY_TYPES = 0x00000105 + CKR_WRAPPED_KEY_INVALID = 0x00000110 + CKR_WRAPPED_KEY_LEN_RANGE = 0x00000112 + CKR_WRAPPING_KEY_HANDLE_INVALID = 0x00000113 + CKR_WRAPPING_KEY_SIZE_RANGE = 0x00000114 + CKR_WRAPPING_KEY_TYPE_INCONSISTENT = 0x00000115 + CKR_RANDOM_SEED_NOT_SUPPORTED = 0x00000120 + CKR_RANDOM_NO_RNG = 0x00000121 + CKR_DOMAIN_PARAMS_INVALID = 0x00000130 + CKR_BUFFER_TOO_SMALL = 0x00000150 + CKR_SAVED_STATE_INVALID = 0x00000160 + CKR_INFORMATION_SENSITIVE = 0x00000170 + CKR_STATE_UNSAVEABLE = 0x00000180 + CKR_CRYPTOKI_NOT_INITIALIZED = 0x00000190 + CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191 + CKR_MUTEX_BAD = 0x000001A0 + CKR_MUTEX_NOT_LOCKED = 0x000001A1 + CKR_NEW_PIN_MODE = 0x000001B0 + CKR_NEXT_OTP = 0x000001B1 + CKR_FUNCTION_REJECTED = 0x00000200 + CKR_VENDOR_DEFINED = 0x80000000 + CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001 + CKF_OS_LOCKING_OK = 0x00000002 + CKF_DONT_BLOCK = 1 + CKF_NEXT_OTP = 0x00000001 + CKF_EXCLUDE_TIME = 0x00000002 + CKF_EXCLUDE_COUNTER = 0x00000004 + CKF_EXCLUDE_CHALLENGE = 0x00000008 + CKF_EXCLUDE_PIN = 0x00000010 + CKF_USER_FRIENDLY_OTP = 0x00000020 +) diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/error.go b/Godeps/_workspace/src/github.com/miekg/pkcs11/error.go new file mode 100644 index 00000000000..7df0e93a6b5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/error.go @@ -0,0 +1,98 @@ +// Copyright 2013 Miek Gieben. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs11 + +// awk '/#define CKR_/{ print $3":\""$2"\"," }' pkcs11t.h + +var strerror = map[uint]string{ + 0x00000000: "CKR_OK", + 0x00000001: "CKR_CANCEL", + 0x00000002: "CKR_HOST_MEMORY", + 0x00000003: "CKR_SLOT_ID_INVALID", + 0x00000005: "CKR_GENERAL_ERROR", + 0x00000006: "CKR_FUNCTION_FAILED", + 0x00000007: "CKR_ARGUMENTS_BAD", + 0x00000008: "CKR_NO_EVENT", + 0x00000009: "CKR_NEED_TO_CREATE_THREADS", + 0x0000000A: "CKR_CANT_LOCK", + 0x00000010: "CKR_ATTRIBUTE_READ_ONLY", + 0x00000011: "CKR_ATTRIBUTE_SENSITIVE", + 0x00000012: "CKR_ATTRIBUTE_TYPE_INVALID", + 0x00000013: "CKR_ATTRIBUTE_VALUE_INVALID", + 0x00000020: "CKR_DATA_INVALID", + 0x00000021: "CKR_DATA_LEN_RANGE", + 0x00000030: "CKR_DEVICE_ERROR", + 0x00000031: "CKR_DEVICE_MEMORY", + 0x00000032: "CKR_DEVICE_REMOVED", + 0x00000040: "CKR_ENCRYPTED_DATA_INVALID", + 0x00000041: "CKR_ENCRYPTED_DATA_LEN_RANGE", + 0x00000050: "CKR_FUNCTION_CANCELED", + 0x00000051: "CKR_FUNCTION_NOT_PARALLEL", + 0x00000054: "CKR_FUNCTION_NOT_SUPPORTED", + 0x00000060: "CKR_KEY_HANDLE_INVALID", + 0x00000062: "CKR_KEY_SIZE_RANGE", + 0x00000063: "CKR_KEY_TYPE_INCONSISTENT", + 0x00000064: "CKR_KEY_NOT_NEEDED", + 0x00000065: "CKR_KEY_CHANGED", + 0x00000066: "CKR_KEY_NEEDED", + 0x00000067: "CKR_KEY_INDIGESTIBLE", + 0x00000068: "CKR_KEY_FUNCTION_NOT_PERMITTED", + 0x00000069: "CKR_KEY_NOT_WRAPPABLE", + 0x0000006A: "CKR_KEY_UNEXTRACTABLE", + 0x00000070: "CKR_MECHANISM_INVALID", + 0x00000071: "CKR_MECHANISM_PARAM_INVALID", + 0x00000082: "CKR_OBJECT_HANDLE_INVALID", + 0x00000090: "CKR_OPERATION_ACTIVE", + 0x00000091: "CKR_OPERATION_NOT_INITIALIZED", + 0x000000A0: "CKR_PIN_INCORRECT", + 0x000000A1: "CKR_PIN_INVALID", + 0x000000A2: "CKR_PIN_LEN_RANGE", + 0x000000A3: "CKR_PIN_EXPIRED", + 0x000000A4: "CKR_PIN_LOCKED", + 0x000000B0: "CKR_SESSION_CLOSED", + 0x000000B1: "CKR_SESSION_COUNT", + 0x000000B3: "CKR_SESSION_HANDLE_INVALID", + 0x000000B4: "CKR_SESSION_PARALLEL_NOT_SUPPORTED", + 0x000000B5: "CKR_SESSION_READ_ONLY", + 0x000000B6: "CKR_SESSION_EXISTS", + 0x000000B7: "CKR_SESSION_READ_ONLY_EXISTS", + 0x000000B8: "CKR_SESSION_READ_WRITE_SO_EXISTS", + 0x000000C0: "CKR_SIGNATURE_INVALID", + 0x000000C1: "CKR_SIGNATURE_LEN_RANGE", + 0x000000D0: "CKR_TEMPLATE_INCOMPLETE", + 0x000000D1: "CKR_TEMPLATE_INCONSISTENT", + 0x000000E0: "CKR_TOKEN_NOT_PRESENT", + 0x000000E1: "CKR_TOKEN_NOT_RECOGNIZED", + 0x000000E2: "CKR_TOKEN_WRITE_PROTECTED", + 0x000000F0: "CKR_UNWRAPPING_KEY_HANDLE_INVALID", + 0x000000F1: "CKR_UNWRAPPING_KEY_SIZE_RANGE", + 0x000000F2: "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT", + 0x00000100: "CKR_USER_ALREADY_LOGGED_IN", + 0x00000101: "CKR_USER_NOT_LOGGED_IN", + 0x00000102: "CKR_USER_PIN_NOT_INITIALIZED", + 0x00000103: "CKR_USER_TYPE_INVALID", + 0x00000104: "CKR_USER_ANOTHER_ALREADY_LOGGED_IN", + 0x00000105: "CKR_USER_TOO_MANY_TYPES", + 0x00000110: "CKR_WRAPPED_KEY_INVALID", + 0x00000112: "CKR_WRAPPED_KEY_LEN_RANGE", + 0x00000113: "CKR_WRAPPING_KEY_HANDLE_INVALID", + 0x00000114: "CKR_WRAPPING_KEY_SIZE_RANGE", + 0x00000115: "CKR_WRAPPING_KEY_TYPE_INCONSISTENT", + 0x00000120: "CKR_RANDOM_SEED_NOT_SUPPORTED", + 0x00000121: "CKR_RANDOM_NO_RNG", + 0x00000130: "CKR_DOMAIN_PARAMS_INVALID", + 0x00000150: "CKR_BUFFER_TOO_SMALL", + 0x00000160: "CKR_SAVED_STATE_INVALID", + 0x00000170: "CKR_INFORMATION_SENSITIVE", + 0x00000180: "CKR_STATE_UNSAVEABLE", + 0x00000190: "CKR_CRYPTOKI_NOT_INITIALIZED", + 0x00000191: "CKR_CRYPTOKI_ALREADY_INITIALIZED", + 0x000001A0: "CKR_MUTEX_BAD", + 0x000001A1: "CKR_MUTEX_NOT_LOCKED", + 0x000001B0: "CKR_NEW_PIN_MODE", + 0x000001B1: "CKR_NEXT_OTP", + 0x00000200: "CKR_FUNCTION_REJECTED", + 0x80000000: "CKR_VENDOR_DEFINED", +} diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/hsm.db b/Godeps/_workspace/src/github.com/miekg/pkcs11/hsm.db new file mode 100644 index 0000000000000000000000000000000000000000..eb3f10dadcdf6af2416c79bc91280e9f13f41c72 GIT binary patch literal 10240 zcmeHN4RBP|6@KTOx4Z9cHk;ifu;d5w@<$Q~klk!TQV`i>HyHA>5Eeq1N}HceSmh^# zg%Ht^#evp#6s&a+hejx-TI-aSs@Ph^LPc$-N}&Y-8Emam`LVPr6ouM*_r5Iwwa!=_ zEbg1x_kHKQbI;y$-rjS6k{Q$ML*by-xu|DBYgj9lWC=i;tZ9-YC9;p1ePWl15jiF> z1or6|B!3i5l*atIfIBk6B#Aas1AYTe!FncK6<4#-=*Z88-q6C1;POz%@<3mAa8~R5 zr9n?P+!JbB8V)WoRyX-P0iRae==IIk2HR-~Fgv z*dD%UZMfX4Fu2_1qG+>PZ?VRm7eyShDWf1miS)AGb#(=MI)d|q;b1@r!o?EZbD*hq z$`oIdc8Q5r<*V^G`82Pu-p68M0qBj`gDJI*F?~&wzhQ7_&DZ%@qgZFOYczkocWg|Y zp!piTk!mtIva?~;^l)q2{6Xov7_uDen5U}VH`se&Yb@EdUY6#7k9T`oQ*DE%sYR>v zwG_v`=|2y>z8cTW`heCrv%bEVXXc}yL|=tgRqwB2femUgKe(_fJnutoN{SlL=*Y-` zCD9o4%;-Ru^j=qLg&*qLpney%fyv=;KqNQnFR8Wu$%WJAC+>BSU$~wNr>vmSTyd_@vEWG4OBsGMC%fs4# zx%l`;`lm$a*)4v>GZ4?fmm&j*C?TL^V9^4-&tp~ud?~_@2N};mJOh#`lW*|Luu7tL z=>)w_n`tZUrX%z?Jxvi>Of3|mR@y)wsw5{BQ8uNKou!Z$u8B2 z-K7(oQxIuQiLNn@(@DZuotVeyL@w5eWwcQS6>yX;cNdvt06;9%6;PlP94VeqzOHD` z(@AHpPNW>>OaaU`%fLFmlFfdaMFs=l2Ols&$}-6+0_2Ynm^WNtZl=JT41rp@Kzo`% z+c1G04uNe$1)7EkR8s{iDFO}20)uveWQ!tVl0chP=q-r`SyjOzr0xWxtg^_>LIhPH zDp56=gxGEr*l7?b$;^iWq{^xcJYY1-szDX;B8wU5G`mY?0i4FKcn0DbxJomiCdily zkj)SCOZomk6V^-YO#Wfm14rN_ypKjq$2=U16L^yTN2(RAp36)O8j~wF-(hP?L0ul4{cp2voaHgP(Wwd4p*n4oREJJGKpDoVMFE?VrZamaA>G83t1JlG^E0+&y*Ou!J#c*`xk7IQHR5SF>=1?RdGuE+OW%lovJ+vWHd*bMU1I5Rr z+%#|c@H1~KnEc?_=B$&;4yLrs2|eJy(~#)aiss&tcyq=R%Ci^hew_G*Hp}vdGe>@Y z=7u%f54FR}6?d&#-G8>#9BJ-9_s!n4;XjEyeB&(#UbruGeAnLIcYgD7ZSEVER@>-x z6MV1#z_P9hLYr5gtLtB#A+6-&KMndN=!fH2j#F_l-imASe*6(WgTKZ7_$NGtXNf3@ zGN^z`=~|jfGbu>#M1NE9+vl2rsl)kCC1L@{JF<7@wOQZWxbApI>4~?x{|1NKt6CR- zWwP(-)29|4>TUemU!24Ib4HactlR%$?VJ0)o3wpb!uZGTbqty0o}=CFo^^2Y)DbaX z`Ny2nJp&`Yz3I6}ZLh4@;r}4(-Ha`ni+?rHdtlxE((A2#`%;XfhVHy|Tl%;=mhKvO z>b+b1Db8sP2XD%*q4JFrcmI8Ia+Xm7R-W`lbF@C?YfQ)LQ*=%J@de6~&CFPVV&_k+ z23d2M#3~f(CCZu`lSPd(=W&@AoOVdbXPgx&99*T;k=#I1*cL=Bh*3}rxhZRgU@qcX z?x7o$QH--n#k8YiT8m^Zj&T{xV`AJ4=CLuJ0OoNqZUl3Q&ZRYy>g3$QzTT#~V$^Oe z<&;Mion+;R#cg5=R*Sw6#mHQy2LL%_#`~l^n8*GGfXSGHKAeX=Y^J}N?cKkFn_(Vq z!zb}M+=qwpH9UcD<9RZWl^mq8(*PGuATKr0ESgK5w2+oT-{(3U{*Rs82tkw0nCfuC%msWKn)>;+~=8DE|d+qGH&MhReB zT(Ghc!}hjOEMyk^KTa-BoJo<<3T)_=h-EA@VRd8>&oRl!20z~%N3lR4DmspgIsjse z1@4KR0uD4Hkham2^lREfudq|Wx9Ds%&GB12 z1D`enVr=9PJ0|3#C5JL%gW!s +#include +#include +#include +#include "pkcs11.h" + +struct ctx { + lt_dlhandle handle; + CK_FUNCTION_LIST_PTR sym; +}; + +// New initializes a ctx and fills the symbol table. +struct ctx *New(const char *module) +{ + if (lt_dlinit() != 0) { + return NULL; + } + CK_C_GetFunctionList list; + struct ctx *c = calloc(1, sizeof(struct ctx)); + c->handle = lt_dlopen(module); + if (c->handle == NULL) { + free(c); + return NULL; + } + list = (CK_C_GetFunctionList) lt_dlsym(c->handle, "C_GetFunctionList"); + if (list == NULL) { + free(c); + return NULL; + } + list(&c->sym); + return c; +} + +// Destroy cleans up a ctx. +void Destroy(struct ctx *c) +{ + if (!c) { + return; + } + if (c->handle == NULL) { + return; + } + if (lt_dlclose(c->handle) < 0) { + return; + } + lt_dlexit(); + free(c); +} + +CK_RV Initialize(struct ctx * c, CK_VOID_PTR initArgs) +{ + return c->sym->C_Initialize(initArgs); +} + +CK_RV Finalize(struct ctx * c) +{ + return c->sym->C_Finalize(NULL); +} + +CK_RV GetInfo(struct ctx * c, CK_INFO_PTR info) +{ + return c->sym->C_GetInfo(info); +} + +CK_RV GetSlotList(struct ctx * c, CK_BBOOL tokenPresent, + CK_ULONG_PTR * slotList, CK_ULONG_PTR ulCount) +{ + CK_RV e = c->sym->C_GetSlotList(tokenPresent, NULL, ulCount); + if (e != CKR_OK) { + return e; + } + *slotList = calloc(*ulCount, sizeof(CK_SLOT_ID)); + e = c->sym->C_GetSlotList(tokenPresent, *slotList, ulCount); + return e; +} + +CK_RV GetSlotInfo(struct ctx * c, CK_ULONG slotID, CK_SLOT_INFO_PTR info) +{ + CK_RV e = c->sym->C_GetSlotInfo((CK_SLOT_ID) slotID, info); + return e; +} + +CK_RV GetTokenInfo(struct ctx * c, CK_ULONG slotID, CK_TOKEN_INFO_PTR info) +{ + CK_RV e = c->sym->C_GetTokenInfo((CK_SLOT_ID) slotID, info); + return e; +} + +CK_RV GetMechanismList(struct ctx * c, CK_ULONG slotID, + CK_ULONG_PTR * mech, CK_ULONG_PTR mechlen) +{ + CK_RV e = + c->sym->C_GetMechanismList((CK_SLOT_ID) slotID, NULL, mechlen); + if (e != CKR_OK) { + return e; + } + *mech = calloc(*mechlen, sizeof(CK_MECHANISM_TYPE)); + e = c->sym->C_GetMechanismList((CK_SLOT_ID) slotID, + (CK_MECHANISM_TYPE_PTR) * mech, mechlen); + return e; +} + +CK_RV GetMechanismInfo(struct ctx * c, CK_ULONG slotID, CK_MECHANISM_TYPE mech, + CK_MECHANISM_INFO_PTR info) +{ + CK_RV e = c->sym->C_GetMechanismInfo((CK_SLOT_ID) slotID, mech, info); + return e; +} + +CK_RV InitToken(struct ctx * c, CK_ULONG slotID, char *pin, CK_ULONG pinlen, + char *label) +{ + CK_RV e = + c->sym->C_InitToken((CK_SLOT_ID) slotID, (CK_UTF8CHAR_PTR) pin, + pinlen, (CK_UTF8CHAR_PTR) label); + return e; +} + +CK_RV InitPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *pin, CK_ULONG pinlen) +{ + CK_RV e = c->sym->C_InitPIN(sh, (CK_UTF8CHAR_PTR) pin, pinlen); + return e; +} + +CK_RV SetPIN(struct ctx * c, CK_SESSION_HANDLE sh, char *oldpin, + CK_ULONG oldpinlen, char *newpin, CK_ULONG newpinlen) +{ + CK_RV e = c->sym->C_SetPIN(sh, (CK_UTF8CHAR_PTR) oldpin, oldpinlen, + (CK_UTF8CHAR_PTR) newpin, newpinlen); + return e; +} + +CK_RV OpenSession(struct ctx * c, CK_ULONG slotID, CK_ULONG flags, + CK_SESSION_HANDLE_PTR session) +{ + CK_RV e = + c->sym->C_OpenSession((CK_SLOT_ID) slotID, (CK_FLAGS) flags, NULL, + NULL, session); + return e; +} + +CK_RV CloseSession(struct ctx * c, CK_SESSION_HANDLE session) +{ + CK_RV e = c->sym->C_CloseSession(session); + return e; +} + +CK_RV CloseAllSessions(struct ctx * c, CK_ULONG slotID) +{ + CK_RV e = c->sym->C_CloseAllSessions(slotID); + return e; +} + +CK_RV GetSessionInfo(struct ctx * c, CK_SESSION_HANDLE session, + CK_SESSION_INFO_PTR info) +{ + CK_RV e = c->sym->C_GetSessionInfo(session, info); + return e; +} + +CK_RV GetOperationState(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR * state, CK_ULONG_PTR statelen) +{ + CK_RV rv = c->sym->C_GetOperationState(session, NULL, statelen); + if (rv != CKR_OK) { + return rv; + } + *state = calloc(*statelen, sizeof(CK_BYTE)); + if (*state == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_GetOperationState(session, *state, statelen); + return rv; +} + +CK_RV SetOperationState(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR state, CK_ULONG statelen, + CK_OBJECT_HANDLE encryptkey, CK_OBJECT_HANDLE authkey) +{ + return c->sym->C_SetOperationState(session, state, statelen, encryptkey, + authkey); +} + +CK_RV Login(struct ctx *c, CK_SESSION_HANDLE session, CK_USER_TYPE userType, + char *pin, CK_ULONG pinLen) +{ + CK_RV e = + c->sym->C_Login(session, userType, (CK_UTF8CHAR_PTR) pin, pinLen); + return e; +} + +CK_RV Logout(struct ctx * c, CK_SESSION_HANDLE session) +{ + CK_RV e = c->sym->C_Logout(session); + return e; +} + +CK_RV CreateObject(struct ctx * c, CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount, + CK_OBJECT_HANDLE_PTR obj) +{ + CK_RV e = c->sym->C_CreateObject(session, temp, tempCount, obj); + return e; +} + +CK_RV CopyObject(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, + CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount, + CK_OBJECT_HANDLE_PTR obj) +{ + CK_RV e = c->sym->C_CopyObject(session, o, temp, tempCount, obj); + return e; +} + +CK_RV DestroyObject(struct ctx * c, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object) +{ + CK_RV e = c->sym->C_DestroyObject(session, object); + return e; +} + +CK_RV GetObjectSize(struct ctx * c, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, CK_ULONG_PTR size) +{ + CK_RV e = c->sym->C_GetObjectSize(session, object, size); + return e; +} + +CK_RV GetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp, + CK_ULONG templen) +{ + // Call for the first time, check the returned ulValue in the attributes, then + // allocate enough space and try again. + CK_RV e = c->sym->C_GetAttributeValue(session, object, temp, templen); + if (e != CKR_OK) { + return e; + } + CK_ULONG i; + for (i = 0; i < templen; i++) { + if ((CK_LONG) temp[i].ulValueLen == -1) { + // either access denied or no such object + continue; + } + temp[i].pValue = calloc(temp[i].ulValueLen, sizeof(CK_BYTE)); + } + e = c->sym->C_GetAttributeValue(session, object, temp, templen); + return e; +} + +CK_RV SetAttributeValue(struct ctx * c, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR temp, + CK_ULONG templen) +{ + CK_RV e = c->sym->C_SetAttributeValue(session, object, temp, templen); + return e; +} + +CK_RV FindObjectsInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR temp, CK_ULONG tempCount) +{ + CK_RV e = c->sym->C_FindObjectsInit(session, temp, tempCount); + return e; +} + +CK_RV FindObjects(struct ctx * c, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE_PTR * obj, CK_ULONG max, + CK_ULONG_PTR objCount) +{ + *obj = calloc(max, sizeof(CK_OBJECT_HANDLE)); + CK_RV e = c->sym->C_FindObjects(session, *obj, max, objCount); + return e; +} + +CK_RV FindObjectsFinal(struct ctx * c, CK_SESSION_HANDLE session) +{ + CK_RV e = c->sym->C_FindObjectsFinal(session); + return e; +} + +CK_RV EncryptInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) +{ + CK_RV e = c->sym->C_EncryptInit(session, mechanism, key); + return e; +} + +CK_RV Encrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, + CK_ULONG mlen, CK_BYTE_PTR * enc, CK_ULONG_PTR enclen) +{ + CK_RV rv = c->sym->C_Encrypt(session, message, mlen, NULL, enclen); + if (rv != CKR_OK) { + return rv; + } + *enc = calloc(*enclen, sizeof(CK_BYTE)); + if (*enc == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_Encrypt(session, message, mlen, *enc, enclen); + return rv; +} + +CK_RV EncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR plain, CK_ULONG plainlen, CK_BYTE_PTR * cipher, + CK_ULONG_PTR cipherlen) +{ + CK_RV rv = + c->sym->C_EncryptUpdate(session, plain, plainlen, NULL, cipherlen); + if (rv != CKR_OK) { + return rv; + } + *cipher = calloc(*cipherlen, sizeof(CK_BYTE)); + if (*cipher == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_EncryptUpdate(session, plain, plainlen, *cipher, + cipherlen); + return rv; +} + +CK_RV EncryptFinal(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR * cipher, CK_ULONG_PTR cipherlen) +{ + CK_RV rv = c->sym->C_EncryptFinal(session, NULL, cipherlen); + if (rv != CKR_OK) { + return rv; + } + *cipher = calloc(*cipherlen, sizeof(CK_BYTE)); + if (*cipher == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_EncryptFinal(session, *cipher, cipherlen); + return rv; +} + +CK_RV DecryptInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) +{ + CK_RV e = c->sym->C_DecryptInit(session, mechanism, key); + return e; +} + +CK_RV Decrypt(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR cypher, + CK_ULONG clen, CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen) +{ + CK_RV e = c->sym->C_Decrypt(session, cypher, clen, NULL, plainlen); + if (e != CKR_OK) { + return e; + } + *plain = calloc(*plainlen, sizeof(CK_BYTE)); + if (*plain == NULL) { + return CKR_HOST_MEMORY; + } + e = c->sym->C_Decrypt(session, cypher, clen, *plain, plainlen); + return e; +} + +CK_RV DecryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR cipher, CK_ULONG cipherlen, CK_BYTE_PTR * part, + CK_ULONG_PTR partlen) +{ + CK_RV rv = + c->sym->C_DecryptUpdate(session, cipher, cipherlen, NULL, partlen); + if (rv != CKR_OK) { + return rv; + } + *part = calloc(*partlen, sizeof(CK_BYTE)); + if (*part == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DecryptUpdate(session, cipher, cipherlen, *part, + partlen); + return rv; +} + +CK_RV DecryptFinal(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR * plain, CK_ULONG_PTR plainlen) +{ + CK_RV rv = c->sym->C_DecryptFinal(session, NULL, plainlen); + if (rv != CKR_OK) { + return rv; + } + *plain = calloc(*plainlen, sizeof(CK_BYTE)); + if (*plain == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DecryptFinal(session, *plain, plainlen); + return rv; +} + +CK_RV DigestInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism) +{ + CK_RV e = c->sym->C_DigestInit(session, mechanism); + return e; +} + +CK_RV Digest(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, + CK_ULONG mlen, CK_BYTE_PTR * hash, CK_ULONG_PTR hashlen) +{ + CK_RV rv = c->sym->C_Digest(session, message, mlen, NULL, hashlen); + if (rv != CKR_OK) { + return rv; + } + *hash = calloc(*hashlen, sizeof(CK_BYTE)); + if (*hash == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_Digest(session, message, mlen, *hash, hashlen); + return rv; +} + +CK_RV DigestUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR message, CK_ULONG mlen) +{ + CK_RV rv = c->sym->C_DigestUpdate(session, message, mlen); + return rv; +} + +CK_RV DigestKey(struct ctx * c, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key) +{ + CK_RV rv = c->sym->C_DigestKey(session, key); + return rv; +} + +CK_RV DigestFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * hash, + CK_ULONG_PTR hashlen) +{ + CK_RV rv = c->sym->C_DigestFinal(session, NULL, hashlen); + if (rv != CKR_OK) { + return rv; + } + *hash = calloc(*hashlen, sizeof(CK_BYTE)); + if (*hash == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DigestFinal(session, *hash, hashlen); + return rv; +} + +CK_RV SignInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) +{ + CK_RV e = c->sym->C_SignInit(session, mechanism, key); + return e; +} + +CK_RV Sign(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, + CK_ULONG mlen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen) +{ + CK_RV rv = c->sym->C_Sign(session, message, mlen, NULL, siglen); + if (rv != CKR_OK) { + return rv; + } + *sig = calloc(*siglen, sizeof(CK_BYTE)); + if (*sig == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_Sign(session, message, mlen, *sig, siglen); + return rv; +} + +CK_RV SignUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR message, CK_ULONG mlen) +{ + CK_RV rv = c->sym->C_SignUpdate(session, message, mlen); + return rv; +} + +CK_RV SignFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR * sig, + CK_ULONG_PTR siglen) +{ + CK_RV rv = c->sym->C_SignFinal(session, NULL, siglen); + if (rv != CKR_OK) { + return rv; + } + *sig = calloc(*siglen, sizeof(CK_BYTE)); + if (*sig == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_SignFinal(session, *sig, siglen); + return rv; +} + +CK_RV SignRecoverInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key) +{ + CK_RV rv = c->sym->C_SignRecoverInit(session, mech, key); + return rv; +} + +CK_RV SignRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR data, + CK_ULONG datalen, CK_BYTE_PTR * sig, CK_ULONG_PTR siglen) +{ + CK_RV rv = c->sym->C_SignRecover(session, data, datalen, NULL, siglen); + if (rv != CKR_OK) { + return rv; + } + *sig = calloc(*siglen, sizeof(CK_BYTE)); + if (*sig == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_SignRecover(session, data, datalen, *sig, siglen); + return rv; +} + +CK_RV VerifyInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key) +{ + CK_RV rv = c->sym->C_VerifyInit(session, mech, key); + return rv; +} + +CK_RV Verify(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR message, + CK_ULONG mesglen, CK_BYTE_PTR sig, CK_ULONG siglen) +{ + CK_RV rv = c->sym->C_Verify(session, message, mesglen, sig, siglen); + return rv; +} + +CK_RV VerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR part, CK_ULONG partlen) +{ + CK_RV rv = c->sym->C_VerifyUpdate(session, part, partlen); + return rv; +} + +CK_RV VerifyFinal(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig, + CK_ULONG siglen) +{ + CK_RV rv = c->sym->C_VerifyFinal(session, sig, siglen); + return rv; +} + +CK_RV VerifyRecoverInit(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE key) +{ + CK_RV rv = c->sym->C_VerifyRecoverInit(session, mech, key); + return rv; +} + +CK_RV VerifyRecover(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR sig, + CK_ULONG siglen, CK_BYTE_PTR * data, CK_ULONG_PTR datalen) +{ + CK_RV rv = c->sym->C_VerifyRecover(session, sig, siglen, NULL, datalen); + if (rv != CKR_OK) { + return rv; + } + *data = calloc(*datalen, sizeof(CK_BYTE)); + if (*data == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_VerifyRecover(session, sig, siglen, *data, datalen); + return rv; +} + +CK_RV DigestEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc, + CK_ULONG_PTR enclen) +{ + CK_RV rv = + c->sym->C_DigestEncryptUpdate(session, part, partlen, NULL, enclen); + if (rv != CKR_OK) { + return rv; + } + *enc = calloc(*enclen, sizeof(CK_BYTE)); + if (*enc == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DigestEncryptUpdate(session, part, partlen, *enc, + enclen); + return rv; +} + +CK_RV DecryptDigestUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR cipher, CK_ULONG cipherlen, + CK_BYTE_PTR * part, CK_ULONG_PTR partlen) +{ + CK_RV rv = + c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, NULL, + partlen); + if (rv != CKR_OK) { + return rv; + } + *part = calloc(*partlen, sizeof(CK_BYTE)); + if (*part == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DecryptDigestUpdate(session, cipher, cipherlen, *part, + partlen); + return rv; +} + +CK_RV SignEncryptUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR part, CK_ULONG partlen, CK_BYTE_PTR * enc, + CK_ULONG_PTR enclen) +{ + CK_RV rv = + c->sym->C_SignEncryptUpdate(session, part, partlen, NULL, enclen); + if (rv != CKR_OK) { + return rv; + } + *enc = calloc(*enclen, sizeof(CK_BYTE)); + if (*enc == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_SignEncryptUpdate(session, part, partlen, *enc, enclen); + return rv; +} + +CK_RV DecryptVerifyUpdate(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR cipher, CK_ULONG cipherlen, + CK_BYTE_PTR * part, CK_ULONG_PTR partlen) +{ + CK_RV rv = + c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, NULL, + partlen); + if (rv != CKR_OK) { + return rv; + } + *part = calloc(*partlen, sizeof(CK_BYTE)); + if (*part == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_DecryptVerifyUpdate(session, cipher, cipherlen, *part, + partlen); + return rv; +} + +CK_RV GenerateKey(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR temp, + CK_ULONG tempCount, CK_OBJECT_HANDLE_PTR key) +{ + CK_RV e = + c->sym->C_GenerateKey(session, mechanism, temp, tempCount, key); + return e; +} + +CK_RV GenerateKeyPair(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_ATTRIBUTE_PTR pub, + CK_ULONG pubCount, CK_ATTRIBUTE_PTR priv, + CK_ULONG privCount, CK_OBJECT_HANDLE_PTR pubkey, + CK_OBJECT_HANDLE_PTR privkey) +{ + CK_RV e = + c->sym->C_GenerateKeyPair(session, mechanism, pub, pubCount, priv, + privCount, + pubkey, privkey); + return e; +} + +CK_RV WrapKey(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE wrappingkey, + CK_OBJECT_HANDLE key, CK_BYTE_PTR * wrapped, + CK_ULONG_PTR wrappedlen) +{ + CK_RV rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, NULL, + wrappedlen); + if (rv != CKR_OK) { + return rv; + } + *wrapped = calloc(*wrappedlen, sizeof(CK_BYTE)); + if (*wrapped == NULL) { + return CKR_HOST_MEMORY; + } + rv = c->sym->C_WrapKey(session, mechanism, wrappingkey, key, *wrapped, + wrappedlen); + return rv; +} + +CK_RV DeriveKey(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE basekey, + CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key) +{ + CK_RV e = c->sym->C_DeriveKey(session, mech, basekey, a, alen, key); + return e; +} + +CK_RV UnwrapKey(struct ctx * c, CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mech, CK_OBJECT_HANDLE unwrappingkey, + CK_BYTE_PTR wrappedkey, CK_ULONG wrappedkeylen, + CK_ATTRIBUTE_PTR a, CK_ULONG alen, CK_OBJECT_HANDLE_PTR key) +{ + CK_RV e = c->sym->C_UnwrapKey(session, mech, unwrappingkey, wrappedkey, + wrappedkeylen, a, alen, key); + return e; +} + +CK_RV SeedRandom(struct ctx * c, CK_SESSION_HANDLE session, CK_BYTE_PTR seed, + CK_ULONG seedlen) +{ + CK_RV e = c->sym->C_SeedRandom(session, seed, seedlen); + return e; +} + +CK_RV GenerateRandom(struct ctx * c, CK_SESSION_HANDLE session, + CK_BYTE_PTR * rand, CK_ULONG length) +{ + *rand = calloc(length, sizeof(CK_BYTE)); + if (*rand == NULL) { + return CKR_HOST_MEMORY; + } + CK_RV e = c->sym->C_GenerateRandom(session, *rand, length); + return e; +} + +CK_RV WaitForSlotEvent(struct ctx * c, CK_FLAGS flags, CK_ULONG_PTR slot) +{ + CK_RV e = + c->sym->C_WaitForSlotEvent(flags, (CK_SLOT_ID_PTR) slot, NULL); + return e; +} +*/ +import "C" +import "strings" + +import "unsafe" + +// Ctx contains the current pkcs11 context. +type Ctx struct { + ctx *C.struct_ctx +} + +// New creates a new context and initializes the module/library for use. +func New(module string) *Ctx { + c := new(Ctx) + mod := C.CString(module) + defer C.free(unsafe.Pointer(mod)) + c.ctx = C.New(mod) + if c.ctx == nil { + return nil + } + return c +} + +// Destroy unloads the module/library and frees any remaining memory. +func (c *Ctx) Destroy() { + if c == nil || c.ctx == nil { + return + } + C.Destroy(c.ctx) + c.ctx = nil +} + +/* Initialize initializes the Cryptoki library. */ +func (c *Ctx) Initialize() error { + args := &C.CK_C_INITIALIZE_ARGS{nil, nil, nil, nil, C.CKF_OS_LOCKING_OK, nil} + e := C.Initialize(c.ctx, C.CK_VOID_PTR(args)) + return toError(e) +} + +/* Finalize indicates that an application is done with the Cryptoki library. */ +func (c *Ctx) Finalize() error { + if c.ctx == nil { + return toError(CKR_CRYPTOKI_NOT_INITIALIZED) + } + e := C.Finalize(c.ctx) + return toError(e) +} + +/* GetInfo returns general information about Cryptoki. */ +func (c *Ctx) GetInfo() (Info, error) { + var p C.CK_INFO + e := C.GetInfo(c.ctx, C.CK_INFO_PTR(&p)) + i := Info{ + CryptokiVersion: toVersion(p.cryptokiVersion), + ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.manufacturerID[0]), 32)), " "), + Flags: uint(p.flags), + LibraryDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&p.libraryDescription[0]), 32)), " "), + LibraryVersion: toVersion(p.libraryVersion), + } + return i, toError(e) +} + +/* GetSlotList obtains a list of slots in the system. */ +func (c *Ctx) GetSlotList(tokenPresent bool) ([]uint, error) { + var ( + slotList C.CK_ULONG_PTR + ulCount C.CK_ULONG + ) + e := C.GetSlotList(c.ctx, cBBool(tokenPresent), &slotList, &ulCount) + if toError(e) != nil { + return nil, toError(e) + } + l := toList(slotList, ulCount) + return l, nil +} + +/* GetSlotInfo obtains information about a particular slot in the system. */ +func (c *Ctx) GetSlotInfo(slotID uint) (SlotInfo, error) { + var csi C.CK_SLOT_INFO + e := C.GetSlotInfo(c.ctx, C.CK_ULONG(slotID), &csi) + s := SlotInfo{ + SlotDescription: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.slotDescription[0]), 64)), " "), + ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&csi.manufacturerID[0]), 32)), " "), + Flags: uint(csi.flags), + HardwareVersion: toVersion(csi.hardwareVersion), + FirmwareVersion: toVersion(csi.firmwareVersion), + } + return s, toError(e) +} + +// GetTokenInfo obtains information about a particular token +// in the system. +func (c *Ctx) GetTokenInfo(slotID uint) (TokenInfo, error) { + var cti C.CK_TOKEN_INFO + e := C.GetTokenInfo(c.ctx, C.CK_ULONG(slotID), &cti) + s := TokenInfo{ + Label: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.label[0]), 32)), " "), + ManufacturerID: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.manufacturerID[0]), 32)), " "), + Model: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.model[0]), 16)), " "), + SerialNumber: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.serialNumber[0]), 16)), " "), + Flags: uint(cti.flags), + MaxSessionCount: uint(cti.ulMaxSessionCount), + SessionCount: uint(cti.ulSessionCount), + MaxRwSessionCount: uint(cti.ulMaxRwSessionCount), + RwSessionCount: uint(cti.ulRwSessionCount), + MaxPinLen: uint(cti.ulMaxPinLen), + MinPinLen: uint(cti.ulMinPinLen), + TotalPublicMemory: uint(cti.ulTotalPublicMemory), + FreePublicMemory: uint(cti.ulFreePublicMemory), + TotalPrivateMemory: uint(cti.ulTotalPrivateMemory), + FreePrivateMemory: uint(cti.ulFreePrivateMemory), + HardwareVersion: toVersion(cti.hardwareVersion), + FirmwareVersion: toVersion(cti.firmwareVersion), + UTCTime: strings.TrimRight(string(C.GoBytes(unsafe.Pointer(&cti.utcTime[0]), 16)), " "), + } + return s, toError(e) +} + +/* GetMechanismList obtains a list of mechanism types supported by a token. */ +func (c *Ctx) GetMechanismList(slotID uint) ([]*Mechanism, error) { + var ( + mech C.CK_ULONG_PTR // in pkcs#11 we're all CK_ULONGs \o/ + mechlen C.CK_ULONG + ) + e := C.GetMechanismList(c.ctx, C.CK_ULONG(slotID), &mech, &mechlen) + if toError(e) != nil { + return nil, toError(e) + } + // Although the function returns only type, cast them back into real + // attributes as this is used in other functions. + m := make([]*Mechanism, int(mechlen)) + for i, typ := range toList(mech, mechlen) { + m[i] = NewMechanism(typ, nil) + } + return m, nil +} + +// GetMechanismInfo obtains information about a particular +// mechanism possibly supported by a token. +func (c *Ctx) GetMechanismInfo(slotID uint, m []*Mechanism) (MechanismInfo, error) { + var cm C.CK_MECHANISM_INFO + e := C.GetMechanismInfo(c.ctx, C.CK_ULONG(slotID), C.CK_MECHANISM_TYPE(m[0].Mechanism), + C.CK_MECHANISM_INFO_PTR(&cm)) + mi := MechanismInfo{ + MinKeySize: uint(cm.ulMinKeySize), + MaxKeySize: uint(cm.ulMaxKeySize), + Flags: uint(cm.flags), + } + return mi, toError(e) +} + +// InitToken initializes a token. The label must be 32 characters +// long, it is blank padded if it is not. If it is longer it is capped +// to 32 characters. +func (c *Ctx) InitToken(slotID uint, pin string, label string) error { + p := C.CString(pin) + defer C.free(unsafe.Pointer(p)) + ll := len(label) + for ll < 32 { + label += " " + ll++ + } + l := C.CString(label[:32]) + defer C.free(unsafe.Pointer(l)) + e := C.InitToken(c.ctx, C.CK_ULONG(slotID), p, C.CK_ULONG(len(pin)), l) + return toError(e) +} + +/* InitPIN initializes the normal user's PIN. */ +func (c *Ctx) InitPIN(sh SessionHandle, pin string) error { + p := C.CString(pin) + defer C.free(unsafe.Pointer(p)) + e := C.InitPIN(c.ctx, C.CK_SESSION_HANDLE(sh), p, C.CK_ULONG(len(pin))) + return toError(e) +} + +/* SetPIN modifies the PIN of the user who is logged in. */ +func (c *Ctx) SetPIN(sh SessionHandle, oldpin string, newpin string) error { + old := C.CString(oldpin) + defer C.free(unsafe.Pointer(old)) + new := C.CString(newpin) + defer C.free(unsafe.Pointer(new)) + e := C.SetPIN(c.ctx, C.CK_SESSION_HANDLE(sh), old, C.CK_ULONG(len(oldpin)), new, C.CK_ULONG(len(newpin))) + return toError(e) +} + +/* OpenSession opens a session between an application and a token. */ +func (c *Ctx) OpenSession(slotID uint, flags uint) (SessionHandle, error) { + var s C.CK_SESSION_HANDLE + e := C.OpenSession(c.ctx, C.CK_ULONG(slotID), C.CK_ULONG(flags), C.CK_SESSION_HANDLE_PTR(&s)) + return SessionHandle(s), toError(e) +} + +/* CloseSession closes a session between an application and a token. */ +func (c *Ctx) CloseSession(sh SessionHandle) error { + if c.ctx == nil { + return toError(CKR_CRYPTOKI_NOT_INITIALIZED) + } + e := C.CloseSession(c.ctx, C.CK_SESSION_HANDLE(sh)) + return toError(e) +} + +/* CloseAllSessions closes all sessions with a token. */ +func (c *Ctx) CloseAllSessions(slotID uint) error { + if c.ctx == nil { + return toError(CKR_CRYPTOKI_NOT_INITIALIZED) + } + e := C.CloseAllSessions(c.ctx, C.CK_ULONG(slotID)) + return toError(e) +} + +/* GetSessionInfo obtains information about the session. */ +func (c *Ctx) GetSessionInfo(sh SessionHandle) (SessionInfo, error) { + var csi C.CK_SESSION_INFO + e := C.GetSessionInfo(c.ctx, C.CK_SESSION_HANDLE(sh), &csi) + s := SessionInfo{SlotID: uint(csi.slotID), + State: uint(csi.state), + Flags: uint(csi.flags), + DeviceError: uint(csi.ulDeviceError), + } + return s, toError(e) +} + +/* GetOperationState obtains the state of the cryptographic operation in a session. */ +func (c *Ctx) GetOperationState(sh SessionHandle) ([]byte, error) { + var ( + state C.CK_BYTE_PTR + statelen C.CK_ULONG + ) + e := C.GetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), &state, &statelen) + if toError(e) != nil { + return nil, toError(e) + } + b := C.GoBytes(unsafe.Pointer(state), C.int(statelen)) + C.free(unsafe.Pointer(state)) + return b, nil +} + +/* SetOperationState restores the state of the cryptographic operation in a session. */ +func (c *Ctx) SetOperationState(sh SessionHandle, state []byte, encryptKey, authKey ObjectHandle) error { + e := C.SetOperationState(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&state[0])), + C.CK_ULONG(len(state)), C.CK_OBJECT_HANDLE(encryptKey), C.CK_OBJECT_HANDLE(authKey)) + return toError(e) +} + +/* Login logs a user into a token. */ +func (c *Ctx) Login(sh SessionHandle, userType uint, pin string) error { + p := C.CString(pin) + defer C.free(unsafe.Pointer(p)) + e := C.Login(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_USER_TYPE(userType), p, C.CK_ULONG(len(pin))) + return toError(e) +} + +/* Logout logs a user out from a token. */ +func (c *Ctx) Logout(sh SessionHandle) error { + if c.ctx == nil { + return toError(CKR_CRYPTOKI_NOT_INITIALIZED) + } + e := C.Logout(c.ctx, C.CK_SESSION_HANDLE(sh)) + return toError(e) +} + +/* CreateObject creates a new object. */ +func (c *Ctx) CreateObject(sh SessionHandle, temp []*Attribute) (ObjectHandle, error) { + var obj C.CK_OBJECT_HANDLE + t, tcount := cAttributeList(temp) + e := C.CreateObject(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj)) + e1 := toError(e) + if e1 == nil { + return ObjectHandle(obj), nil + } + return 0, e1 +} + +/* CopyObject copies an object, creating a new object for the copy. */ +func (c *Ctx) CopyObject(sh SessionHandle, o ObjectHandle, temp []*Attribute) (ObjectHandle, error) { + var obj C.CK_OBJECT_HANDLE + t, tcount := cAttributeList(temp) + + e := C.CopyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), t, tcount, C.CK_OBJECT_HANDLE_PTR(&obj)) + e1 := toError(e) + if e1 == nil { + return ObjectHandle(obj), nil + } + return 0, e1 +} + +/* DestroyObject destroys an object. */ +func (c *Ctx) DestroyObject(sh SessionHandle, oh ObjectHandle) error { + e := C.DestroyObject(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh)) + return toError(e) +} + +/* GetObjectSize gets the size of an object in bytes. */ +func (c *Ctx) GetObjectSize(sh SessionHandle, oh ObjectHandle) (uint, error) { + var size C.CK_ULONG + e := C.GetObjectSize(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(oh), &size) + return uint(size), toError(e) +} + +/* GetAttributeValue obtains the value of one or more object attributes. */ +func (c *Ctx) GetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) ([]*Attribute, error) { + // copy the attribute list and make all the values nil, so that + // the C function can (allocate) fill them in + pa := make([]C.CK_ATTRIBUTE, len(a)) + for i := 0; i < len(a); i++ { + pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type) + } + e := C.GetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), C.CK_ATTRIBUTE_PTR(&pa[0]), C.CK_ULONG(len(a))) + if toError(e) != nil { + return nil, toError(e) + } + a1 := make([]*Attribute, len(a)) + for i, c := range pa { + x := new(Attribute) + x.Type = uint(c._type) + if int(c.ulValueLen) != -1 { + x.Value = C.GoBytes(unsafe.Pointer(c.pValue), C.int(c.ulValueLen)) + C.free(unsafe.Pointer(c.pValue)) + } + a1[i] = x + } + return a1, nil +} + +/* SetAttributeValue modifies the value of one or more object attributes */ +func (c *Ctx) SetAttributeValue(sh SessionHandle, o ObjectHandle, a []*Attribute) error { + pa, palen := cAttributeList(a) + e := C.SetAttributeValue(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(o), pa, palen) + return toError(e) +} + +// FindObjectsInit initializes a search for token and session +// objects that match a template. +func (c *Ctx) FindObjectsInit(sh SessionHandle, temp []*Attribute) error { + t, tcount := cAttributeList(temp) + e := C.FindObjectsInit(c.ctx, C.CK_SESSION_HANDLE(sh), t, tcount) + return toError(e) +} + +// FindObjects continues a search for token and session +// objects that match a template, obtaining additional object +// handles. The returned boolean indicates if the list would +// have been larger than max. +func (c *Ctx) FindObjects(sh SessionHandle, max int) ([]ObjectHandle, bool, error) { + var ( + objectList C.CK_OBJECT_HANDLE_PTR + ulCount C.CK_ULONG + ) + e := C.FindObjects(c.ctx, C.CK_SESSION_HANDLE(sh), &objectList, C.CK_ULONG(max), &ulCount) + if toError(e) != nil { + return nil, false, toError(e) + } + l := toList(C.CK_ULONG_PTR(unsafe.Pointer(objectList)), ulCount) + // Make again a new list of the correct type. + // This is copying data, but this is not an often used function. + o := make([]ObjectHandle, len(l)) + for i, v := range l { + o[i] = ObjectHandle(v) + } + return o, ulCount > C.CK_ULONG(max), nil +} + +/* FindObjectsFinal finishes a search for token and session objects. */ +func (c *Ctx) FindObjectsFinal(sh SessionHandle) error { + e := C.FindObjectsFinal(c.ctx, C.CK_SESSION_HANDLE(sh)) + return toError(e) +} + +/* EncryptInit initializes an encryption operation. */ +func (c *Ctx) EncryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { + mech, _ := cMechanismList(m) + e := C.EncryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) + return toError(e) +} + +/* Encrypt encrypts single-part data. */ +func (c *Ctx) Encrypt(sh SessionHandle, message []byte) ([]byte, error) { + var ( + enc C.CK_BYTE_PTR + enclen C.CK_ULONG + ) + e := C.Encrypt(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &enc, &enclen) + if toError(e) != nil { + return nil, toError(e) + } + s := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) + C.free(unsafe.Pointer(enc)) + return s, nil +} + +/* EncryptUpdate continues a multiple-part encryption operation. */ +func (c *Ctx) EncryptUpdate(sh SessionHandle, plain []byte) ([]byte, error) { + var ( + part C.CK_BYTE_PTR + partlen C.CK_ULONG + ) + e := C.EncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&plain[0])), C.CK_ULONG(len(plain)), &part, &partlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) + C.free(unsafe.Pointer(part)) + return h, nil +} + +// EncryptFinal finishes a multiple-part encryption operation. +func (c *Ctx) EncryptFinal(sh SessionHandle) ([]byte, error) { + var ( + enc C.CK_BYTE_PTR + enclen C.CK_ULONG + ) + e := C.EncryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &enc, &enclen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) + C.free(unsafe.Pointer(enc)) + return h, nil +} + +/* DecryptInit initializes a decryption operation. */ +func (c *Ctx) DecryptInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { + mech, _ := cMechanismList(m) + e := C.DecryptInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) + return toError(e) +} + +/* Decrypt decrypts encrypted data in a single part. */ +func (c *Ctx) Decrypt(sh SessionHandle, cypher []byte) ([]byte, error) { + var ( + plain C.CK_BYTE_PTR + plainlen C.CK_ULONG + ) + e := C.Decrypt(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&cypher[0])), C.CK_ULONG(len(cypher)), &plain, &plainlen) + if toError(e) != nil { + return nil, toError(e) + } + s := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen)) + C.free(unsafe.Pointer(plain)) + return s, nil +} + +/* DecryptUpdate continues a multiple-part decryption operation. */ +func (c *Ctx) DecryptUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { + var ( + part C.CK_BYTE_PTR + partlen C.CK_ULONG + ) + e := C.DecryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&cipher[0])), C.CK_ULONG(len(cipher)), &part, &partlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) + C.free(unsafe.Pointer(part)) + return h, nil +} + +/* DecryptFinal finishes a multiple-part decryption operation. */ +func (c *Ctx) DecryptFinal(sh SessionHandle) ([]byte, error) { + var ( + plain C.CK_BYTE_PTR + plainlen C.CK_ULONG + ) + e := C.DecryptFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &plain, &plainlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(plain), C.int(plainlen)) + C.free(unsafe.Pointer(plain)) + return h, nil +} + +/* DigestInit initializes a message-digesting operation. */ +func (c *Ctx) DigestInit(sh SessionHandle, m []*Mechanism) error { + mech, _ := cMechanismList(m) + e := C.DigestInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech) + return toError(e) +} + +/* Digest digests message in a single part. */ +func (c *Ctx) Digest(sh SessionHandle, message []byte) ([]byte, error) { + var ( + hash C.CK_BYTE_PTR + hashlen C.CK_ULONG + ) + e := C.Digest(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &hash, &hashlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen)) + C.free(unsafe.Pointer(hash)) + return h, nil +} + +/* DigestUpdate continues a multiple-part message-digesting operation. */ +func (c *Ctx) DigestUpdate(sh SessionHandle, message []byte) error { + e := C.DigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message))) + if toError(e) != nil { + return toError(e) + } + return nil +} + +// DigestKey continues a multi-part message-digesting +// operation, by digesting the value of a secret key as part of +// the data already digested. +func (c *Ctx) DigestKey(sh SessionHandle, key ObjectHandle) error { + e := C.DigestKey(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_OBJECT_HANDLE(key)) + if toError(e) != nil { + return toError(e) + } + return nil +} + +/* DigestFinal finishes a multiple-part message-digesting operation. */ +func (c *Ctx) DigestFinal(sh SessionHandle) ([]byte, error) { + var ( + hash C.CK_BYTE_PTR + hashlen C.CK_ULONG + ) + e := C.DigestFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &hash, &hashlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(hash), C.int(hashlen)) + C.free(unsafe.Pointer(hash)) + return h, nil +} + +// SignInit initializes a signature (private key encryption) +// operation, where the signature is (will be) an appendix to +// the data, and plaintext cannot be recovered from the +// signature. +func (c *Ctx) SignInit(sh SessionHandle, m []*Mechanism, o ObjectHandle) error { + mech, _ := cMechanismList(m) // Only the first is used, but still use a list. + e := C.SignInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(o)) + return toError(e) +} + +// Sign signs (encrypts with private key) data in a single part, where the signature +// is (will be) an appendix to the data, and plaintext cannot be recovered from the signature. +func (c *Ctx) Sign(sh SessionHandle, message []byte) ([]byte, error) { + var ( + sig C.CK_BYTE_PTR + siglen C.CK_ULONG + ) + e := C.Sign(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message)), &sig, &siglen) + if toError(e) != nil { + return nil, toError(e) + } + s := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) + C.free(unsafe.Pointer(sig)) + return s, nil +} + +// SignUpdate continues a multiple-part signature operation, +// where the signature is (will be) an appendix to the data, +// and plaintext cannot be recovered from the signature. +func (c *Ctx) SignUpdate(sh SessionHandle, message []byte) error { + e := C.SignUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&message[0])), C.CK_ULONG(len(message))) + return toError(e) +} + +/* SignFinal finishes a multiple-part signature operation returning the signature. */ +func (c *Ctx) SignFinal(sh SessionHandle) ([]byte, error) { + var ( + sig C.CK_BYTE_PTR + siglen C.CK_ULONG + ) + e := C.SignFinal(c.ctx, C.CK_SESSION_HANDLE(sh), &sig, &siglen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) + C.free(unsafe.Pointer(sig)) + return h, nil +} + +// SignRecoverInit initializes a signature operation, where +// the data can be recovered from the signature. +func (c *Ctx) SignRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { + mech, _ := cMechanismList(m) + e := C.SignRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) + return toError(e) +} + +// SignRecover signs data in a single operation, where the +// data can be recovered from the signature. +func (c *Ctx) SignRecover(sh SessionHandle, data []byte) ([]byte, error) { + var ( + sig C.CK_BYTE_PTR + siglen C.CK_ULONG + ) + e := C.SignRecover(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&data[0])), C.CK_ULONG(len(data)), &sig, &siglen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(sig), C.int(siglen)) + C.free(unsafe.Pointer(sig)) + return h, nil +} + +// VerifyInit initializes a verification operation, where the +// signature is an appendix to the data, and plaintext cannot +// be recovered from the signature (e.g. DSA). +func (c *Ctx) VerifyInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { + mech, _ := cMechanismList(m) // only use one here + e := C.VerifyInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) + return toError(e) +} + +// Verify verifies a signature in a single-part operation, +// where the signature is an appendix to the data, and plaintext +// cannot be recovered from the signature. +func (c *Ctx) Verify(sh SessionHandle, data []byte, signature []byte) error { + e := C.Verify(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&data[0])), C.CK_ULONG(len(data)), C.CK_BYTE_PTR(unsafe.Pointer(&signature[0])), C.CK_ULONG(len(signature))) + return toError(e) +} + +// VerifyUpdate continues a multiple-part verification +// operation, where the signature is an appendix to the data, +// and plaintext cannot be recovered from the signature. +func (c *Ctx) VerifyUpdate(sh SessionHandle, part []byte) error { + e := C.VerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&part[0])), C.CK_ULONG(len(part))) + return toError(e) +} + +// VerifyFinal finishes a multiple-part verification +// operation, checking the signature. +func (c *Ctx) VerifyFinal(sh SessionHandle, signature []byte) error { + e := C.VerifyFinal(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&signature[0])), C.CK_ULONG(len(signature))) + return toError(e) +} + +// VerifyRecoverInit initializes a signature verification +// operation, where the data is recovered from the signature. +func (c *Ctx) VerifyRecoverInit(sh SessionHandle, m []*Mechanism, key ObjectHandle) error { + mech, _ := cMechanismList(m) + e := C.VerifyRecoverInit(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(key)) + return toError(e) +} + +// VerifyRecover verifies a signature in a single-part +// operation, where the data is recovered from the signature. +func (c *Ctx) VerifyRecover(sh SessionHandle, signature []byte) ([]byte, error) { + var ( + data C.CK_BYTE_PTR + datalen C.CK_ULONG + ) + e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&signature[0])), C.CK_ULONG(len(signature)), &data, &datalen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(data), C.int(datalen)) + C.free(unsafe.Pointer(data)) + return h, nil +} + +// DigestEncryptUpdate continues a multiple-part digesting +// and encryption operation. +func (c *Ctx) DigestEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) { + var ( + enc C.CK_BYTE_PTR + enclen C.CK_ULONG + ) + e := C.DigestEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&part[0])), C.CK_ULONG(len(part)), &enc, &enclen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) + C.free(unsafe.Pointer(enc)) + return h, nil +} + +/* DecryptDigestUpdate continues a multiple-part decryption and digesting operation. */ +func (c *Ctx) DecryptDigestUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { + var ( + part C.CK_BYTE_PTR + partlen C.CK_ULONG + ) + e := C.DecryptDigestUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&cipher[0])), C.CK_ULONG(len(cipher)), &part, &partlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) + C.free(unsafe.Pointer(part)) + return h, nil +} + +/* SignEncryptUpdate continues a multiple-part signing and encryption operation. */ +func (c *Ctx) SignEncryptUpdate(sh SessionHandle, part []byte) ([]byte, error) { + var ( + enc C.CK_BYTE_PTR + enclen C.CK_ULONG + ) + e := C.SignEncryptUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&part[0])), C.CK_ULONG(len(part)), &enc, &enclen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(enc), C.int(enclen)) + C.free(unsafe.Pointer(enc)) + return h, nil +} + +/* DecryptVerifyUpdate continues a multiple-part decryption and verify operation. */ +func (c *Ctx) DecryptVerifyUpdate(sh SessionHandle, cipher []byte) ([]byte, error) { + var ( + part C.CK_BYTE_PTR + partlen C.CK_ULONG + ) + e := C.DecryptVerifyUpdate(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&cipher[0])), C.CK_ULONG(len(cipher)), &part, &partlen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(part), C.int(partlen)) + C.free(unsafe.Pointer(part)) + return h, nil +} + +/* GenerateKey generates a secret key, creating a new key object. */ +func (c *Ctx) GenerateKey(sh SessionHandle, m []*Mechanism, temp []*Attribute) (ObjectHandle, error) { + var key C.CK_OBJECT_HANDLE + t, tcount := cAttributeList(temp) + mech, _ := cMechanismList(m) + e := C.GenerateKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, t, tcount, C.CK_OBJECT_HANDLE_PTR(&key)) + e1 := toError(e) + if e1 == nil { + return ObjectHandle(key), nil + } + return 0, e1 +} + +/* GenerateKeyPair generates a public-key/private-key pair creating new key objects. */ +func (c *Ctx) GenerateKeyPair(sh SessionHandle, m []*Mechanism, public, private []*Attribute) (ObjectHandle, ObjectHandle, error) { + var ( + pubkey C.CK_OBJECT_HANDLE + privkey C.CK_OBJECT_HANDLE + ) + pub, pubcount := cAttributeList(public) + priv, privcount := cAttributeList(private) + mech, _ := cMechanismList(m) + e := C.GenerateKeyPair(c.ctx, C.CK_SESSION_HANDLE(sh), mech, pub, pubcount, priv, privcount, C.CK_OBJECT_HANDLE_PTR(&pubkey), C.CK_OBJECT_HANDLE_PTR(&privkey)) + e1 := toError(e) + if e1 == nil { + return ObjectHandle(pubkey), ObjectHandle(privkey), nil + } + return 0, 0, e1 +} + +/* WrapKey wraps (i.e., encrypts) a key. */ +func (c *Ctx) WrapKey(sh SessionHandle, m []*Mechanism, wrappingkey, key ObjectHandle) ([]byte, error) { + var ( + wrappedkey C.CK_BYTE_PTR + wrappedkeylen C.CK_ULONG + ) + mech, _ := cMechanismList(m) + e := C.WrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(wrappingkey), C.CK_OBJECT_HANDLE(key), &wrappedkey, &wrappedkeylen) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(wrappedkey), C.int(wrappedkeylen)) + C.free(unsafe.Pointer(wrappedkey)) + return h, nil +} + +/* UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ +func (c *Ctx) UnwrapKey(sh SessionHandle, m []*Mechanism, unwrappingkey ObjectHandle, wrappedkey []byte, a []*Attribute) (ObjectHandle, error) { + var key C.CK_OBJECT_HANDLE + ac, aclen := cAttributeList(a) + mech, _ := cMechanismList(m) + e := C.UnwrapKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(unwrappingkey), C.CK_BYTE_PTR(unsafe.Pointer(&wrappedkey[0])), C.CK_ULONG(len(wrappedkey)), ac, aclen, &key) + return ObjectHandle(key), toError(e) +} + +// DeriveKey derives a key from a base key, creating a new key object. */ +func (c *Ctx) DeriveKey(sh SessionHandle, m []*Mechanism, basekey ObjectHandle, a []*Attribute) (ObjectHandle, error) { + var key C.CK_OBJECT_HANDLE + ac, aclen := cAttributeList(a) + mech, _ := cMechanismList(m) + e := C.DeriveKey(c.ctx, C.CK_SESSION_HANDLE(sh), mech, C.CK_OBJECT_HANDLE(basekey), ac, aclen, &key) + return ObjectHandle(key), toError(e) +} + +// SeedRandom mixes additional seed material into the token's +// random number generator. +func (c *Ctx) SeedRandom(sh SessionHandle, seed []byte) error { + e := C.SeedRandom(c.ctx, C.CK_SESSION_HANDLE(sh), C.CK_BYTE_PTR(unsafe.Pointer(&seed[0])), C.CK_ULONG(len(seed))) + return toError(e) +} + +/* GenerateRandom generates random data. */ +func (c *Ctx) GenerateRandom(sh SessionHandle, length int) ([]byte, error) { + var rand C.CK_BYTE_PTR + e := C.GenerateRandom(c.ctx, C.CK_SESSION_HANDLE(sh), &rand, C.CK_ULONG(length)) + if toError(e) != nil { + return nil, toError(e) + } + h := C.GoBytes(unsafe.Pointer(rand), C.int(length)) + C.free(unsafe.Pointer(rand)) + return h, nil +} + +// WaitForSlotEvent returns a channel which returns a slot event +// (token insertion, removal, etc.) when it occurs. +func (c *Ctx) WaitForSlotEvent(flags uint) chan SlotEvent { + sl := make(chan SlotEvent, 1) // hold one element + go c.waitForSlotEventHelper(flags, sl) + return sl +} + +func (c *Ctx) waitForSlotEventHelper(f uint, sl chan SlotEvent) { + var slotID C.CK_ULONG + C.WaitForSlotEvent(c.ctx, C.CK_FLAGS(f), &slotID) + sl <- SlotEvent{uint(slotID)} + close(sl) // TODO(miek): Sending and then closing ...? +} diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11.h b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11.h new file mode 100644 index 00000000000..9261e1e4c3f --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11.h @@ -0,0 +1,299 @@ +/* pkcs11.h include file for PKCS #11. */ +/* $Revision: 1.2 $ */ + +/* License to copy and use this software is granted provided that it is + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface + * (Cryptoki)" in all material mentioning or referencing this software. + + * License is also granted to make and use derivative works provided that + * such works are identified as "derived from the RSA Security Inc. PKCS #11 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or + * referencing the derived work. + + * RSA Security Inc. makes no representations concerning either the + * merchantability of this software or the suitability of this software for + * any particular purpose. It is provided "as is" without express or implied + * warranty of any kind. + */ + +#ifndef _PKCS11_H_ +#define _PKCS11_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Before including this file (pkcs11.h) (or pkcs11t.h by + * itself), 6 platform-specific macros must be defined. These + * macros are described below, and typical definitions for them + * are also given. Be advised that these definitions can depend + * on both the platform and the compiler used (and possibly also + * on whether a Cryptoki library is linked statically or + * dynamically). + * + * In addition to defining these 6 macros, the packing convention + * for Cryptoki structures should be set. The Cryptoki + * convention on packing is that structures should be 1-byte + * aligned. + * + * If you're using Microsoft Developer Studio 5.0 to produce + * Win32 stuff, this might be done by using the following + * preprocessor directive before including pkcs11.h or pkcs11t.h: + * + * #pragma pack(push, cryptoki, 1) + * + * and using the following preprocessor directive after including + * pkcs11.h or pkcs11t.h: + * + * #pragma pack(pop, cryptoki) + * + * If you're using an earlier version of Microsoft Developer + * Studio to produce Win16 stuff, this might be done by using + * the following preprocessor directive before including + * pkcs11.h or pkcs11t.h: + * + * #pragma pack(1) + * + * In a UNIX environment, you're on your own for this. You might + * not need to do (or be able to do!) anything. + * + * + * Now for the macros: + * + * + * 1. CK_PTR: The indirection string for making a pointer to an + * object. It can be used like this: + * + * typedef CK_BYTE CK_PTR CK_BYTE_PTR; + * + * If you're using Microsoft Developer Studio 5.0 to produce + * Win32 stuff, it might be defined by: + * + * #define CK_PTR * + * + * If you're using an earlier version of Microsoft Developer + * Studio to produce Win16 stuff, it might be defined by: + * + * #define CK_PTR far * + * + * In a typical UNIX environment, it might be defined by: + * + * #define CK_PTR * + * + * + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes + * an exportable Cryptoki library function definition out of a + * return type and a function name. It should be used in the + * following fashion to define the exposed Cryptoki functions in + * a Cryptoki library: + * + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( + * CK_VOID_PTR pReserved + * ) + * { + * ... + * } + * + * If you're using Microsoft Developer Studio 5.0 to define a + * function in a Win32 Cryptoki .dll, it might be defined by: + * + * #define CK_DEFINE_FUNCTION(returnType, name) \ + * returnType __declspec(dllexport) name + * + * If you're using an earlier version of Microsoft Developer + * Studio to define a function in a Win16 Cryptoki .dll, it + * might be defined by: + * + * #define CK_DEFINE_FUNCTION(returnType, name) \ + * returnType __export _far _pascal name + * + * In a UNIX environment, it might be defined by: + * + * #define CK_DEFINE_FUNCTION(returnType, name) \ + * returnType name + * + * + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes + * an importable Cryptoki library function declaration out of a + * return type and a function name. It should be used in the + * following fashion: + * + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( + * CK_VOID_PTR pReserved + * ); + * + * If you're using Microsoft Developer Studio 5.0 to declare a + * function in a Win32 Cryptoki .dll, it might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType __declspec(dllimport) name + * + * If you're using an earlier version of Microsoft Developer + * Studio to declare a function in a Win16 Cryptoki .dll, it + * might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType __export _far _pascal name + * + * In a UNIX environment, it might be defined by: + * + * #define CK_DECLARE_FUNCTION(returnType, name) \ + * returnType name + * + * + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro + * which makes a Cryptoki API function pointer declaration or + * function pointer type declaration out of a return type and a + * function name. It should be used in the following fashion: + * + * // Define funcPtr to be a pointer to a Cryptoki API function + * // taking arguments args and returning CK_RV. + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); + * + * or + * + * // Define funcPtrType to be the type of a pointer to a + * // Cryptoki API function taking arguments args and returning + * // CK_RV, and then define funcPtr to be a variable of type + * // funcPtrType. + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); + * funcPtrType funcPtr; + * + * If you're using Microsoft Developer Studio 5.0 to access + * functions in a Win32 Cryptoki .dll, in might be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType __declspec(dllimport) (* name) + * + * If you're using an earlier version of Microsoft Developer + * Studio to access functions in a Win16 Cryptoki .dll, it might + * be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType __export _far _pascal (* name) + * + * In a UNIX environment, it might be defined by: + * + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ + * returnType (* name) + * + * + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes + * a function pointer type for an application callback out of + * a return type for the callback and a name for the callback. + * It should be used in the following fashion: + * + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); + * + * to declare a function pointer, myCallback, to a callback + * which takes arguments args and returns a CK_RV. It can also + * be used like this: + * + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); + * myCallbackType myCallback; + * + * If you're using Microsoft Developer Studio 5.0 to do Win32 + * Cryptoki development, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType (* name) + * + * If you're using an earlier version of Microsoft Developer + * Studio to do Win16 development, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType _far _pascal (* name) + * + * In a UNIX environment, it might be defined by: + * + * #define CK_CALLBACK_FUNCTION(returnType, name) \ + * returnType (* name) + * + * + * 6. NULL_PTR: This macro is the value of a NULL pointer. + * + * In any ANSI/ISO C environment (and in many others as well), + * this should best be defined by + * + * #ifndef NULL_PTR + * #define NULL_PTR 0 + * #endif + */ + + +/* All the various Cryptoki types and #define'd values are in the + * file pkcs11t.h. */ +#include "pkcs11t.h" + +#define __PASTE(x,y) x##y + + +/* ============================================================== + * Define the "extern" form of all the entry points. + * ============================================================== + */ + +#define CK_NEED_ARG_LIST 1 +#define CK_PKCS11_FUNCTION_INFO(name) \ + extern CK_DECLARE_FUNCTION(CK_RV, name) + +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ +#include "pkcs11f.h" + +#undef CK_NEED_ARG_LIST +#undef CK_PKCS11_FUNCTION_INFO + + +/* ============================================================== + * Define the typedef form of all the entry points. That is, for + * each Cryptoki function C_XXX, define a type CK_C_XXX which is + * a pointer to that kind of function. + * ============================================================== + */ + +#define CK_NEED_ARG_LIST 1 +#define CK_PKCS11_FUNCTION_INFO(name) \ + typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) + +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ +#include "pkcs11f.h" + +#undef CK_NEED_ARG_LIST +#undef CK_PKCS11_FUNCTION_INFO + + +/* ============================================================== + * Define structed vector of entry points. A CK_FUNCTION_LIST + * contains a CK_VERSION indicating a library's Cryptoki version + * and then a whole slew of function pointers to the routines in + * the library. This type was declared, but not defined, in + * pkcs11t.h. + * ============================================================== + */ + +#define CK_PKCS11_FUNCTION_INFO(name) \ + __PASTE(CK_,name) name; + +struct CK_FUNCTION_LIST { + + CK_VERSION version; /* Cryptoki version */ + +/* Pile all the function pointers into the CK_FUNCTION_LIST. */ +/* pkcs11f.h has all the information about the Cryptoki + * function prototypes. */ +#include "pkcs11f.h" + +}; + +#undef CK_PKCS11_FUNCTION_INFO + + +#undef __PASTE + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11_test.go b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11_test.go new file mode 100644 index 00000000000..0ac02a2d5c3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11_test.go @@ -0,0 +1,242 @@ +// Copyright 2013 Miek Gieben. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs11 + +// These tests depend on SoftHSM and the library being in +// in /usr/lib/softhsm/libsofthsm.so + +import ( + "fmt" + "math/big" + "os" + "testing" +) + +func setenv(t *testing.T) *Ctx { + wd, _ := os.Getwd() + os.Setenv("SOFTHSM_CONF", wd+"/softhsm.conf") + p := New("/usr/lib/softhsm/libsofthsm.so") //p := New("/home/miek/libsofthsm.so") + if p == nil { + t.Fatal("Failed to init lib") + } + return p +} + +func getSession(p *Ctx, t *testing.T) SessionHandle { + if e := p.Initialize(); e != nil { + t.Fatalf("init error %s\n", e.Error()) + } + slots, e := p.GetSlotList(true) + if e != nil { + t.Fatalf("slots %s\n", e.Error()) + } + session, e := p.OpenSession(slots[0], CKF_SERIAL_SESSION) + if e != nil { + t.Fatalf("session %s\n", e.Error()) + } + if e := p.Login(session, CKU_USER, "1234"); e != nil { + t.Fatal("user pin %s\n", e.Error()) + } + return session +} + +func TestGetInfo(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.CloseSession(session) + defer p.Finalize() + defer p.Destroy() + info, err := p.GetInfo() + if err != nil { + t.Fatalf("Non zero error %s\n", err.Error()) + } + if info.ManufacturerID != "SoftHSM" { + t.Fatal("ID should be SoftHSM") + } + t.Logf("%+v\n", info) +} + +func TestFindObject(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.CloseSession(session) + defer p.Finalize() + defer p.Destroy() + // There are 2 keys in the db with this tag + template := []*Attribute{NewAttribute(CKA_LABEL, "MyFirstKey")} + if e := p.FindObjectsInit(session, template); e != nil { + t.Fatalf("Failed to init: %s\n", e.Error()) + } + obj, b, e := p.FindObjects(session, 2) + if e != nil { + t.Fatalf("Failed to find: %s %v\n", e.Error(), b) + } + if e := p.FindObjectsFinal(session); e != nil { + t.Fatalf("Failed to finalize: %s\n", e.Error()) + } + if len(obj) != 2 { + t.Fatal("should have found two objects") + } +} + +func TestGetAttributeValue(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.Destroy() + defer p.Finalize() + defer p.CloseSession(session) + // There are at least two RSA keys in the hsm.db, objecthandle 1 and 2. + template := []*Attribute{ + NewAttribute(CKA_PUBLIC_EXPONENT, nil), + NewAttribute(CKA_MODULUS_BITS, nil), + NewAttribute(CKA_MODULUS, nil), + NewAttribute(CKA_LABEL, nil), + } + // ObjectHandle two is the public key + attr, err := p.GetAttributeValue(session, ObjectHandle(2), template) + if err != nil { + t.Fatalf("err %s\n", err.Error()) + } + for i, a := range attr { + t.Logf("Attr %d, type %d, valuelen %d", i, a.Type, len(a.Value)) + if a.Type == CKA_MODULUS { + mod := big.NewInt(0) + mod.SetBytes(a.Value) + t.Logf("Modulus %s\n", mod.String()) + } + } +} + +func TestDigest(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.CloseSession(session) + defer p.Finalize() + defer p.Destroy() + e := p.DigestInit(session, []*Mechanism{NewMechanism(CKM_SHA_1, nil)}) + if e != nil { + t.Fatalf("DigestInit: %s\n", e.Error()) + } + + hash, e := p.Digest(session, []byte("this is a string")) + if e != nil { + t.Fatalf("Digest: %s\n", e.Error()) + } + hex := "" + for _, d := range hash { + hex += fmt.Sprintf("%x", d) + } + // Teststring create with: echo -n "this is a string" | sha1sum + if hex != "517592df8fec3ad146a79a9af153db2a4d784ec5" { + t.Fatalf("wrong digest: %s", hex) + } +} + +func TestDigestUpdate(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.CloseSession(session) + defer p.Finalize() + defer p.Destroy() + if e := p.DigestInit(session, []*Mechanism{NewMechanism(CKM_SHA_1, nil)}); e != nil { + t.Fatalf("DigestInit: %s\n", e.Error()) + } + if e := p.DigestUpdate(session, []byte("this is ")); e != nil { + t.Fatalf("DigestUpdate: %s\n", e.Error()) + } + if e := p.DigestUpdate(session, []byte("a string")); e != nil { + t.Fatalf("DigestUpdate: %s\n", e.Error()) + } + hash, e := p.DigestFinal(session) + if e != nil { + t.Fatalf("DigestFinal: %s\n", e.Error()) + } + hex := "" + for _, d := range hash { + hex += fmt.Sprintf("%x", d) + } + // Teststring create with: echo -n "this is a string" | sha1sum + if hex != "517592df8fec3ad146a79a9af153db2a4d784ec5" { + t.Fatalf("wrong digest: %s", hex) + } + +} + +func testDestroyObject(t *testing.T) { + p := setenv(t) + session := getSession(p, t) + defer p.Logout(session) + defer p.CloseSession(session) + defer p.Finalize() + defer p.Destroy() + + p.Logout(session) // log out the normal user + if e := p.Login(session, CKU_SO, "1234"); e != nil { + t.Fatal("security officer pin %s\n", e.Error()) + } + + // Looking the int values is tricky because they are stored in 64 bits in hsm.db, + // this means looking up stuff on 32 bits will not found them. + template := []*Attribute{ + NewAttribute(CKA_LABEL, "MyFirstKey")} + + if e := p.FindObjectsInit(session, template); e != nil { + t.Fatalf("Failed to init: %s\n", e.Error()) + } + obj, _, e := p.FindObjects(session, 1) + if e != nil || len(obj) == 0 { + t.Fatalf("Failed to find objects\n") + } + if e := p.FindObjectsFinal(session); e != nil { + t.Fatalf("Failed to finalize: %s\n", e.Error()) + } + + if err := p.DestroyObject(session, obj[0]); err != nil { + t.Fatal("DestroyObject failed" + err.Error()) + } +} + +// ExampleSign show how to sign some data with a private key. +// Note: error correction is not implemented in this function. +func ExampleSign() { + p := setenv(nil) + p.Initialize() + defer p.Destroy() + defer p.Finalize() + slots, _ := p.GetSlotList(true) + session, _ := p.OpenSession(slots[0], CKF_SERIAL_SESSION|CKF_RW_SESSION) + defer p.CloseSession(session) + p.Login(session, CKU_USER, "1234") + defer p.Logout(session) + publicKeyTemplate := []*Attribute{ + NewAttribute(CKA_KEY_TYPE, CKO_PUBLIC_KEY), + NewAttribute(CKA_TOKEN, true), + NewAttribute(CKA_ENCRYPT, true), + NewAttribute(CKA_PUBLIC_EXPONENT, []byte{3}), + NewAttribute(CKA_MODULUS_BITS, 1024), + NewAttribute(CKA_LABEL, "MyFirstKey"), + } + privateKeyTemplate := []*Attribute{ + NewAttribute(CKA_KEY_TYPE, CKO_PRIVATE_KEY), + NewAttribute(CKA_TOKEN, true), + NewAttribute(CKA_PRIVATE, true), + NewAttribute(CKA_SIGN, true), + NewAttribute(CKA_LABEL, "MyFirstKey"), + } + pub, priv, _ := p.GenerateKeyPair(session, + []*Mechanism{NewMechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, nil)}, + publicKeyTemplate, privateKeyTemplate) + p.SignInit(session, []*Mechanism{NewMechanism(CKM_SHA1_RSA_PKCS, nil)}, priv) + // Sign something with the private key. + data := []byte("Lets sign this data") + + sig, _ := p.Sign(session, data) + fmt.Printf("%v validate with %v\n", sig, pub) +} diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11f.h b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11f.h new file mode 100644 index 00000000000..ffbe010f64a --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11f.h @@ -0,0 +1,910 @@ +/* pkcs11f.h include file for PKCS #11. */ +/* $Revision: 1.2 $ */ + +/* License to copy and use this software is granted provided that it is + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface + * (Cryptoki)" in all material mentioning or referencing this software. + + * License is also granted to make and use derivative works provided that + * such works are identified as "derived from the RSA Security Inc. PKCS #11 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or + * referencing the derived work. + + * RSA Security Inc. makes no representations concerning either the + * merchantability of this software or the suitability of this software for + * any particular purpose. It is provided "as is" without express or implied + * warranty of any kind. + */ + +/* This header file contains pretty much everything about all the */ +/* Cryptoki function prototypes. Because this information is */ +/* used for more than just declaring function prototypes, the */ +/* order of the functions appearing herein is important, and */ +/* should not be altered. */ + +/* General-purpose */ + +/* C_Initialize initializes the Cryptoki library. */ +CK_PKCS11_FUNCTION_INFO(C_Initialize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets + * cast to CK_C_INITIALIZE_ARGS_PTR + * and dereferenced */ +); +#endif + + +/* C_Finalize indicates that an application is done with the + * Cryptoki library. */ +CK_PKCS11_FUNCTION_INFO(C_Finalize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ +); +#endif + + +/* C_GetInfo returns general information about Cryptoki. */ +CK_PKCS11_FUNCTION_INFO(C_GetInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_INFO_PTR pInfo /* location that receives information */ +); +#endif + + +/* C_GetFunctionList returns the function list. */ +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) +#ifdef CK_NEED_ARG_LIST +( + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to + * function list */ +); +#endif + + + +/* Slot and token management */ + +/* C_GetSlotList obtains a list of slots in the system. */ +CK_PKCS11_FUNCTION_INFO(C_GetSlotList) +#ifdef CK_NEED_ARG_LIST +( + CK_BBOOL tokenPresent, /* only slots with tokens? */ + CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ + CK_ULONG_PTR pulCount /* receives number of slots */ +); +#endif + + +/* C_GetSlotInfo obtains information about a particular slot in + * the system. */ +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the ID of the slot */ + CK_SLOT_INFO_PTR pInfo /* receives the slot information */ +); +#endif + + +/* C_GetTokenInfo obtains information about a particular token + * in the system. */ +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_TOKEN_INFO_PTR pInfo /* receives the token information */ +); +#endif + + +/* C_GetMechanismList obtains a list of mechanism types + * supported by a token. */ +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of token's slot */ + CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ + CK_ULONG_PTR pulCount /* gets # of mechs. */ +); +#endif + + +/* C_GetMechanismInfo obtains information about a particular + * mechanism possibly supported by a token. */ +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_MECHANISM_TYPE type, /* type of mechanism */ + CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ +); +#endif + + +/* C_InitToken initializes a token. */ +CK_PKCS11_FUNCTION_INFO(C_InitToken) +#ifdef CK_NEED_ARG_LIST +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */ +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ + CK_ULONG ulPinLen, /* length in bytes of the PIN */ + CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ +); +#endif + + +/* C_InitPIN initializes the normal user's PIN. */ +CK_PKCS11_FUNCTION_INFO(C_InitPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ + CK_ULONG ulPinLen /* length in bytes of the PIN */ +); +#endif + + +/* C_SetPIN modifies the PIN of the user who is logged in. */ +CK_PKCS11_FUNCTION_INFO(C_SetPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ + CK_ULONG ulOldLen, /* length of the old PIN */ + CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ + CK_ULONG ulNewLen /* length of the new PIN */ +); +#endif + + + +/* Session management */ + +/* C_OpenSession opens a session between an application and a + * token. */ +CK_PKCS11_FUNCTION_INFO(C_OpenSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the slot's ID */ + CK_FLAGS flags, /* from CK_SESSION_INFO */ + CK_VOID_PTR pApplication, /* passed to callback */ + CK_NOTIFY Notify, /* callback function */ + CK_SESSION_HANDLE_PTR phSession /* gets session handle */ +); +#endif + + +/* C_CloseSession closes a session between an application and a + * token. */ +CK_PKCS11_FUNCTION_INFO(C_CloseSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + +/* C_CloseAllSessions closes all sessions with a token. */ +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID /* the token's slot */ +); +#endif + + +/* C_GetSessionInfo obtains information about the session. */ +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_SESSION_INFO_PTR pInfo /* receives session info */ +); +#endif + + +/* C_GetOperationState obtains the state of the cryptographic operation + * in a session. */ +CK_PKCS11_FUNCTION_INFO(C_GetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* gets state */ + CK_ULONG_PTR pulOperationStateLen /* gets state length */ +); +#endif + + +/* C_SetOperationState restores the state of the cryptographic + * operation in a session. */ +CK_PKCS11_FUNCTION_INFO(C_SetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pOperationState, /* holds state */ + CK_ULONG ulOperationStateLen, /* holds state length */ + CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ + CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ +); +#endif + + +/* C_Login logs a user into a token. */ +CK_PKCS11_FUNCTION_INFO(C_Login) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_USER_TYPE userType, /* the user type */ + CK_UTF8CHAR_PTR pPin, /* the user's PIN */ + CK_ULONG ulPinLen /* the length of the PIN */ +); +#endif + + +/* C_Logout logs a user out from a token. */ +CK_PKCS11_FUNCTION_INFO(C_Logout) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Object management */ + +/* C_CreateObject creates a new object. */ +CK_PKCS11_FUNCTION_INFO(C_CreateObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ +); +#endif + +/* C_CopyObject copies an object, creating a new object for the + * copy. */ +CK_PKCS11_FUNCTION_INFO(C_CopyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ +); +#endif + + +/* C_DestroyObject destroys an object. */ +CK_PKCS11_FUNCTION_INFO(C_DestroyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject /* the object's handle */ +); +#endif + + +/* C_GetObjectSize gets the size of an object in bytes. */ +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ULONG_PTR pulSize /* receives size of object */ +); +#endif + + +/* C_GetAttributeValue obtains the value of one or more object + * attributes. */ +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_SetAttributeValue modifies the value of one or more object + * attributes */ +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_FindObjectsInit initializes a search for token and session + * objects that match a template. */ +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ + CK_ULONG ulCount /* attrs in search template */ +); +#endif + + +/* C_FindObjects continues a search for token and session + * objects that match a template, obtaining additional object + * handles. */ +CK_PKCS11_FUNCTION_INFO(C_FindObjects) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ + CK_ULONG ulMaxObjectCount, /* max handles to get */ + CK_ULONG_PTR pulObjectCount /* actual # returned */ +); +#endif + + +/* C_FindObjectsFinal finishes a search for token and session + * objects. */ +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Encryption and decryption */ + +/* C_EncryptInit initializes an encryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_EncryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of encryption key */ +); +#endif + + +/* C_Encrypt encrypts single-part data. */ +CK_PKCS11_FUNCTION_INFO(C_Encrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pData, /* the plaintext data */ + CK_ULONG ulDataLen, /* bytes of plaintext */ + CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ +); +#endif + + +/* C_EncryptUpdate continues a multiple-part encryption + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext data len */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ +); +#endif + + +/* C_EncryptFinal finishes a multiple-part encryption + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session handle */ + CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ + CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ +); +#endif + + +/* C_DecryptInit initializes a decryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of decryption key */ +); +#endif + + +/* C_Decrypt decrypts encrypted data in a single part. */ +CK_PKCS11_FUNCTION_INFO(C_Decrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedData, /* ciphertext */ + CK_ULONG ulEncryptedDataLen, /* ciphertext length */ + CK_BYTE_PTR pData, /* gets plaintext */ + CK_ULONG_PTR pulDataLen /* gets p-text size */ +); +#endif + + +/* C_DecryptUpdate continues a multiple-part decryption + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* encrypted data */ + CK_ULONG ulEncryptedPartLen, /* input length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* p-text size */ +); +#endif + + +/* C_DecryptFinal finishes a multiple-part decryption + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastPart, /* gets plaintext */ + CK_ULONG_PTR pulLastPartLen /* p-text size */ +); +#endif + + + +/* Message digesting */ + +/* C_DigestInit initializes a message-digesting operation. */ +CK_PKCS11_FUNCTION_INFO(C_DigestInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ +); +#endif + + +/* C_Digest digests data in a single part. */ +CK_PKCS11_FUNCTION_INFO(C_Digest) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* data to be digested */ + CK_ULONG ulDataLen, /* bytes of data to digest */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets digest length */ +); +#endif + + +/* C_DigestUpdate continues a multiple-part message-digesting + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* data to be digested */ + CK_ULONG ulPartLen /* bytes of data to be digested */ +); +#endif + + +/* C_DigestKey continues a multi-part message-digesting + * operation, by digesting the value of a secret key as part of + * the data already digested. */ +CK_PKCS11_FUNCTION_INFO(C_DigestKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hKey /* secret key to digest */ +); +#endif + + +/* C_DigestFinal finishes a multiple-part message-digesting + * operation. */ +CK_PKCS11_FUNCTION_INFO(C_DigestFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pDigest, /* gets the message digest */ + CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ +); +#endif + + + +/* Signing and MACing */ + +/* C_SignInit initializes a signature (private key encryption) + * operation, where the signature is (will be) an appendix to + * the data, and plaintext cannot be recovered from the + *signature. */ +CK_PKCS11_FUNCTION_INFO(C_SignInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of signature key */ +); +#endif + + +/* C_Sign signs (encrypts with private key) data in a single + * part, where the signature is (will be) an appendix to the + * data, and plaintext cannot be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_Sign) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + +/* C_SignUpdate continues a multiple-part signature operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_SignUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the data to sign */ + CK_ULONG ulPartLen /* count of bytes to sign */ +); +#endif + + +/* C_SignFinal finishes a multiple-part signature operation, + * returning the signature. */ +CK_PKCS11_FUNCTION_INFO(C_SignFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + +/* C_SignRecoverInit initializes a signature operation, where + * the data can be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the signature key */ +); +#endif + + +/* C_SignRecover signs data in a single operation, where the + * data can be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_SignRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data to sign */ + CK_ULONG ulDataLen, /* count of bytes to sign */ + CK_BYTE_PTR pSignature, /* gets the signature */ + CK_ULONG_PTR pulSignatureLen /* gets signature length */ +); +#endif + + + +/* Verifying signatures and MACs */ + +/* C_VerifyInit initializes a verification operation, where the + * signature is an appendix to the data, and plaintext cannot + * cannot be recovered from the signature (e.g. DSA). */ +CK_PKCS11_FUNCTION_INFO(C_VerifyInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ +); +#endif + + +/* C_Verify verifies a signature in a single-part operation, + * where the signature is an appendix to the data, and plaintext + * cannot be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_Verify) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* signed data */ + CK_ULONG ulDataLen, /* length of signed data */ + CK_BYTE_PTR pSignature, /* signature */ + CK_ULONG ulSignatureLen /* signature length*/ +); +#endif + + +/* C_VerifyUpdate continues a multiple-part verification + * operation, where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* signed data */ + CK_ULONG ulPartLen /* length of signed data */ +); +#endif + + +/* C_VerifyFinal finishes a multiple-part verification + * operation, checking the signature. */ +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen /* signature length */ +); +#endif + + +/* C_VerifyRecoverInit initializes a signature verification + * operation, where the data is recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* verification key */ +); +#endif + + +/* C_VerifyRecover verifies a signature in a single-part + * operation, where the data is recovered from the signature. */ +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* signature to verify */ + CK_ULONG ulSignatureLen, /* signature length */ + CK_BYTE_PTR pData, /* gets signed data */ + CK_ULONG_PTR pulDataLen /* gets signed data len */ +); +#endif + + + +/* Dual-function cryptographic operations */ + +/* C_DigestEncryptUpdate continues a multiple-part digesting + * and encryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ +); +#endif + + +/* C_DecryptDigestUpdate continues a multiple-part decryption and + * digesting operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets plaintext len */ +); +#endif + + +/* C_SignEncryptUpdate continues a multiple-part signing and + * encryption operation. */ +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* plaintext length */ + CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ + CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ +); +#endif + + +/* C_DecryptVerifyUpdate continues a multiple-part decryption and + * verify operation. */ +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_BYTE_PTR pEncryptedPart, /* ciphertext */ + CK_ULONG ulEncryptedPartLen, /* ciphertext length */ + CK_BYTE_PTR pPart, /* gets plaintext */ + CK_ULONG_PTR pulPartLen /* gets p-text length */ +); +#endif + + + +/* Key management */ + +/* C_GenerateKey generates a secret key, creating a new key + * object. */ +CK_PKCS11_FUNCTION_INFO(C_GenerateKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* key generation mech. */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ + CK_ULONG ulCount, /* # of attrs in template */ + CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ +); +#endif + + +/* C_GenerateKeyPair generates a public-key/private-key pair, + * creating new key objects. */ +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session + * handle */ + CK_MECHANISM_PTR pMechanism, /* key-gen + * mech. */ + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template + * for pub. + * key */ + CK_ULONG ulPublicKeyAttributeCount, /* # pub. + * attrs. */ + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template + * for priv. + * key */ + CK_ULONG ulPrivateKeyAttributeCount, /* # priv. + * attrs. */ + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. + * key + * handle */ + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets + * priv. key + * handle */ +); +#endif + + +/* C_WrapKey wraps (i.e., encrypts) a key. */ +CK_PKCS11_FUNCTION_INFO(C_WrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ + CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ + CK_OBJECT_HANDLE hKey, /* key to be wrapped */ + CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ + CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ +); +#endif + + +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new + * key object. */ +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ + CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ + CK_BYTE_PTR pWrappedKey, /* the wrapped key */ + CK_ULONG ulWrappedKeyLen, /* wrapped key len */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ +); +#endif + + +/* C_DeriveKey derives a key from a base key, creating a new key + * object. */ +CK_PKCS11_FUNCTION_INFO(C_DeriveKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* session's handle */ + CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ + CK_OBJECT_HANDLE hBaseKey, /* base key */ + CK_ATTRIBUTE_PTR pTemplate, /* new key template */ + CK_ULONG ulAttributeCount, /* template length */ + CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ +); +#endif + + + +/* Random number generation */ + +/* C_SeedRandom mixes additional seed material into the token's + * random number generator. */ +CK_PKCS11_FUNCTION_INFO(C_SeedRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSeed, /* the seed material */ + CK_ULONG ulSeedLen /* length of seed material */ +); +#endif + + +/* C_GenerateRandom generates random data. */ +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR RandomData, /* receives the random data */ + CK_ULONG ulRandomLen /* # of bytes to generate */ +); +#endif + + + +/* Parallel function management */ + +/* C_GetFunctionStatus is a legacy function; it obtains an + * updated status of a function running in parallel with an + * application. */ +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_CancelFunction is a legacy function; it cancels a function + * running in parallel. */ +CK_PKCS11_FUNCTION_INFO(C_CancelFunction) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Functions added in for Cryptoki Version 2.01 or later */ + +/* C_WaitForSlotEvent waits for a slot event (token insertion, + * removal, etc.) to occur. */ +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) +#ifdef CK_NEED_ARG_LIST +( + CK_FLAGS flags, /* blocking/nonblocking flag */ + CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ + CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ +); +#endif diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11t.h b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11t.h new file mode 100644 index 00000000000..add49e48307 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/pkcs11t.h @@ -0,0 +1,1885 @@ +/* pkcs11t.h include file for PKCS #11. */ +/* $Revision: 1.2 $ */ + +/* License to copy and use this software is granted provided that it is + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface + * (Cryptoki)" in all material mentioning or referencing this software. + + * License is also granted to make and use derivative works provided that + * such works are identified as "derived from the RSA Security Inc. PKCS #11 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or + * referencing the derived work. + + * RSA Security Inc. makes no representations concerning either the + * merchantability of this software or the suitability of this software for + * any particular purpose. It is provided "as is" without express or implied + * warranty of any kind. + */ + +/* See top of pkcs11.h for information about the macros that + * must be defined and the structure-packing conventions that + * must be set before including this file. */ + +#ifndef _PKCS11T_H_ +#define _PKCS11T_H_ 1 + +#define CRYPTOKI_VERSION_MAJOR 2 +#define CRYPTOKI_VERSION_MINOR 20 +#define CRYPTOKI_VERSION_AMENDMENT 3 + +#define CK_TRUE 1 +#define CK_FALSE 0 + +#ifndef CK_DISABLE_TRUE_FALSE +#ifndef FALSE +#define FALSE CK_FALSE +#endif + +#ifndef TRUE +#define TRUE CK_TRUE +#endif +#endif + +/* an unsigned 8-bit value */ +typedef unsigned char CK_BYTE; + +/* an unsigned 8-bit character */ +typedef CK_BYTE CK_CHAR; + +/* an 8-bit UTF-8 character */ +typedef CK_BYTE CK_UTF8CHAR; + +/* a BYTE-sized Boolean flag */ +typedef CK_BYTE CK_BBOOL; + +/* an unsigned value, at least 32 bits long */ +typedef unsigned long int CK_ULONG; + +/* a signed value, the same size as a CK_ULONG */ +/* CK_LONG is new for v2.0 */ +typedef long int CK_LONG; + +/* at least 32 bits; each bit is a Boolean flag */ +typedef CK_ULONG CK_FLAGS; + + +/* some special values for certain CK_ULONG variables */ +#define CK_UNAVAILABLE_INFORMATION (~0UL) +#define CK_EFFECTIVELY_INFINITE 0 + + +typedef CK_BYTE CK_PTR CK_BYTE_PTR; +typedef CK_CHAR CK_PTR CK_CHAR_PTR; +typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; +typedef CK_ULONG CK_PTR CK_ULONG_PTR; +typedef void CK_PTR CK_VOID_PTR; + +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; + + +/* The following value is always invalid if used as a session */ +/* handle or object handle */ +#define CK_INVALID_HANDLE 0 + + +typedef struct CK_VERSION { + CK_BYTE major; /* integer portion of version number */ + CK_BYTE minor; /* 1/100ths portion of version number */ +} CK_VERSION; + +typedef CK_VERSION CK_PTR CK_VERSION_PTR; + + +typedef struct CK_INFO { + /* manufacturerID and libraryDecription have been changed from + * CK_CHAR to CK_UTF8CHAR for v2.10 */ + CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; /* must be zero */ + + /* libraryDescription and libraryVersion are new for v2.0 */ + CK_UTF8CHAR libraryDescription[32]; /* blank padded */ + CK_VERSION libraryVersion; /* version of library */ +} CK_INFO; + +typedef CK_INFO CK_PTR CK_INFO_PTR; + + +/* CK_NOTIFICATION enumerates the types of notifications that + * Cryptoki provides to an application */ +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG + * for v2.0 */ +typedef CK_ULONG CK_NOTIFICATION; +#define CKN_SURRENDER 0 + +/* The following notification is new for PKCS #11 v2.20 amendment 3 */ +#define CKN_OTP_CHANGED 1 + + +typedef CK_ULONG CK_SLOT_ID; + +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; + + +/* CK_SLOT_INFO provides information about a slot */ +typedef struct CK_SLOT_INFO { + /* slotDescription and manufacturerID have been changed from + * CK_CHAR to CK_UTF8CHAR for v2.10 */ + CK_UTF8CHAR slotDescription[64]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; + + /* hardwareVersion and firmwareVersion are new for v2.0 */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ +} CK_SLOT_INFO; + +/* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ +#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */ +#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/ +#define CKF_HW_SLOT 0x00000004 /* hardware slot */ + +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; + + +/* CK_TOKEN_INFO provides information about a token */ +typedef struct CK_TOKEN_INFO { + /* label, manufacturerID, and model have been changed from + * CK_CHAR to CK_UTF8CHAR for v2.10 */ + CK_UTF8CHAR label[32]; /* blank padded */ + CK_UTF8CHAR manufacturerID[32]; /* blank padded */ + CK_UTF8CHAR model[16]; /* blank padded */ + CK_CHAR serialNumber[16]; /* blank padded */ + CK_FLAGS flags; /* see below */ + + /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, + * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been + * changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulMaxSessionCount; /* max open sessions */ + CK_ULONG ulSessionCount; /* sess. now open */ + CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ + CK_ULONG ulRwSessionCount; /* R/W sess. now open */ + CK_ULONG ulMaxPinLen; /* in bytes */ + CK_ULONG ulMinPinLen; /* in bytes */ + CK_ULONG ulTotalPublicMemory; /* in bytes */ + CK_ULONG ulFreePublicMemory; /* in bytes */ + CK_ULONG ulTotalPrivateMemory; /* in bytes */ + CK_ULONG ulFreePrivateMemory; /* in bytes */ + + /* hardwareVersion, firmwareVersion, and time are new for + * v2.0 */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ + CK_CHAR utcTime[16]; /* time */ +} CK_TOKEN_INFO; + +/* The flags parameter is defined as follows: + * Bit Flag Mask Meaning + */ +#define CKF_RNG 0x00000001 /* has random # + * generator */ +#define CKF_WRITE_PROTECTED 0x00000002 /* token is + * write- + * protected */ +#define CKF_LOGIN_REQUIRED 0x00000004 /* user must + * login */ +#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's + * PIN is set */ + +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, + * that means that *every* time the state of cryptographic + * operations of a session is successfully saved, all keys + * needed to continue those operations are stored in the state */ +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 + +/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means + * that the token has some sort of clock. The time on that + * clock is returned in the token info structure */ +#define CKF_CLOCK_ON_TOKEN 0x00000040 + +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is + * set, that means that there is some way for the user to login + * without sending a PIN through the Cryptoki library itself */ +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 + +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, + * that means that a single session with the token can perform + * dual simultaneous cryptographic operations (digest and + * encrypt; decrypt and digest; sign and encrypt; and decrypt + * and sign) */ +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 + +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the + * token has been initialized using C_InitializeToken or an + * equivalent mechanism outside the scope of PKCS #11. + * Calling C_InitializeToken when this flag is set will cause + * the token to be reinitialized. */ +#define CKF_TOKEN_INITIALIZED 0x00000400 + +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is + * true, the token supports secondary authentication for + * private key objects. This flag is deprecated in v2.11 and + onwards. */ +#define CKF_SECONDARY_AUTHENTICATION 0x00000800 + +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an + * incorrect user login PIN has been entered at least once + * since the last successful authentication. */ +#define CKF_USER_PIN_COUNT_LOW 0x00010000 + +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true, + * supplying an incorrect user PIN will it to become locked. */ +#define CKF_USER_PIN_FINAL_TRY 0x00020000 + +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the + * user PIN has been locked. User login to the token is not + * possible. */ +#define CKF_USER_PIN_LOCKED 0x00040000 + +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true, + * the user PIN value is the default value set by token + * initialization or manufacturing, or the PIN has been + * expired by the card. */ +#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000 + +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an + * incorrect SO login PIN has been entered at least once since + * the last successful authentication. */ +#define CKF_SO_PIN_COUNT_LOW 0x00100000 + +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true, + * supplying an incorrect SO PIN will it to become locked. */ +#define CKF_SO_PIN_FINAL_TRY 0x00200000 + +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO + * PIN has been locked. SO login to the token is not possible. + */ +#define CKF_SO_PIN_LOCKED 0x00400000 + +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true, + * the SO PIN value is the default value set by token + * initialization or manufacturing, or the PIN has been + * expired by the card. */ +#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000 + +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; + + +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that + * identifies a session */ +typedef CK_ULONG CK_SESSION_HANDLE; + +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; + + +/* CK_USER_TYPE enumerates the types of Cryptoki users */ +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for + * v2.0 */ +typedef CK_ULONG CK_USER_TYPE; +/* Security Officer */ +#define CKU_SO 0 +/* Normal user */ +#define CKU_USER 1 +/* Context specific (added in v2.20) */ +#define CKU_CONTEXT_SPECIFIC 2 + +/* CK_STATE enumerates the session states */ +/* CK_STATE has been changed from an enum to a CK_ULONG for + * v2.0 */ +typedef CK_ULONG CK_STATE; +#define CKS_RO_PUBLIC_SESSION 0 +#define CKS_RO_USER_FUNCTIONS 1 +#define CKS_RW_PUBLIC_SESSION 2 +#define CKS_RW_USER_FUNCTIONS 3 +#define CKS_RW_SO_FUNCTIONS 4 + + +/* CK_SESSION_INFO provides information about a session */ +typedef struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; /* see below */ + + /* ulDeviceError was changed from CK_USHORT to CK_ULONG for + * v2.0 */ + CK_ULONG ulDeviceError; /* device-dependent error code */ +} CK_SESSION_INFO; + +/* The flags are defined in the following table: + * Bit Flag Mask Meaning + */ +#define CKF_RW_SESSION 0x00000002 /* session is r/w */ +#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */ + +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; + + +/* CK_OBJECT_HANDLE is a token-specific identifier for an + * object */ +typedef CK_ULONG CK_OBJECT_HANDLE; + +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; + + +/* CK_OBJECT_CLASS is a value that identifies the classes (or + * types) of objects that Cryptoki recognizes. It is defined + * as follows: */ +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for + * v2.0 */ +typedef CK_ULONG CK_OBJECT_CLASS; + +/* The following classes of objects are defined: */ +/* CKO_HW_FEATURE is new for v2.10 */ +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */ +/* CKO_MECHANISM is new for v2.20 */ +#define CKO_DATA 0x00000000 +#define CKO_CERTIFICATE 0x00000001 +#define CKO_PUBLIC_KEY 0x00000002 +#define CKO_PRIVATE_KEY 0x00000003 +#define CKO_SECRET_KEY 0x00000004 +#define CKO_HW_FEATURE 0x00000005 +#define CKO_DOMAIN_PARAMETERS 0x00000006 +#define CKO_MECHANISM 0x00000007 + +/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */ +#define CKO_OTP_KEY 0x00000008 + +#define CKO_VENDOR_DEFINED 0x80000000 + +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; + +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a + * value that identifies the hardware feature type of an object + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */ +typedef CK_ULONG CK_HW_FEATURE_TYPE; + +/* The following hardware feature types are defined */ +/* CKH_USER_INTERFACE is new for v2.20 */ +#define CKH_MONOTONIC_COUNTER 0x00000001 +#define CKH_CLOCK 0x00000002 +#define CKH_USER_INTERFACE 0x00000003 +#define CKH_VENDOR_DEFINED 0x80000000 + +/* CK_KEY_TYPE is a value that identifies a key type */ +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_KEY_TYPE; + +/* the following key types are defined: */ +#define CKK_RSA 0x00000000 +#define CKK_DSA 0x00000001 +#define CKK_DH 0x00000002 + +/* CKK_ECDSA and CKK_KEA are new for v2.0 */ +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */ +#define CKK_ECDSA 0x00000003 +#define CKK_EC 0x00000003 +#define CKK_X9_42_DH 0x00000004 +#define CKK_KEA 0x00000005 + +#define CKK_GENERIC_SECRET 0x00000010 +#define CKK_RC2 0x00000011 +#define CKK_RC4 0x00000012 +#define CKK_DES 0x00000013 +#define CKK_DES2 0x00000014 +#define CKK_DES3 0x00000015 + +/* all these key types are new for v2.0 */ +#define CKK_CAST 0x00000016 +#define CKK_CAST3 0x00000017 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */ +#define CKK_CAST5 0x00000018 +#define CKK_CAST128 0x00000018 +#define CKK_RC5 0x00000019 +#define CKK_IDEA 0x0000001A +#define CKK_SKIPJACK 0x0000001B +#define CKK_BATON 0x0000001C +#define CKK_JUNIPER 0x0000001D +#define CKK_CDMF 0x0000001E +#define CKK_AES 0x0000001F + +/* BlowFish and TwoFish are new for v2.20 */ +#define CKK_BLOWFISH 0x00000020 +#define CKK_TWOFISH 0x00000021 + +/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */ +#define CKK_SECURID 0x00000022 +#define CKK_HOTP 0x00000023 +#define CKK_ACTI 0x00000024 + +/* Camellia is new for PKCS #11 v2.20 amendment 3 */ +#define CKK_CAMELLIA 0x00000025 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */ +#define CKK_ARIA 0x00000026 + + +#define CKK_VENDOR_DEFINED 0x80000000 + + +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate + * type */ +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG + * for v2.0 */ +typedef CK_ULONG CK_CERTIFICATE_TYPE; + +/* The following certificate types are defined: */ +/* CKC_X_509_ATTR_CERT is new for v2.10 */ +/* CKC_WTLS is new for v2.20 */ +#define CKC_X_509 0x00000000 +#define CKC_X_509_ATTR_CERT 0x00000001 +#define CKC_WTLS 0x00000002 +#define CKC_VENDOR_DEFINED 0x80000000 + + +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute + * type */ +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for + * v2.0 */ +typedef CK_ULONG CK_ATTRIBUTE_TYPE; + +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which + consists of an array of values. */ +#define CKF_ARRAY_ATTRIBUTE 0x40000000 + +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 + and relates to the CKA_OTP_FORMAT attribute */ +#define CK_OTP_FORMAT_DECIMAL 0 +#define CK_OTP_FORMAT_HEXADECIMAL 1 +#define CK_OTP_FORMAT_ALPHANUMERIC 2 +#define CK_OTP_FORMAT_BINARY 3 + +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 + and relates to the CKA_OTP_..._REQUIREMENT attributes */ +#define CK_OTP_PARAM_IGNORED 0 +#define CK_OTP_PARAM_OPTIONAL 1 +#define CK_OTP_PARAM_MANDATORY 2 + +/* The following attribute types are defined: */ +#define CKA_CLASS 0x00000000 +#define CKA_TOKEN 0x00000001 +#define CKA_PRIVATE 0x00000002 +#define CKA_LABEL 0x00000003 +#define CKA_APPLICATION 0x00000010 +#define CKA_VALUE 0x00000011 + +/* CKA_OBJECT_ID is new for v2.10 */ +#define CKA_OBJECT_ID 0x00000012 + +#define CKA_CERTIFICATE_TYPE 0x00000080 +#define CKA_ISSUER 0x00000081 +#define CKA_SERIAL_NUMBER 0x00000082 + +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new + * for v2.10 */ +#define CKA_AC_ISSUER 0x00000083 +#define CKA_OWNER 0x00000084 +#define CKA_ATTR_TYPES 0x00000085 + +/* CKA_TRUSTED is new for v2.11 */ +#define CKA_TRUSTED 0x00000086 + +/* CKA_CERTIFICATE_CATEGORY ... + * CKA_CHECK_VALUE are new for v2.20 */ +#define CKA_CERTIFICATE_CATEGORY 0x00000087 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088 +#define CKA_URL 0x00000089 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B +#define CKA_CHECK_VALUE 0x00000090 + +#define CKA_KEY_TYPE 0x00000100 +#define CKA_SUBJECT 0x00000101 +#define CKA_ID 0x00000102 +#define CKA_SENSITIVE 0x00000103 +#define CKA_ENCRYPT 0x00000104 +#define CKA_DECRYPT 0x00000105 +#define CKA_WRAP 0x00000106 +#define CKA_UNWRAP 0x00000107 +#define CKA_SIGN 0x00000108 +#define CKA_SIGN_RECOVER 0x00000109 +#define CKA_VERIFY 0x0000010A +#define CKA_VERIFY_RECOVER 0x0000010B +#define CKA_DERIVE 0x0000010C +#define CKA_START_DATE 0x00000110 +#define CKA_END_DATE 0x00000111 +#define CKA_MODULUS 0x00000120 +#define CKA_MODULUS_BITS 0x00000121 +#define CKA_PUBLIC_EXPONENT 0x00000122 +#define CKA_PRIVATE_EXPONENT 0x00000123 +#define CKA_PRIME_1 0x00000124 +#define CKA_PRIME_2 0x00000125 +#define CKA_EXPONENT_1 0x00000126 +#define CKA_EXPONENT_2 0x00000127 +#define CKA_COEFFICIENT 0x00000128 +#define CKA_PRIME 0x00000130 +#define CKA_SUBPRIME 0x00000131 +#define CKA_BASE 0x00000132 + +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */ +#define CKA_PRIME_BITS 0x00000133 +#define CKA_SUBPRIME_BITS 0x00000134 +#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS +/* (To retain backwards-compatibility) */ + +#define CKA_VALUE_BITS 0x00000160 +#define CKA_VALUE_LEN 0x00000161 + +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS, + * and CKA_EC_POINT are new for v2.0 */ +#define CKA_EXTRACTABLE 0x00000162 +#define CKA_LOCAL 0x00000163 +#define CKA_NEVER_EXTRACTABLE 0x00000164 +#define CKA_ALWAYS_SENSITIVE 0x00000165 + +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */ +#define CKA_KEY_GEN_MECHANISM 0x00000166 + +#define CKA_MODIFIABLE 0x00000170 + +/* CKA_ECDSA_PARAMS is deprecated in v2.11, + * CKA_EC_PARAMS is preferred. */ +#define CKA_ECDSA_PARAMS 0x00000180 +#define CKA_EC_PARAMS 0x00000180 + +#define CKA_EC_POINT 0x00000181 + +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, + * are new for v2.10. Deprecated in v2.11 and onwards. */ +#define CKA_SECONDARY_AUTH 0x00000200 +#define CKA_AUTH_PIN_FLAGS 0x00000201 + +/* CKA_ALWAYS_AUTHENTICATE ... + * CKA_UNWRAP_TEMPLATE are new for v2.20 */ +#define CKA_ALWAYS_AUTHENTICATE 0x00000202 + +#define CKA_WRAP_WITH_TRUSTED 0x00000210 +#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211) +#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212) + +/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */ +#define CKA_OTP_FORMAT 0x00000220 +#define CKA_OTP_LENGTH 0x00000221 +#define CKA_OTP_TIME_INTERVAL 0x00000222 +#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223 +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224 +#define CKA_OTP_TIME_REQUIREMENT 0x00000225 +#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226 +#define CKA_OTP_PIN_REQUIREMENT 0x00000227 +#define CKA_OTP_COUNTER 0x0000022E +#define CKA_OTP_TIME 0x0000022F +#define CKA_OTP_USER_IDENTIFIER 0x0000022A +#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022B +#define CKA_OTP_SERVICE_LOGO 0x0000022C +#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022D + + +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET + * are new for v2.10 */ +#define CKA_HW_FEATURE_TYPE 0x00000300 +#define CKA_RESET_ON_INIT 0x00000301 +#define CKA_HAS_RESET 0x00000302 + +/* The following attributes are new for v2.20 */ +#define CKA_PIXEL_X 0x00000400 +#define CKA_PIXEL_Y 0x00000401 +#define CKA_RESOLUTION 0x00000402 +#define CKA_CHAR_ROWS 0x00000403 +#define CKA_CHAR_COLUMNS 0x00000404 +#define CKA_COLOR 0x00000405 +#define CKA_BITS_PER_PIXEL 0x00000406 +#define CKA_CHAR_SETS 0x00000480 +#define CKA_ENCODING_METHODS 0x00000481 +#define CKA_MIME_TYPES 0x00000482 +#define CKA_MECHANISM_TYPE 0x00000500 +#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501 +#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502 +#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503 +#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600) + +#define CKA_VENDOR_DEFINED 0x80000000 + +/* CK_ATTRIBUTE is a structure that includes the type, length + * and value of an attribute */ +typedef struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + + /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulValueLen; /* in bytes */ +} CK_ATTRIBUTE; + +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; + + +/* CK_DATE is a structure that defines a date */ +typedef struct CK_DATE{ + CK_CHAR year[4]; /* the year ("1900" - "9999") */ + CK_CHAR month[2]; /* the month ("01" - "12") */ + CK_CHAR day[2]; /* the day ("01" - "31") */ +} CK_DATE; + + +/* CK_MECHANISM_TYPE is a value that identifies a mechanism + * type */ +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for + * v2.0 */ +typedef CK_ULONG CK_MECHANISM_TYPE; + +/* the following mechanism types are defined: */ +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 +#define CKM_RSA_PKCS 0x00000001 +#define CKM_RSA_9796 0x00000002 +#define CKM_RSA_X_509 0x00000003 + +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS + * are new for v2.0. They are mechanisms which hash and sign */ +#define CKM_MD2_RSA_PKCS 0x00000004 +#define CKM_MD5_RSA_PKCS 0x00000005 +#define CKM_SHA1_RSA_PKCS 0x00000006 + +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and + * CKM_RSA_PKCS_OAEP are new for v2.10 */ +#define CKM_RIPEMD128_RSA_PKCS 0x00000007 +#define CKM_RIPEMD160_RSA_PKCS 0x00000008 +#define CKM_RSA_PKCS_OAEP 0x00000009 + +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31, + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */ +#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A +#define CKM_RSA_X9_31 0x0000000B +#define CKM_SHA1_RSA_X9_31 0x0000000C +#define CKM_RSA_PKCS_PSS 0x0000000D +#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E + +#define CKM_DSA_KEY_PAIR_GEN 0x00000010 +#define CKM_DSA 0x00000011 +#define CKM_DSA_SHA1 0x00000012 +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 +#define CKM_DH_PKCS_DERIVE 0x00000021 + +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE, + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for + * v2.11 */ +#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 +#define CKM_X9_42_DH_DERIVE 0x00000031 +#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 +#define CKM_X9_42_MQV_DERIVE 0x00000033 + +/* CKM_SHA256/384/512 are new for v2.20 */ +#define CKM_SHA256_RSA_PKCS 0x00000040 +#define CKM_SHA384_RSA_PKCS 0x00000041 +#define CKM_SHA512_RSA_PKCS 0x00000042 +#define CKM_SHA256_RSA_PKCS_PSS 0x00000043 +#define CKM_SHA384_RSA_PKCS_PSS 0x00000044 +#define CKM_SHA512_RSA_PKCS_PSS 0x00000045 + +/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */ +#define CKM_SHA224_RSA_PKCS 0x00000046 +#define CKM_SHA224_RSA_PKCS_PSS 0x00000047 + +#define CKM_RC2_KEY_GEN 0x00000100 +#define CKM_RC2_ECB 0x00000101 +#define CKM_RC2_CBC 0x00000102 +#define CKM_RC2_MAC 0x00000103 + +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ +#define CKM_RC2_MAC_GENERAL 0x00000104 +#define CKM_RC2_CBC_PAD 0x00000105 + +#define CKM_RC4_KEY_GEN 0x00000110 +#define CKM_RC4 0x00000111 +#define CKM_DES_KEY_GEN 0x00000120 +#define CKM_DES_ECB 0x00000121 +#define CKM_DES_CBC 0x00000122 +#define CKM_DES_MAC 0x00000123 + +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ +#define CKM_DES_MAC_GENERAL 0x00000124 +#define CKM_DES_CBC_PAD 0x00000125 + +#define CKM_DES2_KEY_GEN 0x00000130 +#define CKM_DES3_KEY_GEN 0x00000131 +#define CKM_DES3_ECB 0x00000132 +#define CKM_DES3_CBC 0x00000133 +#define CKM_DES3_MAC 0x00000134 + +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */ +#define CKM_DES3_MAC_GENERAL 0x00000135 +#define CKM_DES3_CBC_PAD 0x00000136 +#define CKM_CDMF_KEY_GEN 0x00000140 +#define CKM_CDMF_ECB 0x00000141 +#define CKM_CDMF_CBC 0x00000142 +#define CKM_CDMF_MAC 0x00000143 +#define CKM_CDMF_MAC_GENERAL 0x00000144 +#define CKM_CDMF_CBC_PAD 0x00000145 + +/* the following four DES mechanisms are new for v2.20 */ +#define CKM_DES_OFB64 0x00000150 +#define CKM_DES_OFB8 0x00000151 +#define CKM_DES_CFB64 0x00000152 +#define CKM_DES_CFB8 0x00000153 + +#define CKM_MD2 0x00000200 + +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ +#define CKM_MD2_HMAC 0x00000201 +#define CKM_MD2_HMAC_GENERAL 0x00000202 + +#define CKM_MD5 0x00000210 + +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ +#define CKM_MD5_HMAC 0x00000211 +#define CKM_MD5_HMAC_GENERAL 0x00000212 + +#define CKM_SHA_1 0x00000220 + +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ +#define CKM_SHA_1_HMAC 0x00000221 +#define CKM_SHA_1_HMAC_GENERAL 0x00000222 + +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC, + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC, + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */ +#define CKM_RIPEMD128 0x00000230 +#define CKM_RIPEMD128_HMAC 0x00000231 +#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 +#define CKM_RIPEMD160 0x00000240 +#define CKM_RIPEMD160_HMAC 0x00000241 +#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 + +/* CKM_SHA256/384/512 are new for v2.20 */ +#define CKM_SHA256 0x00000250 +#define CKM_SHA256_HMAC 0x00000251 +#define CKM_SHA256_HMAC_GENERAL 0x00000252 + +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ +#define CKM_SHA224 0x00000255 +#define CKM_SHA224_HMAC 0x00000256 +#define CKM_SHA224_HMAC_GENERAL 0x00000257 + +#define CKM_SHA384 0x00000260 +#define CKM_SHA384_HMAC 0x00000261 +#define CKM_SHA384_HMAC_GENERAL 0x00000262 +#define CKM_SHA512 0x00000270 +#define CKM_SHA512_HMAC 0x00000271 +#define CKM_SHA512_HMAC_GENERAL 0x00000272 + +/* SecurID is new for PKCS #11 v2.20 amendment 1 */ +#define CKM_SECURID_KEY_GEN 0x00000280 +#define CKM_SECURID 0x00000282 + +/* HOTP is new for PKCS #11 v2.20 amendment 1 */ +#define CKM_HOTP_KEY_GEN 0x00000290 +#define CKM_HOTP 0x00000291 + +/* ACTI is new for PKCS #11 v2.20 amendment 1 */ +#define CKM_ACTI 0x000002A0 +#define CKM_ACTI_KEY_GEN 0x000002A1 + +/* All of the following mechanisms are new for v2.0 */ +/* Note that CAST128 and CAST5 are the same algorithm */ +#define CKM_CAST_KEY_GEN 0x00000300 +#define CKM_CAST_ECB 0x00000301 +#define CKM_CAST_CBC 0x00000302 +#define CKM_CAST_MAC 0x00000303 +#define CKM_CAST_MAC_GENERAL 0x00000304 +#define CKM_CAST_CBC_PAD 0x00000305 +#define CKM_CAST3_KEY_GEN 0x00000310 +#define CKM_CAST3_ECB 0x00000311 +#define CKM_CAST3_CBC 0x00000312 +#define CKM_CAST3_MAC 0x00000313 +#define CKM_CAST3_MAC_GENERAL 0x00000314 +#define CKM_CAST3_CBC_PAD 0x00000315 +#define CKM_CAST5_KEY_GEN 0x00000320 +#define CKM_CAST128_KEY_GEN 0x00000320 +#define CKM_CAST5_ECB 0x00000321 +#define CKM_CAST128_ECB 0x00000321 +#define CKM_CAST5_CBC 0x00000322 +#define CKM_CAST128_CBC 0x00000322 +#define CKM_CAST5_MAC 0x00000323 +#define CKM_CAST128_MAC 0x00000323 +#define CKM_CAST5_MAC_GENERAL 0x00000324 +#define CKM_CAST128_MAC_GENERAL 0x00000324 +#define CKM_CAST5_CBC_PAD 0x00000325 +#define CKM_CAST128_CBC_PAD 0x00000325 +#define CKM_RC5_KEY_GEN 0x00000330 +#define CKM_RC5_ECB 0x00000331 +#define CKM_RC5_CBC 0x00000332 +#define CKM_RC5_MAC 0x00000333 +#define CKM_RC5_MAC_GENERAL 0x00000334 +#define CKM_RC5_CBC_PAD 0x00000335 +#define CKM_IDEA_KEY_GEN 0x00000340 +#define CKM_IDEA_ECB 0x00000341 +#define CKM_IDEA_CBC 0x00000342 +#define CKM_IDEA_MAC 0x00000343 +#define CKM_IDEA_MAC_GENERAL 0x00000344 +#define CKM_IDEA_CBC_PAD 0x00000345 +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 +#define CKM_XOR_BASE_AND_DATA 0x00000364 +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 + +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN, + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */ +#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 +#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 +#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 +#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 + +/* CKM_TLS_PRF is new for v2.20 */ +#define CKM_TLS_PRF 0x00000378 + +#define CKM_SSL3_MD5_MAC 0x00000380 +#define CKM_SSL3_SHA1_MAC 0x00000381 +#define CKM_MD5_KEY_DERIVATION 0x00000390 +#define CKM_MD2_KEY_DERIVATION 0x00000391 +#define CKM_SHA1_KEY_DERIVATION 0x00000392 + +/* CKM_SHA256/384/512 are new for v2.20 */ +#define CKM_SHA256_KEY_DERIVATION 0x00000393 +#define CKM_SHA384_KEY_DERIVATION 0x00000394 +#define CKM_SHA512_KEY_DERIVATION 0x00000395 + +/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */ +#define CKM_SHA224_KEY_DERIVATION 0x00000396 + +#define CKM_PBE_MD2_DES_CBC 0x000003A0 +#define CKM_PBE_MD5_DES_CBC 0x000003A1 +#define CKM_PBE_MD5_CAST_CBC 0x000003A2 +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3 +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4 +#define CKM_PBE_MD5_CAST128_CBC 0x000003A4 +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 +#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 +#define CKM_PBE_SHA1_RC4_128 0x000003A6 +#define CKM_PBE_SHA1_RC4_40 0x000003A7 +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB + +/* CKM_PKCS5_PBKD2 is new for v2.10 */ +#define CKM_PKCS5_PBKD2 0x000003B0 + +#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 + +/* WTLS mechanisms are new for v2.20 */ +#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0 +#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2 +#define CKM_WTLS_PRF 0x000003D3 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5 + +#define CKM_KEY_WRAP_LYNKS 0x00000400 +#define CKM_KEY_WRAP_SET_OAEP 0x00000401 + +/* CKM_CMS_SIG is new for v2.20 */ +#define CKM_CMS_SIG 0x00000500 + +/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */ +#define CKM_KIP_DERIVE 0x00000510 +#define CKM_KIP_WRAP 0x00000511 +#define CKM_KIP_MAC 0x00000512 + +/* Camellia is new for PKCS #11 v2.20 amendment 3 */ +#define CKM_CAMELLIA_KEY_GEN 0x00000550 +#define CKM_CAMELLIA_ECB 0x00000551 +#define CKM_CAMELLIA_CBC 0x00000552 +#define CKM_CAMELLIA_MAC 0x00000553 +#define CKM_CAMELLIA_MAC_GENERAL 0x00000554 +#define CKM_CAMELLIA_CBC_PAD 0x00000555 +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556 +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557 +#define CKM_CAMELLIA_CTR 0x00000558 + +/* ARIA is new for PKCS #11 v2.20 amendment 3 */ +#define CKM_ARIA_KEY_GEN 0x00000560 +#define CKM_ARIA_ECB 0x00000561 +#define CKM_ARIA_CBC 0x00000562 +#define CKM_ARIA_MAC 0x00000563 +#define CKM_ARIA_MAC_GENERAL 0x00000564 +#define CKM_ARIA_CBC_PAD 0x00000565 +#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566 +#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567 + +/* Fortezza mechanisms */ +#define CKM_SKIPJACK_KEY_GEN 0x00001000 +#define CKM_SKIPJACK_ECB64 0x00001001 +#define CKM_SKIPJACK_CBC64 0x00001002 +#define CKM_SKIPJACK_OFB64 0x00001003 +#define CKM_SKIPJACK_CFB64 0x00001004 +#define CKM_SKIPJACK_CFB32 0x00001005 +#define CKM_SKIPJACK_CFB16 0x00001006 +#define CKM_SKIPJACK_CFB8 0x00001007 +#define CKM_SKIPJACK_WRAP 0x00001008 +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 +#define CKM_SKIPJACK_RELAYX 0x0000100a +#define CKM_KEA_KEY_PAIR_GEN 0x00001010 +#define CKM_KEA_KEY_DERIVE 0x00001011 +#define CKM_FORTEZZA_TIMESTAMP 0x00001020 +#define CKM_BATON_KEY_GEN 0x00001030 +#define CKM_BATON_ECB128 0x00001031 +#define CKM_BATON_ECB96 0x00001032 +#define CKM_BATON_CBC128 0x00001033 +#define CKM_BATON_COUNTER 0x00001034 +#define CKM_BATON_SHUFFLE 0x00001035 +#define CKM_BATON_WRAP 0x00001036 + +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, + * CKM_EC_KEY_PAIR_GEN is preferred */ +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 +#define CKM_EC_KEY_PAIR_GEN 0x00001040 + +#define CKM_ECDSA 0x00001041 +#define CKM_ECDSA_SHA1 0x00001042 + +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE + * are new for v2.11 */ +#define CKM_ECDH1_DERIVE 0x00001050 +#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051 +#define CKM_ECMQV_DERIVE 0x00001052 + +#define CKM_JUNIPER_KEY_GEN 0x00001060 +#define CKM_JUNIPER_ECB128 0x00001061 +#define CKM_JUNIPER_CBC128 0x00001062 +#define CKM_JUNIPER_COUNTER 0x00001063 +#define CKM_JUNIPER_SHUFFLE 0x00001064 +#define CKM_JUNIPER_WRAP 0x00001065 +#define CKM_FASTHASH 0x00001070 + +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC, + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN, + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are + * new for v2.11 */ +#define CKM_AES_KEY_GEN 0x00001080 +#define CKM_AES_ECB 0x00001081 +#define CKM_AES_CBC 0x00001082 +#define CKM_AES_MAC 0x00001083 +#define CKM_AES_MAC_GENERAL 0x00001084 +#define CKM_AES_CBC_PAD 0x00001085 + +/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */ +#define CKM_AES_CTR 0x00001086 + +/* BlowFish and TwoFish are new for v2.20 */ +#define CKM_BLOWFISH_KEY_GEN 0x00001090 +#define CKM_BLOWFISH_CBC 0x00001091 +#define CKM_TWOFISH_KEY_GEN 0x00001092 +#define CKM_TWOFISH_CBC 0x00001093 + + +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */ +#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100 +#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101 +#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102 +#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103 +#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104 +#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105 + +#define CKM_DSA_PARAMETER_GEN 0x00002000 +#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 +#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002 + +#define CKM_VENDOR_DEFINED 0x80000000 + +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; + + +/* CK_MECHANISM is a structure that specifies a particular + * mechanism */ +typedef struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + + /* ulParameterLen was changed from CK_USHORT to CK_ULONG for + * v2.0 */ + CK_ULONG ulParameterLen; /* in bytes */ +} CK_MECHANISM; + +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; + + +/* CK_MECHANISM_INFO provides information about a particular + * mechanism */ +typedef struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +} CK_MECHANISM_INFO; + +/* The flags are defined as follows: + * Bit Flag Mask Meaning */ +#define CKF_HW 0x00000001 /* performed by HW */ + +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, + * and CKF_DERIVE are new for v2.0. They specify whether or not + * a mechanism can be used for a particular task */ +#define CKF_ENCRYPT 0x00000100 +#define CKF_DECRYPT 0x00000200 +#define CKF_DIGEST 0x00000400 +#define CKF_SIGN 0x00000800 +#define CKF_SIGN_RECOVER 0x00001000 +#define CKF_VERIFY 0x00002000 +#define CKF_VERIFY_RECOVER 0x00004000 +#define CKF_GENERATE 0x00008000 +#define CKF_GENERATE_KEY_PAIR 0x00010000 +#define CKF_WRAP 0x00020000 +#define CKF_UNWRAP 0x00040000 +#define CKF_DERIVE 0x00080000 + +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE, + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They + * describe a token's EC capabilities not available in mechanism + * information. */ +#define CKF_EC_F_P 0x00100000 +#define CKF_EC_F_2M 0x00200000 +#define CKF_EC_ECPARAMETERS 0x00400000 +#define CKF_EC_NAMEDCURVE 0x00800000 +#define CKF_EC_UNCOMPRESS 0x01000000 +#define CKF_EC_COMPRESS 0x02000000 + +#define CKF_EXTENSION 0x80000000 /* FALSE for this version */ + +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; + + +/* CK_RV is a value that identifies the return value of a + * Cryptoki function */ +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_RV; + +#define CKR_OK 0x00000000 +#define CKR_CANCEL 0x00000001 +#define CKR_HOST_MEMORY 0x00000002 +#define CKR_SLOT_ID_INVALID 0x00000003 + +/* CKR_FLAGS_INVALID was removed for v2.0 */ + +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ +#define CKR_GENERAL_ERROR 0x00000005 +#define CKR_FUNCTION_FAILED 0x00000006 + +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, + * and CKR_CANT_LOCK are new for v2.01 */ +#define CKR_ARGUMENTS_BAD 0x00000007 +#define CKR_NO_EVENT 0x00000008 +#define CKR_NEED_TO_CREATE_THREADS 0x00000009 +#define CKR_CANT_LOCK 0x0000000A + +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010 +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011 +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012 +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013 +#define CKR_DATA_INVALID 0x00000020 +#define CKR_DATA_LEN_RANGE 0x00000021 +#define CKR_DEVICE_ERROR 0x00000030 +#define CKR_DEVICE_MEMORY 0x00000031 +#define CKR_DEVICE_REMOVED 0x00000032 +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040 +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041 +#define CKR_FUNCTION_CANCELED 0x00000050 +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051 + +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054 + +#define CKR_KEY_HANDLE_INVALID 0x00000060 + +/* CKR_KEY_SENSITIVE was removed for v2.0 */ + +#define CKR_KEY_SIZE_RANGE 0x00000062 +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063 + +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for + * v2.0 */ +#define CKR_KEY_NOT_NEEDED 0x00000064 +#define CKR_KEY_CHANGED 0x00000065 +#define CKR_KEY_NEEDED 0x00000066 +#define CKR_KEY_INDIGESTIBLE 0x00000067 +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068 +#define CKR_KEY_NOT_WRAPPABLE 0x00000069 +#define CKR_KEY_UNEXTRACTABLE 0x0000006A + +#define CKR_MECHANISM_INVALID 0x00000070 +#define CKR_MECHANISM_PARAM_INVALID 0x00000071 + +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID + * were removed for v2.0 */ +#define CKR_OBJECT_HANDLE_INVALID 0x00000082 +#define CKR_OPERATION_ACTIVE 0x00000090 +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091 +#define CKR_PIN_INCORRECT 0x000000A0 +#define CKR_PIN_INVALID 0x000000A1 +#define CKR_PIN_LEN_RANGE 0x000000A2 + +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ +#define CKR_PIN_EXPIRED 0x000000A3 +#define CKR_PIN_LOCKED 0x000000A4 + +#define CKR_SESSION_CLOSED 0x000000B0 +#define CKR_SESSION_COUNT 0x000000B1 +#define CKR_SESSION_HANDLE_INVALID 0x000000B3 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4 +#define CKR_SESSION_READ_ONLY 0x000000B5 +#define CKR_SESSION_EXISTS 0x000000B6 + +/* CKR_SESSION_READ_ONLY_EXISTS and + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */ +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7 +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8 + +#define CKR_SIGNATURE_INVALID 0x000000C0 +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1 +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0 +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1 +#define CKR_TOKEN_NOT_PRESENT 0x000000E0 +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1 +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2 +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100 +#define CKR_USER_NOT_LOGGED_IN 0x00000101 +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102 +#define CKR_USER_TYPE_INVALID 0x00000103 + +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES + * are new to v2.01 */ +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104 +#define CKR_USER_TOO_MANY_TYPES 0x00000105 + +#define CKR_WRAPPED_KEY_INVALID 0x00000110 +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112 +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113 +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115 +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120 + +/* These are new to v2.0 */ +#define CKR_RANDOM_NO_RNG 0x00000121 + +/* These are new to v2.11 */ +#define CKR_DOMAIN_PARAMS_INVALID 0x00000130 + +/* These are new to v2.0 */ +#define CKR_BUFFER_TOO_SMALL 0x00000150 +#define CKR_SAVED_STATE_INVALID 0x00000160 +#define CKR_INFORMATION_SENSITIVE 0x00000170 +#define CKR_STATE_UNSAVEABLE 0x00000180 + +/* These are new to v2.01 */ +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191 +#define CKR_MUTEX_BAD 0x000001A0 +#define CKR_MUTEX_NOT_LOCKED 0x000001A1 + +/* The following return values are new for PKCS #11 v2.20 amendment 3 */ +#define CKR_NEW_PIN_MODE 0x000001B0 +#define CKR_NEXT_OTP 0x000001B1 + +/* This is new to v2.20 */ +#define CKR_FUNCTION_REJECTED 0x00000200 + +#define CKR_VENDOR_DEFINED 0x80000000 + + +/* CK_NOTIFY is an application callback that processes events */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_NOTIFICATION event, + CK_VOID_PTR pApplication /* passed to C_OpenSession */ +); + + +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec + * version and pointers of appropriate types to all the + * Cryptoki functions */ +/* CK_FUNCTION_LIST is new for v2.0 */ +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; + +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; + +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; + + +/* CK_CREATEMUTEX is an application callback for creating a + * mutex object */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( + CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ +); + + +/* CK_DESTROYMUTEX is an application callback for destroying a + * mutex object */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_LOCKMUTEX is an application callback for locking a mutex */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_UNLOCKMUTEX is an application callback for unlocking a + * mutex */ +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_C_INITIALIZE_ARGS provides the optional arguments to + * C_Initialize */ +typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; +} CK_C_INITIALIZE_ARGS; + +/* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 +#define CKF_OS_LOCKING_OK 0x00000002 + +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; + + +/* additional flags for parameters to functions */ + +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ +#define CKF_DONT_BLOCK 1 + +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10. + * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message + * Generation Function (MGF) applied to a message block when + * formatting a message block for the PKCS #1 OAEP encryption + * scheme. */ +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; + +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; + +/* The following MGFs are defined */ +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512 + * are new for v2.20 */ +#define CKG_MGF1_SHA1 0x00000001 +#define CKG_MGF1_SHA256 0x00000002 +#define CKG_MGF1_SHA384 0x00000003 +#define CKG_MGF1_SHA512 0x00000004 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ +#define CKG_MGF1_SHA224 0x00000005 + +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10. + * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source + * of the encoding parameter when formatting a message block + * for the PKCS #1 OAEP encryption scheme. */ +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; + +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; + +/* The following encoding parameter sources are defined */ +#define CKZ_DATA_SPECIFIED 0x00000001 + +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10. + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the + * CKM_RSA_PKCS_OAEP mechanism. */ +typedef struct CK_RSA_PKCS_OAEP_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_RSA_PKCS_OAEP_SOURCE_TYPE source; + CK_VOID_PTR pSourceData; + CK_ULONG ulSourceDataLen; +} CK_RSA_PKCS_OAEP_PARAMS; + +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; + +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11. + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the + * CKM_RSA_PKCS_PSS mechanism(s). */ +typedef struct CK_RSA_PKCS_PSS_PARAMS { + CK_MECHANISM_TYPE hashAlg; + CK_RSA_PKCS_MGF_TYPE mgf; + CK_ULONG sLen; +} CK_RSA_PKCS_PSS_PARAMS; + +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; + +/* CK_EC_KDF_TYPE is new for v2.11. */ +typedef CK_ULONG CK_EC_KDF_TYPE; + +/* The following EC Key Derivation Functions are defined */ +#define CKD_NULL 0x00000001 +#define CKD_SHA1_KDF 0x00000002 + +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11. + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, + * where each party contributes one key pair. + */ +typedef struct CK_ECDH1_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_ECDH1_DERIVE_PARAMS; + +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; + + +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11. + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */ +typedef struct CK_ECDH2_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; +} CK_ECDH2_DERIVE_PARAMS; + +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; + +typedef struct CK_ECMQV_DERIVE_PARAMS { + CK_EC_KDF_TYPE kdf; + CK_ULONG ulSharedDataLen; + CK_BYTE_PTR pSharedData; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_ECMQV_DERIVE_PARAMS; + +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; + +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */ +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; + +/* The following X9.42 DH key derivation functions are defined + (besides CKD_NULL already defined : */ +#define CKD_SHA1_KDF_ASN1 0x00000003 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004 + +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11. + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party + * contributes one key pair */ +typedef struct CK_X9_42_DH1_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_X9_42_DH1_DERIVE_PARAMS; + +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; + +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11. + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation + * mechanisms, where each party contributes two key pairs */ +typedef struct CK_X9_42_DH2_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; +} CK_X9_42_DH2_DERIVE_PARAMS; + +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; + +typedef struct CK_X9_42_MQV_DERIVE_PARAMS { + CK_X9_42_DH_KDF_TYPE kdf; + CK_ULONG ulOtherInfoLen; + CK_BYTE_PTR pOtherInfo; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPrivateDataLen; + CK_OBJECT_HANDLE hPrivateData; + CK_ULONG ulPublicDataLen2; + CK_BYTE_PTR pPublicData2; + CK_OBJECT_HANDLE publicKey; +} CK_X9_42_MQV_DERIVE_PARAMS; + +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; + +/* CK_KEA_DERIVE_PARAMS provides the parameters to the + * CKM_KEA_DERIVE mechanism */ +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */ +typedef struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pRandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_KEA_DERIVE_PARAMS; + +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; + + +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and + * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just + * holds the effective keysize */ +typedef CK_ULONG CK_RC2_PARAMS; + +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; + + +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC + * mechanism */ +typedef struct CK_RC2_CBC_PARAMS { + /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for + * v2.0 */ + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + + CK_BYTE iv[8]; /* IV for CBC mode */ +} CK_RC2_CBC_PARAMS; + +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; + + +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC2_MAC_GENERAL mechanism */ +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC2_MAC_GENERAL_PARAMS; + +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC2_MAC_GENERAL_PARAMS_PTR; + + +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and + * CKM_RC5_MAC mechanisms */ +/* CK_RC5_PARAMS is new for v2.0 */ +typedef struct CK_RC5_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ +} CK_RC5_PARAMS; + +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; + + +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC + * mechanism */ +/* CK_RC5_CBC_PARAMS is new for v2.0 */ +typedef struct CK_RC5_CBC_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_BYTE_PTR pIv; /* pointer to IV */ + CK_ULONG ulIvLen; /* length of IV in bytes */ +} CK_RC5_CBC_PARAMS; + +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; + + +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the + * CKM_RC5_MAC_GENERAL mechanism */ +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC5_MAC_GENERAL_PARAMS; + +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ + CK_RC5_MAC_GENERAL_PARAMS_PTR; + + +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block + * ciphers' MAC_GENERAL mechanisms. Its value is the length of + * the MAC */ +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef CK_ULONG CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; + +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */ +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[8]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_DES_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_AES_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; + +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pPrimeP; + CK_BYTE_PTR pBaseG; + CK_BYTE_PTR pSubprimeQ; +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; + +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ + CK_SKIPJACK_PRIVATE_WRAP_PTR; + + +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the + * CKM_SKIPJACK_RELAYX mechanism */ +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ +typedef struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE_PTR pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE_PTR pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE_PTR pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE_PTR pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE_PTR pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE_PTR pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE_PTR pNewRandomA; +} CK_SKIPJACK_RELAYX_PARAMS; + +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ + CK_SKIPJACK_RELAYX_PARAMS_PTR; + + +typedef struct CK_PBE_PARAMS { + CK_BYTE_PTR pInitVector; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; +} CK_PBE_PARAMS; + +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; + + +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the + * CKM_KEY_WRAP_SET_OAEP mechanism */ +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; /* block contents byte */ + CK_BYTE_PTR pX; /* extra data */ + CK_ULONG ulXLen; /* length of extra data in bytes */ +} CK_KEY_WRAP_SET_OAEP_PARAMS; + +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \ + CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; + + +typedef struct CK_SSL3_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; +} CK_SSL3_RANDOM_DATA; + + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; + + +typedef struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE_PTR pIVClient; + CK_BYTE_PTR pIVServer; +} CK_SSL3_KEY_MAT_OUT; + +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; + + +typedef struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; +} CK_SSL3_KEY_MAT_PARAMS; + +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; + +/* CK_TLS_PRF_PARAMS is new for version 2.20 */ +typedef struct CK_TLS_PRF_PARAMS { + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; +} CK_TLS_PRF_PARAMS; + +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; + +/* WTLS is new for version 2.20 */ +typedef struct CK_WTLS_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; +} CK_WTLS_RANDOM_DATA; + +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; + +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_BYTE_PTR pVersion; +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS; + +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; + +typedef struct CK_WTLS_PRF_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; + CK_BYTE_PTR pLabel; + CK_ULONG ulLabelLen; + CK_BYTE_PTR pOutput; + CK_ULONG_PTR pulOutputLen; +} CK_WTLS_PRF_PARAMS; + +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; + +typedef struct CK_WTLS_KEY_MAT_OUT { + CK_OBJECT_HANDLE hMacSecret; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pIV; +} CK_WTLS_KEY_MAT_OUT; + +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; + +typedef struct CK_WTLS_KEY_MAT_PARAMS { + CK_MECHANISM_TYPE DigestMechanism; + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_ULONG ulSequenceNumber; + CK_BBOOL bIsExport; + CK_WTLS_RANDOM_DATA RandomInfo; + CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; +} CK_WTLS_KEY_MAT_PARAMS; + +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; + +/* CMS is new for version 2.20 */ +typedef struct CK_CMS_SIG_PARAMS { + CK_OBJECT_HANDLE certificateHandle; + CK_MECHANISM_PTR pSigningMechanism; + CK_MECHANISM_PTR pDigestMechanism; + CK_UTF8CHAR_PTR pContentType; + CK_BYTE_PTR pRequestedAttributes; + CK_ULONG ulRequestedAttributesLen; + CK_BYTE_PTR pRequiredAttributes; + CK_ULONG ulRequiredAttributesLen; +} CK_CMS_SIG_PARAMS; + +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; + +typedef struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE_PTR pData; + CK_ULONG ulLen; +} CK_KEY_DERIVATION_STRING_DATA; + +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ + CK_KEY_DERIVATION_STRING_DATA_PTR; + + +/* The CK_EXTRACT_PARAMS is used for the + * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit + * of the base key should be used as the first bit of the + * derived key */ +/* CK_EXTRACT_PARAMS is new for v2.0 */ +typedef CK_ULONG CK_EXTRACT_PARAMS; + +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; + +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10. + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to + * indicate the Pseudo-Random Function (PRF) used to generate + * key bits using PKCS #5 PBKDF2. */ +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; + +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; + +/* The following PRFs are defined in PKCS #5 v2.0. */ +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001 + + +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10. + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the + * source of the salt value when deriving a key using PKCS #5 + * PBKDF2. */ +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; + +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; + +/* The following salt value sources are defined in PKCS #5 v2.0. */ +#define CKZ_SALT_SPECIFIED 0x00000001 + +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10. + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the + * parameters to the CKM_PKCS5_PBKD2 mechanism. */ +typedef struct CK_PKCS5_PBKD2_PARAMS { + CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; + CK_VOID_PTR pSaltSourceData; + CK_ULONG ulSaltSourceDataLen; + CK_ULONG iterations; + CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; + CK_VOID_PTR pPrfData; + CK_ULONG ulPrfDataLen; + CK_UTF8CHAR_PTR pPassword; + CK_ULONG_PTR ulPasswordLen; +} CK_PKCS5_PBKD2_PARAMS; + +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; + +/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */ + +typedef CK_ULONG CK_OTP_PARAM_TYPE; +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */ + +typedef struct CK_OTP_PARAM { + CK_OTP_PARAM_TYPE type; + CK_VOID_PTR pValue; + CK_ULONG ulValueLen; +} CK_OTP_PARAM; + +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; + +typedef struct CK_OTP_PARAMS { + CK_OTP_PARAM_PTR pParams; + CK_ULONG ulCount; +} CK_OTP_PARAMS; + +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; + +typedef struct CK_OTP_SIGNATURE_INFO { + CK_OTP_PARAM_PTR pParams; + CK_ULONG ulCount; +} CK_OTP_SIGNATURE_INFO; + +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; + +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ +#define CK_OTP_VALUE 0 +#define CK_OTP_PIN 1 +#define CK_OTP_CHALLENGE 2 +#define CK_OTP_TIME 3 +#define CK_OTP_COUNTER 4 +#define CK_OTP_FLAGS 5 +#define CK_OTP_OUTPUT_LENGTH 6 +#define CK_OTP_OUTPUT_FORMAT 7 + +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ +#define CKF_NEXT_OTP 0x00000001 +#define CKF_EXCLUDE_TIME 0x00000002 +#define CKF_EXCLUDE_COUNTER 0x00000004 +#define CKF_EXCLUDE_CHALLENGE 0x00000008 +#define CKF_EXCLUDE_PIN 0x00000010 +#define CKF_USER_FRIENDLY_OTP 0x00000020 + +/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */ +typedef struct CK_KIP_PARAMS { + CK_MECHANISM_PTR pMechanism; + CK_OBJECT_HANDLE hKey; + CK_BYTE_PTR pSeed; + CK_ULONG ulSeedLen; +} CK_KIP_PARAMS; + +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; + +/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ +typedef struct CK_AES_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +} CK_AES_CTR_PARAMS; + +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; + +/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ +typedef struct CK_CAMELLIA_CTR_PARAMS { + CK_ULONG ulCounterBits; + CK_BYTE cb[16]; +} CK_CAMELLIA_CTR_PARAMS; + +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; + +/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + +/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { + CK_BYTE iv[16]; + CK_BYTE_PTR pData; + CK_ULONG length; +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; + +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; + +#endif diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/softhsm.conf b/Godeps/_workspace/src/github.com/miekg/pkcs11/softhsm.conf new file mode 100644 index 00000000000..f95862b1046 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/softhsm.conf @@ -0,0 +1 @@ +0:hsm.db diff --git a/Godeps/_workspace/src/github.com/miekg/pkcs11/types.go b/Godeps/_workspace/src/github.com/miekg/pkcs11/types.go new file mode 100644 index 00000000000..9a709cd8518 --- /dev/null +++ b/Godeps/_workspace/src/github.com/miekg/pkcs11/types.go @@ -0,0 +1,274 @@ +// Copyright 2013 Miek Gieben. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkcs11 + +/* +#define CK_PTR * +#ifndef NULL_PTR +#define NULL_PTR 0 +#endif +#define CK_DEFINE_FUNCTION(returnType, name) returnType name +#define CK_DECLARE_FUNCTION(returnType, name) returnType name +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name) +#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name) + +#include +#include "pkcs11.h" + +CK_ULONG Index(CK_ULONG_PTR array, CK_ULONG i) +{ + return array[i]; +} + +CK_ULONG Sizeof() +{ + return sizeof(CK_ULONG); +} +*/ +import "C" + +import ( + "fmt" + "time" + "unsafe" +) + +// toList converts from a C style array to a []uint. +func toList(clist C.CK_ULONG_PTR, size C.CK_ULONG) []uint { + l := make([]uint, int(size)) + for i := 0; i < len(l); i++ { + l[i] = uint(C.Index(clist, C.CK_ULONG(i))) + } + defer C.free(unsafe.Pointer(clist)) + return l +} + +// cBBool converts a bool to a CK_BBOOL. +func cBBool(x bool) C.CK_BBOOL { + if x { + return C.CK_BBOOL(C.CK_TRUE) + } + return C.CK_BBOOL(C.CK_FALSE) +} + +// Error represents an PKCS#11 error. +type Error uint + +func (e Error) Error() string { + return fmt.Sprintf("pkcs11: 0x%X: %s", uint(e), strerror[uint(e)]) +} + +func toError(e C.CK_RV) error { + if e == C.CKR_OK { + return nil + } + return Error(e) +} + +/* SessionHandle is a Cryptoki-assigned value that identifies a session. */ +type SessionHandle uint + +/* ObjectHandle is a token-specific identifier for an object. */ +type ObjectHandle uint + +// Version represents any version information from the library. +type Version struct { + Major byte + Minor byte +} + +func toVersion(version C.CK_VERSION) Version { + return Version{byte(version.major), byte(version.minor)} +} + +// SlotEvent holds the SlotID which for which an slot event (token insertion, +// removal, etc.) occurred. +type SlotEvent struct { + SlotID uint +} + +// Info provides information about the library and hardware used. +type Info struct { + CryptokiVersion Version + ManufacturerID string + Flags uint + LibraryDescription string + LibraryVersion Version +} + +/* SlotInfo provides information about a slot. */ +type SlotInfo struct { + SlotDescription string // 64 bytes. + ManufacturerID string // 32 bytes. + Flags uint + HardwareVersion Version + FirmwareVersion Version +} + +/* TokenInfo provides information about a token. */ +type TokenInfo struct { + Label string + ManufacturerID string + Model string + SerialNumber string + Flags uint + MaxSessionCount uint + SessionCount uint + MaxRwSessionCount uint + RwSessionCount uint + MaxPinLen uint + MinPinLen uint + TotalPublicMemory uint + FreePublicMemory uint + TotalPrivateMemory uint + FreePrivateMemory uint + HardwareVersion Version + FirmwareVersion Version + UTCTime string +} + +/* SesionInfo provides information about a session. */ +type SessionInfo struct { + SlotID uint + State uint + Flags uint + DeviceError uint +} + +// Attribute holds an attribute type/value combination. +type Attribute struct { + Type uint + Value []byte +} + +// NewAttribute allocates a Attribute and returns a pointer to it. +// Note that this is merely a convience function, as values returned +// from the HSM are not converted back to Go values, those are just raw +// byte slices. +func NewAttribute(typ uint, x interface{}) *Attribute { + // This function nicely transforms *to* an attribute, but there is + // no corresponding function that transform back *from* an attribute, + // which in PKCS#11 is just an byte array. + a := new(Attribute) + a.Type = typ + if x == nil { + return a + } + switch x.(type) { + case bool: // create bbool + if x.(bool) { + a.Value = []byte{1} + break + } + a.Value = []byte{0} + case uint, int: + var y uint + if _, ok := x.(int); ok { + y = uint(x.(int)) + } + if _, ok := x.(uint); ok { + y = x.(uint) + } + // TODO(miek): ugly! + switch int(C.Sizeof()) { + case 4: + a.Value = make([]byte, 4) + a.Value[0] = byte(y) + a.Value[1] = byte(y >> 8) + a.Value[2] = byte(y >> 16) + a.Value[3] = byte(y >> 24) + case 8: + a.Value = make([]byte, 8) + a.Value[0] = byte(y) + a.Value[1] = byte(y >> 8) + a.Value[2] = byte(y >> 16) + a.Value[3] = byte(y >> 24) + a.Value[4] = byte(y >> 32) + a.Value[5] = byte(y >> 40) + a.Value[6] = byte(y >> 48) + a.Value[7] = byte(y >> 56) + } + case string: + a.Value = []byte(x.(string)) + case []byte: // just copy + a.Value = x.([]byte) + case time.Time: // for CKA_DATE + a.Value = cDate(x.(time.Time)) + default: + panic("pkcs11: unhandled attribute type") + } + return a +} + +// cAttribute returns the start address and the length of an attribute list. +func cAttributeList(a []*Attribute) (C.CK_ATTRIBUTE_PTR, C.CK_ULONG) { + if len(a) == 0 { + return nil, 0 + } + pa := make([]C.CK_ATTRIBUTE, len(a)) + for i := 0; i < len(a); i++ { + pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type) + if a[i].Value == nil { + continue + } + pa[i].pValue = C.CK_VOID_PTR((&a[i].Value[0])) + pa[i].ulValueLen = C.CK_ULONG(len(a[i].Value)) + } + return C.CK_ATTRIBUTE_PTR(&pa[0]), C.CK_ULONG(len(a)) +} + +func cDate(t time.Time) []byte { + b := make([]byte, 8) + year, month, day := t.Date() + y := fmt.Sprintf("%4d", year) + m := fmt.Sprintf("%02d", month) + d1 := fmt.Sprintf("%02d", day) + b[0], b[1], b[2], b[3] = y[0], y[1], y[2], y[3] + b[4], b[5] = m[0], m[1] + b[6], b[7] = d1[0], d1[1] + return b +} + +// Mechanism holds an mechanism type/value combination. +type Mechanism struct { + Mechanism uint + Parameter []byte +} + +func NewMechanism(mech uint, x interface{}) *Mechanism { + m := new(Mechanism) + m.Mechanism = mech + if x == nil { + return m + } + + // Add any parameters passed (For now presume always bytes were passed in, is there another case?) + m.Parameter = x.([]byte) + + return m +} + +func cMechanismList(m []*Mechanism) (C.CK_MECHANISM_PTR, C.CK_ULONG) { + if len(m) == 0 { + return nil, 0 + } + pm := make([]C.CK_MECHANISM, len(m)) + for i := 0; i < len(m); i++ { + pm[i].mechanism = C.CK_MECHANISM_TYPE(m[i].Mechanism) + if m[i].Parameter == nil { + continue + } + pm[i].pParameter = C.CK_VOID_PTR(&(m[i].Parameter[0])) + pm[i].ulParameterLen = C.CK_ULONG(len(m[i].Parameter)) + } + return C.CK_MECHANISM_PTR(&pm[0]), C.CK_ULONG(len(m)) +} + +// MechanismInfo provides information about a particular mechanism. +type MechanismInfo struct { + MinKeySize uint + MaxKeySize uint + Flags uint +} diff --git a/README.md b/README.md index ff701097735..784514a9361 100644 --- a/README.md +++ b/README.md @@ -101,11 +101,25 @@ All dependencies are vendorized under the Godeps directory, both to [make dependency management easier](https://groups.google.com/forum/m/#!topic/golang-dev/nMWoEAG55v8) and to [avoid insecure fallback in go -get](https://github.com/golang/go/issues/9637). To update dependencies: +get](https://github.com/golang/go/issues/9637). + +We need to use the build tag 'pkcs11' to really pull in all our dependencies. +To do this, you'll need to pull and install this godep branch, which supports +build tags: https://github.com/tools/godep/pull/117/files. NOTE: If you skip +this step, godep will delete some of the vendorized depdendencies. + +To update dependencies: ``` # Disable insecure fallback by blocking port 80. sudo /sbin/iptables -A OUTPUT -p tcp --dport 80 -j DROP +# Fetch godep +go get https://github.com/tools/godep.git +# Pull in the tags branch and install +cd $GOPATH/src/github.com/tools/godep +git pull https://github.com/jnfeinstein/godep.git jnfeinstein +go install + # Update to the latest version of a dependency. Alternately you can cd to the # directory under GOPATH and check out a specific revision. go get -u github.com/cloudflare/cfssl/... @@ -113,7 +127,7 @@ go get -u github.com/cloudflare/cfssl/... godep update github.com/cloudflare/cfssl/... # Save the dependencies, rewriting any internal or external dependencies that # may have been added. -godep save -r ./... +godep save -r -tags pkcs11 ./... git add Godeps git commit # Assuming you had no other iptables rules, re-enable port 80.