vendor: github.com/moby/swarmkit/v2 v2.0.0-20230808164555-1983e41a9fff
notable changes: - Free unused volumes in more cases - Convert BasicKeyRequest to KeyRequest to use cloudflare/cfssl 1.x.x - reduce direct imports of logrus diffs: - github.com/cloudflare/cfssl v1.6.4; full diff: https://github.com/cloudflare/cfssl/compare/5d63dbd981b5...v1.6.4 - github.com/moby/swarmkit/v2; full diff: https://github.com/moby/swarmkit/compare/bc71908479e5...60421a63a7f148ba1ec7d35c55e4cf9ac03d6b78 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
7b66ae1531
commit
b9d9504df5
385 changed files with 49935 additions and 316 deletions
|
@ -969,7 +969,7 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *testing.T) {
|
|||
if i%2 != 0 {
|
||||
cert, _, key, err = initca.New(&csr.CertificateRequest{
|
||||
CN: "newRoot",
|
||||
KeyRequest: csr.NewBasicKeyRequest(),
|
||||
KeyRequest: csr.NewKeyRequest(),
|
||||
CA: &csr.CAConfig{Expiry: ca.RootCAExpiration},
|
||||
})
|
||||
assert.NilError(c, err)
|
||||
|
|
|
@ -23,7 +23,7 @@ require (
|
|||
github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.15.17
|
||||
github.com/aws/smithy-go v1.13.5
|
||||
github.com/bsphere/le_go v0.0.0-20200109081728-fc06dab2caa8
|
||||
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
|
||||
github.com/cloudflare/cfssl v1.6.4
|
||||
github.com/container-orchestrated-devices/container-device-interface v0.6.0
|
||||
github.com/containerd/cgroups/v3 v3.0.2
|
||||
github.com/containerd/containerd v1.6.22
|
||||
|
@ -65,7 +65,7 @@ require (
|
|||
github.com/moby/locker v1.0.1
|
||||
github.com/moby/patternmatcher v0.5.0
|
||||
github.com/moby/pubsub v1.0.0
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230713153928-bc71908479e5
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230814163642-60421a63a7f1
|
||||
github.com/moby/sys/mount v0.3.3
|
||||
github.com/moby/sys/mountinfo v0.6.2
|
||||
github.com/moby/sys/sequential v0.5.0
|
||||
|
@ -158,6 +158,7 @@ require (
|
|||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.3 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
|
@ -176,6 +177,9 @@ require (
|
|||
github.com/tonistiigi/fsutil v0.0.0-20230629203738-36ef4d8c0dbb // indirect
|
||||
github.com/tonistiigi/go-actions-cache v0.0.0-20220404170428-0bdeb6e1eac7 // indirect
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b // indirect
|
||||
github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc // indirect
|
||||
github.com/zmap/zlint/v3 v3.1.0 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.6 // indirect
|
||||
go.etcd.io/etcd/raft/v3 v3.5.6 // indirect
|
||||
|
|
25
vendor.sum
25
vendor.sum
|
@ -293,8 +293,8 @@ github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnx
|
|||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 h1:PqZ3bA4yzwywivzk7PBQWngJp2/PAS0bWRZerKteicY=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/cfssl v1.6.4 h1:NMOvfrEjFfC63K3SGXgAnFdsgkmiq4kATme5BfcqrO8=
|
||||
github.com/cloudflare/cfssl v1.6.4/go.mod h1:8b3CQMxfWPAeom3zBnGJ6sd+G1NkL5TXqmDXacb+1J0=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
|
@ -895,6 +895,8 @@ github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeY
|
|||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jmoiron/sqlx v1.3.3 h1:j82X0bf7oQ27XeqxicSZsTU5suPwKElg3oyxNn43iTk=
|
||||
github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
|
@ -975,6 +977,7 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
|
|||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
|
@ -1022,8 +1025,8 @@ github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M
|
|||
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/pubsub v1.0.0 h1:jkp/imWsmJz2f6LyFsk7EkVeN2HxR/HTTOY8kHrsxfA=
|
||||
github.com/moby/pubsub v1.0.0/go.mod h1:bXSO+3h5MNXXCaEG+6/NlAIk7MMZbySZlnB+cUQhKKc=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230713153928-bc71908479e5 h1:o6x+wIX1vKD0kJlEqe8M9TLIe0SK8lnGcA6XoJtaFqg=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230713153928-bc71908479e5/go.mod h1:XUMlwIIC+wrwBDMUjxEvk5Z8FPoIPM8LdBw7w/Zu1rg=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230814163642-60421a63a7f1 h1:B/mrXLRdSVXXJvwVNatNe+Yf+9WMS/TT7+mYKFMbgF0=
|
||||
github.com/moby/swarmkit/v2 v2.0.0-20230814163642-60421a63a7f1/go.mod h1:qYvjIScIddAio4DaXFZUyNuRxcHhm2Srm6GIrA/G/5c=
|
||||
github.com/moby/sys/mount v0.1.0/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
|
||||
github.com/moby/sys/mount v0.1.1/go.mod h1:FVQFLDRWwyBjDTBNQXDlWnSFREqOo3OKX9aqhmeoo74=
|
||||
github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs=
|
||||
|
@ -1054,6 +1057,7 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
|||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||
github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
|
||||
github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
|
||||
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
|
@ -1264,6 +1268,7 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
|
@ -1395,6 +1400,9 @@ github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1
|
|||
github.com/vishvananda/netns v0.0.2 h1:Cn05BRLm+iRP/DZxyVSsfVyrzgjDbwHwkVt38qvXnNI=
|
||||
github.com/vishvananda/netns v0.0.2/go.mod h1:yitZXdAVI+yPFSb4QUe+VW3vOVl4PZPNcBgbPxAtJxw=
|
||||
github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||
github.com/weppos/publicsuffix-go v0.13.1-0.20210123135404-5fd73613514e/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE=
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b h1:FsyNrX12e5BkplJq7wKOLk0+C6LZ+KGXvuEcKUYm5ss=
|
||||
github.com/weppos/publicsuffix-go v0.15.1-0.20210511084619-b1f36a2d6c0b/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE=
|
||||
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
|
||||
github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug=
|
||||
|
@ -1418,6 +1426,13 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
|
|||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
|
||||
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
|
||||
github.com/zmap/zcrypto v0.0.0-20210123152837-9cf5beac6d91/go.mod h1:R/deQh6+tSWlgI9tb4jNmXxn8nSCabl5ZQsBX9//I/E=
|
||||
github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc h1:zkGwegkOW709y0oiAraH/3D8njopUR/pARHv4tZZ6pw=
|
||||
github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc/go.mod h1:FM4U1E3NzlNMRnSUTU3P1UdukWhYGifqEsjk9fn7BCk=
|
||||
github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0=
|
||||
github.com/zmap/zlint/v3 v3.1.0/go.mod h1:L7t8s3sEKkb0A2BxGy1IWrxt1ZATa1R4QfJZaQOD3zU=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||
|
@ -1525,6 +1540,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
|
@ -1735,6 +1751,7 @@ golang.org/x/sys v0.0.0-20201013081832-0aaa2718063a/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
6
vendor/github.com/cloudflare/cfssl/api/api.go
generated
vendored
6
vendor/github.com/cloudflare/cfssl/api/api.go
generated
vendored
|
@ -3,7 +3,7 @@ package api
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/cloudflare/cfssl/errors"
|
||||
|
@ -92,7 +92,7 @@ func (h HTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
func readRequestBlob(r *http.Request) (map[string]string, error) {
|
||||
var blob map[string]string
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ type Response struct {
|
|||
Messages []ResponseMessage `json:"messages"`
|
||||
}
|
||||
|
||||
// NewSuccessResponse is a shortcut for creating new successul API
|
||||
// NewSuccessResponse is a shortcut for creating new successful API
|
||||
// responses.
|
||||
func NewSuccessResponse(result interface{}) Response {
|
||||
return Response{
|
||||
|
|
5
vendor/github.com/cloudflare/cfssl/auth/auth.go
generated
vendored
5
vendor/github.com/cloudflare/cfssl/auth/auth.go
generated
vendored
|
@ -10,7 +10,6 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
@ -52,11 +51,11 @@ func New(key string, ad []byte) (*Standard, error) {
|
|||
case "env":
|
||||
key = os.Getenv(splitKey[1])
|
||||
case "file":
|
||||
data, err := ioutil.ReadFile(splitKey[1])
|
||||
data, err := os.ReadFile(splitKey[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = string(data)
|
||||
key = strings.TrimSpace(string(data))
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown key prefix: %s", splitKey[0])
|
||||
}
|
||||
|
|
12
vendor/github.com/cloudflare/cfssl/certdb/README.md
generated
vendored
12
vendor/github.com/cloudflare/cfssl/certdb/README.md
generated
vendored
|
@ -27,11 +27,11 @@ Currently supported:
|
|||
### Use goose to start and terminate a MySQL DB
|
||||
To start a MySQL using goose:
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql up
|
||||
goose -path certdb/mysql up
|
||||
|
||||
To tear down a MySQL DB using goose
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/mysql down
|
||||
goose -path certdb/mysql down
|
||||
|
||||
Note: the administration of MySQL DB is not included. We assume
|
||||
the databases being connected to are already created and access control
|
||||
|
@ -40,11 +40,11 @@ is properly handled.
|
|||
### Use goose to start and terminate a PostgreSQL DB
|
||||
To start a PostgreSQL using goose:
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg up
|
||||
goose -path certdb/pg up
|
||||
|
||||
To tear down a PostgreSQL DB using goose
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/pg down
|
||||
goose -path certdb/pg down
|
||||
|
||||
Note: the administration of PostgreSQL DB is not included. We assume
|
||||
the databases being connected to are already created and access control
|
||||
|
@ -53,11 +53,11 @@ is properly handled.
|
|||
### Use goose to start and terminate a SQLite DB
|
||||
To start a SQLite DB using goose:
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite up
|
||||
goose -path certdb/sqlite up
|
||||
|
||||
To tear down a SQLite DB using goose
|
||||
|
||||
goose -path $GOPATH/src/github.com/cloudflare/cfssl/certdb/sqlite down
|
||||
goose -path certdb/sqlite down
|
||||
|
||||
## CFSSL Configuration
|
||||
|
||||
|
|
46
vendor/github.com/cloudflare/cfssl/certdb/certdb.go
generated
vendored
46
vendor/github.com/cloudflare/cfssl/certdb/certdb.go
generated
vendored
|
@ -1,7 +1,11 @@
|
|||
package certdb
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx/types"
|
||||
)
|
||||
|
||||
// CertificateRecord encodes a certificate and its metadata
|
||||
|
@ -15,6 +19,46 @@ type CertificateRecord struct {
|
|||
Expiry time.Time `db:"expiry"`
|
||||
RevokedAt time.Time `db:"revoked_at"`
|
||||
PEM string `db:"pem"`
|
||||
// the following fields will be empty for data inserted before migrate 002 has been run.
|
||||
IssuedAt *time.Time `db:"issued_at"`
|
||||
NotBefore *time.Time `db:"not_before"`
|
||||
MetadataJSON types.JSONText `db:"metadata"`
|
||||
SANsJSON types.JSONText `db:"sans"`
|
||||
CommonName sql.NullString `db:"common_name"`
|
||||
}
|
||||
|
||||
// SetMetadata sets the metadata json
|
||||
func (c *CertificateRecord) SetMetadata(meta map[string]interface{}) error {
|
||||
marshaled, err := json.Marshal(meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.MetadataJSON = types.JSONText(marshaled)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMetadata returns the json metadata
|
||||
func (c *CertificateRecord) GetMetadata() (map[string]interface{}, error) {
|
||||
var meta map[string]interface{}
|
||||
err := c.MetadataJSON.Unmarshal(&meta)
|
||||
return meta, err
|
||||
}
|
||||
|
||||
// SetSANs sets the list of sans
|
||||
func (c *CertificateRecord) SetSANs(meta []string) error {
|
||||
marshaled, err := json.Marshal(meta)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.SANsJSON = types.JSONText(marshaled)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSANs returns the json SANs
|
||||
func (c *CertificateRecord) GetSANs() ([]string, error) {
|
||||
var sans []string
|
||||
err := c.SANsJSON.Unmarshal(&sans)
|
||||
return sans, err
|
||||
}
|
||||
|
||||
// OCSPRecord encodes a OCSP response body and its metadata
|
||||
|
@ -32,7 +76,9 @@ type Accessor interface {
|
|||
GetCertificate(serial, aki string) ([]CertificateRecord, error)
|
||||
GetUnexpiredCertificates() ([]CertificateRecord, error)
|
||||
GetRevokedAndUnexpiredCertificates() ([]CertificateRecord, error)
|
||||
GetUnexpiredCertificatesByLabel(labels []string) (crs []CertificateRecord, err error)
|
||||
GetRevokedAndUnexpiredCertificatesByLabel(label string) ([]CertificateRecord, error)
|
||||
GetRevokedAndUnexpiredCertificatesByLabelSelectColumns(label string) ([]CertificateRecord, error)
|
||||
RevokeCertificate(serial, aki string, reasonCode int) error
|
||||
InsertOCSP(rr OCSPRecord) error
|
||||
GetOCSP(serial, aki string) ([]OCSPRecord, error)
|
||||
|
|
96
vendor/github.com/cloudflare/cfssl/config/config.go
generated
vendored
96
vendor/github.com/cloudflare/cfssl/config/config.go
generated
vendored
|
@ -8,7 +8,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -19,6 +19,9 @@ import (
|
|||
"github.com/cloudflare/cfssl/helpers"
|
||||
"github.com/cloudflare/cfssl/log"
|
||||
ocspConfig "github.com/cloudflare/cfssl/ocsp/config"
|
||||
// empty import of zlint/v3 required to have lints registered.
|
||||
_ "github.com/zmap/zlint/v3"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
)
|
||||
|
||||
// A CSRWhitelist stores booleans for fields in the CSR. If a CSRWhitelist is
|
||||
|
@ -32,7 +35,7 @@ import (
|
|||
// mechanism.
|
||||
type CSRWhitelist struct {
|
||||
Subject, PublicKeyAlgorithm, PublicKey, SignatureAlgorithm bool
|
||||
DNSNames, IPAddresses, EmailAddresses bool
|
||||
DNSNames, IPAddresses, EmailAddresses, URIs bool
|
||||
}
|
||||
|
||||
// OID is our own version of asn1's ObjectIdentifier, so we can define a custom
|
||||
|
@ -81,6 +84,8 @@ type SigningProfile struct {
|
|||
ExpiryString string `json:"expiry"`
|
||||
BackdateString string `json:"backdate"`
|
||||
AuthKeyName string `json:"auth_key"`
|
||||
CopyExtensions bool `json:"copy_extensions"`
|
||||
PrevAuthKeyName string `json:"prev_auth_key"` // to support key rotation
|
||||
RemoteName string `json:"remote"`
|
||||
NotBefore time.Time `json:"not_before"`
|
||||
NotAfter time.Time `json:"not_after"`
|
||||
|
@ -89,11 +94,26 @@ type SigningProfile struct {
|
|||
CTLogServers []string `json:"ct_log_servers"`
|
||||
AllowedExtensions []OID `json:"allowed_extensions"`
|
||||
CertStore string `json:"cert_store"`
|
||||
// LintErrLevel controls preissuance linting for the signing profile.
|
||||
// 0 = no linting is performed [default]
|
||||
// 2..3 = reserved
|
||||
// 3 = all lint results except pass are considered errors
|
||||
// 4 = all lint results except pass and notice are considered errors
|
||||
// 5 = all lint results except pass, notice and warn are considered errors
|
||||
// 6 = all lint results except pass, notice, warn and error are considered errors.
|
||||
// 7 = lint is performed, no lint results are treated as errors.
|
||||
LintErrLevel lint.LintStatus `json:"lint_error_level"`
|
||||
// ExcludeLints lists ZLint lint names to exclude from preissuance linting.
|
||||
ExcludeLints []string `json:"ignored_lints"`
|
||||
// ExcludeLintSources lists ZLint lint sources to exclude from preissuance
|
||||
// linting.
|
||||
ExcludeLintSources []string `json:"ignored_lint_sources"`
|
||||
|
||||
Policies []CertificatePolicy
|
||||
Expiry time.Duration
|
||||
Backdate time.Duration
|
||||
Provider auth.Provider
|
||||
PrevProvider auth.Provider // to suppport key rotation
|
||||
RemoteProvider auth.Provider
|
||||
RemoteServer string
|
||||
RemoteCAs *x509.CertPool
|
||||
|
@ -102,6 +122,11 @@ type SigningProfile struct {
|
|||
NameWhitelist *regexp.Regexp
|
||||
ExtensionWhitelist map[string]bool
|
||||
ClientProvidesSerialNumbers bool
|
||||
// LintRegistry is the collection of lints that should be used if
|
||||
// LintErrLevel is configured. By default all ZLint lints are used. If
|
||||
// ExcludeLints or ExcludeLintSources are set then this registry will be
|
||||
// filtered in populate() to exclude the named lints and lint sources.
|
||||
LintRegistry lint.Registry
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals a JSON string into an OID.
|
||||
|
@ -229,7 +254,7 @@ func (p *SigningProfile) populate(cfg *Config) error {
|
|||
|
||||
if p.AuthKeyName != "" {
|
||||
log.Debug("match auth key in profile to auth_keys section")
|
||||
if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok == true {
|
||||
if key, ok := cfg.AuthKeys[p.AuthKeyName]; ok {
|
||||
if key.Type == "standard" {
|
||||
p.Provider, err = auth.New(key.Key, nil)
|
||||
if err != nil {
|
||||
|
@ -248,6 +273,27 @@ func (p *SigningProfile) populate(cfg *Config) error {
|
|||
}
|
||||
}
|
||||
|
||||
if p.PrevAuthKeyName != "" {
|
||||
log.Debug("match previous auth key in profile to auth_keys section")
|
||||
if key, ok := cfg.AuthKeys[p.PrevAuthKeyName]; ok {
|
||||
if key.Type == "standard" {
|
||||
p.PrevProvider, err = auth.New(key.Key, nil)
|
||||
if err != nil {
|
||||
log.Debugf("failed to create new standard auth provider: %v", err)
|
||||
return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
|
||||
errors.New("failed to create new standard auth provider"))
|
||||
}
|
||||
} else {
|
||||
log.Debugf("unknown authentication type %v", key.Type)
|
||||
return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
|
||||
errors.New("unknown authentication type"))
|
||||
}
|
||||
} else {
|
||||
return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
|
||||
errors.New("failed to find prev_auth_key in auth_keys section"))
|
||||
}
|
||||
}
|
||||
|
||||
if p.AuthRemote.AuthKeyName != "" {
|
||||
log.Debug("match auth remote key in profile to auth_keys section")
|
||||
if key, ok := cfg.AuthKeys[p.AuthRemote.AuthKeyName]; ok == true {
|
||||
|
@ -284,6 +330,40 @@ func (p *SigningProfile) populate(cfg *Config) error {
|
|||
p.ExtensionWhitelist[asn1.ObjectIdentifier(oid).String()] = true
|
||||
}
|
||||
|
||||
// By default perform any required preissuance linting with all ZLint lints.
|
||||
p.LintRegistry = lint.GlobalRegistry()
|
||||
|
||||
// If ExcludeLintSources are present in config build a lint.SourceList while
|
||||
// validating that no unknown sources were specified.
|
||||
var excludedSources lint.SourceList
|
||||
if len(p.ExcludeLintSources) > 0 {
|
||||
for _, sourceName := range p.ExcludeLintSources {
|
||||
var lintSource lint.LintSource
|
||||
lintSource.FromString(sourceName)
|
||||
if lintSource == lint.UnknownLintSource {
|
||||
return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
|
||||
fmt.Errorf("failed to build excluded lint source list: unknown source %q",
|
||||
sourceName))
|
||||
}
|
||||
excludedSources = append(excludedSources, lintSource)
|
||||
}
|
||||
}
|
||||
|
||||
opts := lint.FilterOptions{
|
||||
ExcludeNames: p.ExcludeLints,
|
||||
ExcludeSources: excludedSources,
|
||||
}
|
||||
if !opts.Empty() {
|
||||
// If ExcludeLints or ExcludeLintSources were not empty then filter out the
|
||||
// lints we don't want to use for preissuance linting with this profile.
|
||||
filteredRegistry, err := p.LintRegistry.Filter(opts)
|
||||
if err != nil {
|
||||
return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy,
|
||||
fmt.Errorf("failed to build filtered lint registry: %v", err))
|
||||
}
|
||||
p.LintRegistry = filteredRegistry
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -404,7 +484,8 @@ func (p *SigningProfile) Usages() (ku x509.KeyUsage, eku []x509.ExtKeyUsage, unk
|
|||
// valid local default profile has defined at least a default expiration.
|
||||
// A valid remote profile (default or not) has remote signer initialized.
|
||||
// In addition, a remote profile must has a valid auth provider if auth
|
||||
// key defined.
|
||||
// key defined. A valid profile must not include a lint_error_level outside of
|
||||
// [0,8).
|
||||
func (p *SigningProfile) validProfile(isDefault bool) bool {
|
||||
if p == nil {
|
||||
return false
|
||||
|
@ -461,6 +542,11 @@ func (p *SigningProfile) validProfile(isDefault bool) bool {
|
|||
}
|
||||
}
|
||||
|
||||
if p.LintErrLevel < 0 || p.LintErrLevel >= 8 {
|
||||
log.Debugf("invalid profile: lint_error_level outside of range [0,8)")
|
||||
return false
|
||||
}
|
||||
|
||||
log.Debugf("profile is valid")
|
||||
return true
|
||||
}
|
||||
|
@ -613,7 +699,7 @@ func LoadFile(path string) (*Config, error) {
|
|||
return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("invalid path"))
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadFile(path)
|
||||
body, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, errors.New("could not read configuration file"))
|
||||
}
|
||||
|
|
27
vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go
generated
vendored
27
vendor/github.com/cloudflare/cfssl/crypto/pkcs7/pkcs7.go
generated
vendored
|
@ -3,17 +3,17 @@
|
|||
// to PKCS #7 format from another encoding such as PEM conforms to this implementation.
|
||||
// reference: https://www.openssl.org/docs/man1.1.0/apps/crl2pkcs7.html
|
||||
//
|
||||
// PKCS #7 Data type, reference: https://tools.ietf.org/html/rfc2315
|
||||
// PKCS #7 Data type, reference: https://tools.ietf.org/html/rfc2315
|
||||
//
|
||||
// The full pkcs#7 cryptographic message syntax allows for cryptographic enhancements,
|
||||
// for example data can be encrypted and signed and then packaged through pkcs#7 to be
|
||||
// sent over a network and then verified and decrypted. It is asn1, and the type of
|
||||
// PKCS #7 ContentInfo, which comprises the PKCS #7 structure, is:
|
||||
//
|
||||
// ContentInfo ::= SEQUENCE {
|
||||
// contentType ContentType,
|
||||
// content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
|
||||
// }
|
||||
// ContentInfo ::= SEQUENCE {
|
||||
// contentType ContentType,
|
||||
// content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
|
||||
// }
|
||||
//
|
||||
// There are 6 possible ContentTypes, data, signedData, envelopedData,
|
||||
// signedAndEnvelopedData, digestedData, and encryptedData. Here signedData, Data, and encrypted
|
||||
|
@ -22,15 +22,14 @@
|
|||
// formats.
|
||||
// The ContentType signedData has the form:
|
||||
//
|
||||
//
|
||||
// signedData ::= SEQUENCE {
|
||||
// version Version,
|
||||
// digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
// contentInfo ContentInfo,
|
||||
// certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL
|
||||
// crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
// signerInfos SignerInfos
|
||||
// }
|
||||
// signedData ::= SEQUENCE {
|
||||
// version Version,
|
||||
// digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
// contentInfo ContentInfo,
|
||||
// certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL
|
||||
// crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
|
||||
// signerInfos SignerInfos
|
||||
// }
|
||||
//
|
||||
// As of yet signerInfos and digestAlgorithms are not parsed, as they are not relevant to
|
||||
// this system's use of PKCS #7 data. Version is an integer type, note that PKCS #7 is
|
||||
|
|
145
vendor/github.com/cloudflare/cfssl/csr/csr.go
generated
vendored
145
vendor/github.com/cloudflare/cfssl/csr/csr.go
generated
vendored
|
@ -12,8 +12,11 @@ import (
|
|||
"encoding/asn1"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
cferr "github.com/cloudflare/cfssl/errors"
|
||||
|
@ -29,46 +32,40 @@ const (
|
|||
|
||||
// A Name contains the SubjectInfo fields.
|
||||
type Name struct {
|
||||
C string // Country
|
||||
ST string // State
|
||||
L string // Locality
|
||||
O string // OrganisationName
|
||||
OU string // OrganisationalUnitName
|
||||
SerialNumber string
|
||||
C string `json:"C,omitempty" yaml:"C,omitempty"` // Country
|
||||
ST string `json:"ST,omitempty" yaml:"ST,omitempty"` // State
|
||||
L string `json:"L,omitempty" yaml:"L,omitempty"` // Locality
|
||||
O string `json:"O,omitempty" yaml:"O,omitempty"` // OrganisationName
|
||||
OU string `json:"OU,omitempty" yaml:"OU,omitempty"` // OrganisationalUnitName
|
||||
E string `json:"E,omitempty" yaml:"E,omitempty"`
|
||||
SerialNumber string `json:"SerialNumber,omitempty" yaml:"SerialNumber,omitempty"`
|
||||
OID map[string]string `json:"OID,omitempty", yaml:"OID,omitempty"`
|
||||
}
|
||||
|
||||
// A KeyRequest is a generic request for a new key.
|
||||
type KeyRequest interface {
|
||||
Algo() string
|
||||
Size() int
|
||||
Generate() (crypto.PrivateKey, error)
|
||||
SigAlgo() x509.SignatureAlgorithm
|
||||
}
|
||||
|
||||
// A BasicKeyRequest contains the algorithm and key size for a new private key.
|
||||
type BasicKeyRequest struct {
|
||||
// A KeyRequest contains the algorithm and key size for a new private key.
|
||||
type KeyRequest struct {
|
||||
A string `json:"algo" yaml:"algo"`
|
||||
S int `json:"size" yaml:"size"`
|
||||
}
|
||||
|
||||
// NewBasicKeyRequest returns a default BasicKeyRequest.
|
||||
func NewBasicKeyRequest() *BasicKeyRequest {
|
||||
return &BasicKeyRequest{"ecdsa", curveP256}
|
||||
// NewKeyRequest returns a default KeyRequest.
|
||||
func NewKeyRequest() *KeyRequest {
|
||||
return &KeyRequest{"ecdsa", curveP256}
|
||||
}
|
||||
|
||||
// Algo returns the requested key algorithm represented as a string.
|
||||
func (kr *BasicKeyRequest) Algo() string {
|
||||
func (kr *KeyRequest) Algo() string {
|
||||
return kr.A
|
||||
}
|
||||
|
||||
// Size returns the requested key size.
|
||||
func (kr *BasicKeyRequest) Size() int {
|
||||
func (kr *KeyRequest) Size() int {
|
||||
return kr.S
|
||||
}
|
||||
|
||||
// Generate generates a key as specified in the request. Currently,
|
||||
// only ECDSA and RSA are supported.
|
||||
func (kr *BasicKeyRequest) Generate() (crypto.PrivateKey, error) {
|
||||
func (kr *KeyRequest) Generate() (crypto.PrivateKey, error) {
|
||||
log.Debugf("generate key from request: algo=%s, size=%d", kr.Algo(), kr.Size())
|
||||
switch kr.Algo() {
|
||||
case "rsa":
|
||||
|
@ -99,7 +96,7 @@ func (kr *BasicKeyRequest) Generate() (crypto.PrivateKey, error) {
|
|||
|
||||
// SigAlgo returns an appropriate X.509 signature algorithm given the
|
||||
// key request's type and size.
|
||||
func (kr *BasicKeyRequest) SigAlgo() x509.SignatureAlgorithm {
|
||||
func (kr *KeyRequest) SigAlgo() x509.SignatureAlgorithm {
|
||||
switch kr.Algo() {
|
||||
case "rsa":
|
||||
switch {
|
||||
|
@ -139,19 +136,22 @@ type CAConfig struct {
|
|||
// A CertificateRequest encapsulates the API interface to the
|
||||
// certificate request functionality.
|
||||
type CertificateRequest struct {
|
||||
CN string
|
||||
Names []Name `json:"names" yaml:"names"`
|
||||
Hosts []string `json:"hosts" yaml:"hosts"`
|
||||
KeyRequest KeyRequest `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
CA *CAConfig `json:"ca,omitempty" yaml:"ca,omitempty"`
|
||||
SerialNumber string `json:"serialnumber,omitempty" yaml:"serialnumber,omitempty"`
|
||||
CN string `json:"CN" yaml:"CN"`
|
||||
Names []Name `json:"names" yaml:"names"`
|
||||
Hosts []string `json:"hosts" yaml:"hosts"`
|
||||
KeyRequest *KeyRequest `json:"key,omitempty" yaml:"key,omitempty"`
|
||||
CA *CAConfig `json:"ca,omitempty" yaml:"ca,omitempty"`
|
||||
SerialNumber string `json:"serialnumber,omitempty" yaml:"serialnumber,omitempty"`
|
||||
DelegationEnabled bool `json:"delegation_enabled,omitempty" yaml:"delegation_enabled,omitempty"`
|
||||
Extensions []pkix.Extension `json:"extensions,omitempty" yaml:"extensions,omitempty"`
|
||||
CRL string `json:"crl_url,omitempty" yaml:"crl_url,omitempty"`
|
||||
}
|
||||
|
||||
// New returns a new, empty CertificateRequest with a
|
||||
// BasicKeyRequest.
|
||||
// KeyRequest.
|
||||
func New() *CertificateRequest {
|
||||
return &CertificateRequest{
|
||||
KeyRequest: NewBasicKeyRequest(),
|
||||
KeyRequest: NewKeyRequest(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,25 @@ func appendIf(s string, a *[]string) {
|
|||
}
|
||||
}
|
||||
|
||||
// OIDFromString creates an ASN1 ObjectIdentifier from its string representation
|
||||
func OIDFromString(s string) (asn1.ObjectIdentifier, error) {
|
||||
var oid []int
|
||||
parts := strings.Split(s, ".")
|
||||
if len(parts) < 1 {
|
||||
return oid, fmt.Errorf("invalid OID string: %s", s)
|
||||
}
|
||||
for _, p := range parts {
|
||||
i, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid OID part %s", p)
|
||||
}
|
||||
oid = append(oid, i)
|
||||
}
|
||||
return oid, nil
|
||||
}
|
||||
|
||||
// Name returns the PKIX name for the request.
|
||||
func (cr *CertificateRequest) Name() pkix.Name {
|
||||
func (cr *CertificateRequest) Name() (pkix.Name, error) {
|
||||
var name pkix.Name
|
||||
name.CommonName = cr.CN
|
||||
|
||||
|
@ -173,9 +190,19 @@ func (cr *CertificateRequest) Name() pkix.Name {
|
|||
appendIf(n.L, &name.Locality)
|
||||
appendIf(n.O, &name.Organization)
|
||||
appendIf(n.OU, &name.OrganizationalUnit)
|
||||
for k, v := range n.OID {
|
||||
oid, err := OIDFromString(k)
|
||||
if err != nil {
|
||||
return name, err
|
||||
}
|
||||
name.ExtraNames = append(name.ExtraNames, pkix.AttributeTypeAndValue{Type: oid, Value: v})
|
||||
}
|
||||
if n.E != "" {
|
||||
name.ExtraNames = append(name.ExtraNames, pkix.AttributeTypeAndValue{Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: n.E})
|
||||
}
|
||||
}
|
||||
name.SerialNumber = cr.SerialNumber
|
||||
return name
|
||||
return name, nil
|
||||
}
|
||||
|
||||
// BasicConstraints CSR information RFC 5280, 4.2.1.9
|
||||
|
@ -193,7 +220,7 @@ type BasicConstraints struct {
|
|||
func ParseRequest(req *CertificateRequest) (csr, key []byte, err error) {
|
||||
log.Info("received CSR")
|
||||
if req.KeyRequest == nil {
|
||||
req.KeyRequest = NewBasicKeyRequest()
|
||||
req.KeyRequest = NewKeyRequest()
|
||||
}
|
||||
|
||||
log.Infof("generating key: %s-%d", req.KeyRequest.Algo(), req.KeyRequest.Size())
|
||||
|
@ -268,14 +295,17 @@ func getHosts(cert *x509.Certificate) []string {
|
|||
for _, email := range cert.EmailAddresses {
|
||||
hosts = append(hosts, email)
|
||||
}
|
||||
for _, uri := range cert.URIs {
|
||||
hosts = append(hosts, uri.String())
|
||||
}
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
// getNames returns an array of Names from the certificate
|
||||
// It onnly cares about Country, Organization, OrganizationalUnit, Locality, Province
|
||||
// It only cares about Country, Organization, OrganizationalUnit, Locality, Province
|
||||
func getNames(sub pkix.Name) []Name {
|
||||
// anonymous func for finding the max of a list of interger
|
||||
// anonymous func for finding the max of a list of integer
|
||||
max := func(v1 int, vn ...int) (max int) {
|
||||
max = v1
|
||||
for i := 0; i < len(vn); i++ {
|
||||
|
@ -369,8 +399,13 @@ func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err erro
|
|||
return nil, cferr.New(cferr.PrivateKeyError, cferr.Unavailable)
|
||||
}
|
||||
|
||||
subj, err := req.Name()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tpl = x509.CertificateRequest{
|
||||
Subject: req.Name(),
|
||||
Subject: subj,
|
||||
SignatureAlgorithm: sigAlgo,
|
||||
}
|
||||
|
||||
|
@ -379,11 +414,15 @@ func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err erro
|
|||
tpl.IPAddresses = append(tpl.IPAddresses, ip)
|
||||
} else if email, err := mail.ParseAddress(req.Hosts[i]); err == nil && email != nil {
|
||||
tpl.EmailAddresses = append(tpl.EmailAddresses, email.Address)
|
||||
} else if uri, err := url.ParseRequestURI(req.Hosts[i]); err == nil && uri != nil {
|
||||
tpl.URIs = append(tpl.URIs, uri)
|
||||
} else {
|
||||
tpl.DNSNames = append(tpl.DNSNames, req.Hosts[i])
|
||||
}
|
||||
}
|
||||
|
||||
tpl.ExtraExtensions = []pkix.Extension{}
|
||||
|
||||
if req.CA != nil {
|
||||
err = appendCAInfoToCSR(req.CA, &tpl)
|
||||
if err != nil {
|
||||
|
@ -392,6 +431,18 @@ func Generate(priv crypto.Signer, req *CertificateRequest) (csr []byte, err erro
|
|||
}
|
||||
}
|
||||
|
||||
if req.DelegationEnabled {
|
||||
tpl.ExtraExtensions = append(tpl.Extensions, helpers.DelegationExtension)
|
||||
}
|
||||
|
||||
if req.Extensions != nil {
|
||||
err = appendExtensionsToCSR(req.Extensions, &tpl)
|
||||
if err != nil {
|
||||
err = cferr.Wrap(cferr.CSRError, cferr.GenerationFailed, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
csr, err = x509.CreateCertificateRequest(rand.Reader, &tpl, priv)
|
||||
if err != nil {
|
||||
log.Errorf("failed to generate a CSR: %v", err)
|
||||
|
@ -420,13 +471,19 @@ func appendCAInfoToCSR(reqConf *CAConfig, csr *x509.CertificateRequest) error {
|
|||
return err
|
||||
}
|
||||
|
||||
csr.ExtraExtensions = []pkix.Extension{
|
||||
{
|
||||
Id: asn1.ObjectIdentifier{2, 5, 29, 19},
|
||||
Value: val,
|
||||
Critical: true,
|
||||
},
|
||||
}
|
||||
csr.ExtraExtensions = append(csr.ExtraExtensions, pkix.Extension{
|
||||
Id: asn1.ObjectIdentifier{2, 5, 29, 19},
|
||||
Value: val,
|
||||
Critical: true,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// appendCAInfoToCSR appends user-defined extension to a CSR
|
||||
func appendExtensionsToCSR(extensions []pkix.Extension, csr *x509.CertificateRequest) error {
|
||||
for _, extension := range extensions {
|
||||
csr.ExtraExtensions = append(csr.ExtraExtensions, extension)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
1
vendor/github.com/cloudflare/cfssl/errors/doc.go
generated
vendored
1
vendor/github.com/cloudflare/cfssl/errors/doc.go
generated
vendored
|
@ -7,6 +7,7 @@ It formats to a json object that consists of an error message and a 4-digit code
|
|||
Example: {"code":1002, "message": "Failed to decode certificate"}
|
||||
|
||||
The index of codes are listed below:
|
||||
|
||||
1XXX: CertificateError
|
||||
1000: Unknown
|
||||
1001: ReadFailed
|
||||
|
|
22
vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go
generated
vendored
22
vendor/github.com/cloudflare/cfssl/helpers/derhelpers/derhelpers.go
generated
vendored
|
@ -5,14 +5,15 @@ package derhelpers
|
|||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
|
||||
cferr "github.com/cloudflare/cfssl/errors"
|
||||
)
|
||||
|
||||
// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, or elliptic curve
|
||||
// DER-encoded private key. The key must not be in PEM format.
|
||||
// ParsePrivateKeyDER parses a PKCS #1, PKCS #8, ECDSA, or Ed25519 DER-encoded
|
||||
// private key. The key must not be in PEM format.
|
||||
func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) {
|
||||
generalKey, err := x509.ParsePKCS8PrivateKey(keyDER)
|
||||
if err != nil {
|
||||
|
@ -20,12 +21,15 @@ func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) {
|
|||
if err != nil {
|
||||
generalKey, err = x509.ParseECPrivateKey(keyDER)
|
||||
if err != nil {
|
||||
// We don't include the actual error into
|
||||
// the final error. The reason might be
|
||||
// we don't want to leak any info about
|
||||
// the private key.
|
||||
return nil, cferr.New(cferr.PrivateKeyError,
|
||||
cferr.ParseFailed)
|
||||
generalKey, err = ParseEd25519PrivateKey(keyDER)
|
||||
if err != nil {
|
||||
// We don't include the actual error into
|
||||
// the final error. The reason might be
|
||||
// we don't want to leak any info about
|
||||
// the private key.
|
||||
return nil, cferr.New(cferr.PrivateKeyError,
|
||||
cferr.ParseFailed)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +39,8 @@ func ParsePrivateKeyDER(keyDER []byte) (key crypto.Signer, err error) {
|
|||
return generalKey.(*rsa.PrivateKey), nil
|
||||
case *ecdsa.PrivateKey:
|
||||
return generalKey.(*ecdsa.PrivateKey), nil
|
||||
case ed25519.PrivateKey:
|
||||
return generalKey.(ed25519.PrivateKey), nil
|
||||
}
|
||||
|
||||
// should never reach here
|
||||
|
|
132
vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go
generated
vendored
Normal file
132
vendor/github.com/cloudflare/cfssl/helpers/derhelpers/ed25519.go
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
|||
package derhelpers
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ed25519"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var errEd25519WrongID = errors.New("incorrect object identifier")
|
||||
var errEd25519WrongKeyType = errors.New("incorrect key type")
|
||||
|
||||
// ed25519OID is the OID for the Ed25519 signature scheme: see
|
||||
// https://datatracker.ietf.org/doc/draft-ietf-curdle-pkix-04.
|
||||
var ed25519OID = asn1.ObjectIdentifier{1, 3, 101, 112}
|
||||
|
||||
// subjectPublicKeyInfo reflects the ASN.1 object defined in the X.509 standard.
|
||||
//
|
||||
// This is defined in crypto/x509 as "publicKeyInfo".
|
||||
type subjectPublicKeyInfo struct {
|
||||
Algorithm pkix.AlgorithmIdentifier
|
||||
PublicKey asn1.BitString
|
||||
}
|
||||
|
||||
// MarshalEd25519PublicKey creates a DER-encoded SubjectPublicKeyInfo for an
|
||||
// ed25519 public key, as defined in
|
||||
// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04. This is analogous to
|
||||
// MarshalPKIXPublicKey in crypto/x509, which doesn't currently support Ed25519.
|
||||
func MarshalEd25519PublicKey(pk crypto.PublicKey) ([]byte, error) {
|
||||
pub, ok := pk.(ed25519.PublicKey)
|
||||
if !ok {
|
||||
return nil, errEd25519WrongKeyType
|
||||
}
|
||||
|
||||
spki := subjectPublicKeyInfo{
|
||||
Algorithm: pkix.AlgorithmIdentifier{
|
||||
Algorithm: ed25519OID,
|
||||
},
|
||||
PublicKey: asn1.BitString{
|
||||
BitLength: len(pub) * 8,
|
||||
Bytes: pub,
|
||||
},
|
||||
}
|
||||
|
||||
return asn1.Marshal(spki)
|
||||
}
|
||||
|
||||
// ParseEd25519PublicKey returns the Ed25519 public key encoded by the input.
|
||||
func ParseEd25519PublicKey(der []byte) (crypto.PublicKey, error) {
|
||||
var spki subjectPublicKeyInfo
|
||||
if rest, err := asn1.Unmarshal(der, &spki); err != nil {
|
||||
return nil, err
|
||||
} else if len(rest) > 0 {
|
||||
return nil, errors.New("SubjectPublicKeyInfo too long")
|
||||
}
|
||||
|
||||
if !spki.Algorithm.Algorithm.Equal(ed25519OID) {
|
||||
return nil, errEd25519WrongID
|
||||
}
|
||||
|
||||
if spki.PublicKey.BitLength != ed25519.PublicKeySize*8 {
|
||||
return nil, errors.New("SubjectPublicKeyInfo PublicKey length mismatch")
|
||||
}
|
||||
|
||||
return ed25519.PublicKey(spki.PublicKey.Bytes), nil
|
||||
}
|
||||
|
||||
// oneAsymmetricKey reflects the ASN.1 structure for storing private keys in
|
||||
// https://tools.ietf.org/html/draft-ietf-curdle-pkix-04, excluding the optional
|
||||
// fields, which we don't use here.
|
||||
//
|
||||
// This is identical to pkcs8 in crypto/x509.
|
||||
type oneAsymmetricKey struct {
|
||||
Version int
|
||||
Algorithm pkix.AlgorithmIdentifier
|
||||
PrivateKey []byte
|
||||
}
|
||||
|
||||
// curvePrivateKey is the innter type of the PrivateKey field of
|
||||
// oneAsymmetricKey.
|
||||
type curvePrivateKey []byte
|
||||
|
||||
// MarshalEd25519PrivateKey returns a DER encoding of the input private key as
|
||||
// specified in https://tools.ietf.org/html/draft-ietf-curdle-pkix-04.
|
||||
func MarshalEd25519PrivateKey(sk crypto.PrivateKey) ([]byte, error) {
|
||||
priv, ok := sk.(ed25519.PrivateKey)
|
||||
if !ok {
|
||||
return nil, errEd25519WrongKeyType
|
||||
}
|
||||
|
||||
// Marshal the innter CurvePrivateKey.
|
||||
curvePrivateKey, err := asn1.Marshal(priv.Seed())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Marshal the OneAsymmetricKey.
|
||||
asym := oneAsymmetricKey{
|
||||
Version: 0,
|
||||
Algorithm: pkix.AlgorithmIdentifier{
|
||||
Algorithm: ed25519OID,
|
||||
},
|
||||
PrivateKey: curvePrivateKey,
|
||||
}
|
||||
return asn1.Marshal(asym)
|
||||
}
|
||||
|
||||
// ParseEd25519PrivateKey returns the Ed25519 private key encoded by the input.
|
||||
func ParseEd25519PrivateKey(der []byte) (crypto.PrivateKey, error) {
|
||||
asym := new(oneAsymmetricKey)
|
||||
if rest, err := asn1.Unmarshal(der, asym); err != nil {
|
||||
return nil, err
|
||||
} else if len(rest) > 0 {
|
||||
return nil, errors.New("OneAsymmetricKey too long")
|
||||
}
|
||||
|
||||
// Check that the key type is correct.
|
||||
if !asym.Algorithm.Algorithm.Equal(ed25519OID) {
|
||||
return nil, errEd25519WrongID
|
||||
}
|
||||
|
||||
// Unmarshal the inner CurvePrivateKey.
|
||||
seed := new(curvePrivateKey)
|
||||
if rest, err := asn1.Unmarshal(asym.PrivateKey, seed); err != nil {
|
||||
return nil, err
|
||||
} else if len(rest) > 0 {
|
||||
return nil, errors.New("CurvePrivateKey too long")
|
||||
}
|
||||
|
||||
return ed25519.NewKeyFromSeed(*seed), nil
|
||||
}
|
53
vendor/github.com/cloudflare/cfssl/helpers/helpers.go
generated
vendored
53
vendor/github.com/cloudflare/cfssl/helpers/helpers.go
generated
vendored
|
@ -15,14 +15,7 @@ import (
|
|||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/google/certificate-transparency-go"
|
||||
cttls "github.com/google/certificate-transparency-go/tls"
|
||||
ctx509 "github.com/google/certificate-transparency-go/x509"
|
||||
"golang.org/x/crypto/ocsp"
|
||||
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -30,6 +23,11 @@ import (
|
|||
cferr "github.com/cloudflare/cfssl/errors"
|
||||
"github.com/cloudflare/cfssl/helpers/derhelpers"
|
||||
"github.com/cloudflare/cfssl/log"
|
||||
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
cttls "github.com/google/certificate-transparency-go/tls"
|
||||
ctx509 "github.com/google/certificate-transparency-go/x509"
|
||||
"golang.org/x/crypto/ocsp"
|
||||
"golang.org/x/crypto/pkcs12"
|
||||
)
|
||||
|
||||
|
@ -39,6 +37,16 @@ const OneYear = 8760 * time.Hour
|
|||
// OneDay is a time.Duration representing a day's worth of seconds.
|
||||
const OneDay = 24 * time.Hour
|
||||
|
||||
// DelegationUsage is the OID for the DelegationUseage extensions
|
||||
var DelegationUsage = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 44363, 44}
|
||||
|
||||
// DelegationExtension
|
||||
var DelegationExtension = pkix.Extension{
|
||||
Id: DelegationUsage,
|
||||
Critical: false,
|
||||
Value: []byte{0x05, 0x00}, // ASN.1 NULL
|
||||
}
|
||||
|
||||
// InclusiveDate returns the time.Time representation of a date - 1
|
||||
// nanosecond. This allows time.After to be used inclusively.
|
||||
func InclusiveDate(year int, month time.Month, day int) time.Time {
|
||||
|
@ -184,6 +192,19 @@ func HashAlgoString(alg x509.SignatureAlgorithm) string {
|
|||
}
|
||||
}
|
||||
|
||||
// StringTLSVersion returns underlying enum values from human names for TLS
|
||||
// versions, defaults to current golang default of TLS 1.0
|
||||
func StringTLSVersion(version string) uint16 {
|
||||
switch version {
|
||||
case "1.2":
|
||||
return tls.VersionTLS12
|
||||
case "1.1":
|
||||
return tls.VersionTLS11
|
||||
default:
|
||||
return tls.VersionTLS10
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeCertificatesPEM encodes a number of x509 certificates to PEM
|
||||
func EncodeCertificatesPEM(certs []*x509.Certificate) []byte {
|
||||
var buffer bytes.Buffer
|
||||
|
@ -322,7 +343,7 @@ func LoadPEMCertPool(certsFile string) (*x509.CertPool, error) {
|
|||
if certsFile == "" {
|
||||
return nil, nil
|
||||
}
|
||||
pemCerts, err := ioutil.ReadFile(certsFile)
|
||||
pemCerts, err := os.ReadFile(certsFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -365,7 +386,15 @@ func ParsePrivateKeyPEMWithPassword(keyPEM []byte, password []byte) (key crypto.
|
|||
|
||||
// GetKeyDERFromPEM parses a PEM-encoded private key and returns DER-format key bytes.
|
||||
func GetKeyDERFromPEM(in []byte, password []byte) ([]byte, error) {
|
||||
keyDER, _ := pem.Decode(in)
|
||||
// Ignore any EC PARAMETERS blocks when looking for a key (openssl includes
|
||||
// them by default).
|
||||
var keyDER *pem.Block
|
||||
for {
|
||||
keyDER, in = pem.Decode(in)
|
||||
if keyDER == nil || keyDER.Type != "EC PARAMETERS" {
|
||||
break
|
||||
}
|
||||
}
|
||||
if keyDER != nil {
|
||||
if procType, ok := keyDER.Headers["Proc-Type"]; ok {
|
||||
if strings.Contains(procType, "ENCRYPTED") {
|
||||
|
@ -460,7 +489,7 @@ func LoadClientCertificate(certFile string, keyFile string) (*tls.Certificate, e
|
|||
if certFile != "" && keyFile != "" {
|
||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||
if err != nil {
|
||||
log.Critical("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile)
|
||||
log.Criticalf("Unable to read client certificate from file: %s or key from file: %s", certFile, keyFile)
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("Client certificate loaded ")
|
||||
|
@ -560,13 +589,13 @@ func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTim
|
|||
func ReadBytes(valFile string) ([]byte, error) {
|
||||
switch splitVal := strings.SplitN(valFile, ":", 2); len(splitVal) {
|
||||
case 1:
|
||||
return ioutil.ReadFile(valFile)
|
||||
return os.ReadFile(valFile)
|
||||
case 2:
|
||||
switch splitVal[0] {
|
||||
case "env":
|
||||
return []byte(os.Getenv(splitVal[1])), nil
|
||||
case "file":
|
||||
return ioutil.ReadFile(splitVal[1])
|
||||
return os.ReadFile(splitVal[1])
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown prefix: %s", splitVal[0])
|
||||
}
|
||||
|
|
4
vendor/github.com/cloudflare/cfssl/initca/initca.go
generated
vendored
4
vendor/github.com/cloudflare/cfssl/initca/initca.go
generated
vendored
|
@ -69,6 +69,10 @@ func New(req *csr.CertificateRequest) (cert, csrPEM, key []byte, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
if req.CRL != "" {
|
||||
policy.Default.CRL = req.CRL
|
||||
}
|
||||
|
||||
g := &csr.Generator{Validator: validator}
|
||||
csrPEM, key, err = g.ProcessRequest(req)
|
||||
if err != nil {
|
||||
|
|
194
vendor/github.com/cloudflare/cfssl/signer/local/local.go
generated
vendored
194
vendor/github.com/cloudflare/cfssl/signer/local/local.go
generated
vendored
|
@ -3,20 +3,27 @@ package local
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"database/sql"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cloudflare/cfssl/certdb"
|
||||
"github.com/cloudflare/cfssl/config"
|
||||
|
@ -25,17 +32,23 @@ import (
|
|||
"github.com/cloudflare/cfssl/info"
|
||||
"github.com/cloudflare/cfssl/log"
|
||||
"github.com/cloudflare/cfssl/signer"
|
||||
"github.com/google/certificate-transparency-go"
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/client"
|
||||
"github.com/google/certificate-transparency-go/jsonclient"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
zx509 "github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
)
|
||||
|
||||
// Signer contains a signer that uses the standard library to
|
||||
// support both ECDSA and RSA CA keys.
|
||||
type Signer struct {
|
||||
ca *x509.Certificate
|
||||
priv crypto.Signer
|
||||
ca *x509.Certificate
|
||||
priv crypto.Signer
|
||||
// lintPriv is generated randomly when pre-issuance linting is configured and
|
||||
// used to sign TBSCertificates for linting.
|
||||
lintPriv crypto.Signer
|
||||
policy *config.Signing
|
||||
sigAlgo x509.SignatureAlgorithm
|
||||
dbAccessor certdb.Accessor
|
||||
|
@ -54,11 +67,30 @@ func NewSigner(priv crypto.Signer, cert *x509.Certificate, sigAlgo x509.Signatur
|
|||
return nil, cferr.New(cferr.PolicyError, cferr.InvalidPolicy)
|
||||
}
|
||||
|
||||
var lintPriv crypto.Signer
|
||||
// If there is at least one profile (including the default) that configures
|
||||
// pre-issuance linting then generate the one-off lintPriv key.
|
||||
for _, profile := range policy.Profiles {
|
||||
if profile.LintErrLevel > 0 || policy.Default.LintErrLevel > 0 {
|
||||
// In the future there may be demand for specifying the type of signer used
|
||||
// for pre-issuance linting in configuration. For now we assume that signing
|
||||
// with a randomly generated P-256 ECDSA private key is acceptable for all cases
|
||||
// where linting is requested.
|
||||
k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, cferr.New(cferr.PrivateKeyError, cferr.GenerationFailed)
|
||||
}
|
||||
lintPriv = k
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return &Signer{
|
||||
ca: cert,
|
||||
priv: priv,
|
||||
sigAlgo: sigAlgo,
|
||||
policy: policy,
|
||||
ca: cert,
|
||||
priv: priv,
|
||||
lintPriv: lintPriv,
|
||||
sigAlgo: sigAlgo,
|
||||
policy: policy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -89,14 +121,75 @@ func NewSignerFromFile(caFile, caKeyFile string, policy *config.Signing) (*Signe
|
|||
|
||||
priv, err := helpers.ParsePrivateKeyPEMWithPassword(cakey, password)
|
||||
if err != nil {
|
||||
log.Debug("Malformed private key %v", err)
|
||||
log.Debugf("Malformed private key %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewSigner(priv, parsedCa, signer.DefaultSigAlgo(priv), policy)
|
||||
}
|
||||
|
||||
func (s *Signer) sign(template *x509.Certificate) (cert []byte, err error) {
|
||||
// LintError is an error type returned when pre-issuance linting is configured
|
||||
// in a signing profile and a TBS Certificate fails linting. It wraps the
|
||||
// concrete zlint LintResults so that callers can further inspect the cause of
|
||||
// the failing lints.
|
||||
type LintError struct {
|
||||
ErrorResults map[string]lint.LintResult
|
||||
}
|
||||
|
||||
func (e *LintError) Error() string {
|
||||
return fmt.Sprintf("pre-issuance linting found %d error results",
|
||||
len(e.ErrorResults))
|
||||
}
|
||||
|
||||
// lint performs pre-issuance linting of a given TBS certificate template when
|
||||
// the provided errLevel is > 0. Note that the template is provided by-value and
|
||||
// not by-reference. This is important as the lint function needs to mutate the
|
||||
// template's signature algorithm to match the lintPriv.
|
||||
func (s *Signer) lint(template x509.Certificate, errLevel lint.LintStatus, lintRegistry lint.Registry) error {
|
||||
// Always return nil when linting is disabled (lint.Reserved == 0).
|
||||
if errLevel == lint.Reserved {
|
||||
return nil
|
||||
}
|
||||
// without a lintPriv key to use to sign the tbsCertificate we can't lint it.
|
||||
if s.lintPriv == nil {
|
||||
return cferr.New(cferr.PrivateKeyError, cferr.Unavailable)
|
||||
}
|
||||
|
||||
// The template's SignatureAlgorithm must be mutated to match the lintPriv or
|
||||
// x509.CreateCertificate will error because of the mismatch. At the time of
|
||||
// writing s.lintPriv is always an ECDSA private key. This switch will need to
|
||||
// be expanded if the lint key type is made configurable.
|
||||
switch s.lintPriv.(type) {
|
||||
case *ecdsa.PrivateKey:
|
||||
template.SignatureAlgorithm = x509.ECDSAWithSHA256
|
||||
default:
|
||||
return cferr.New(cferr.PrivateKeyError, cferr.KeyMismatch)
|
||||
}
|
||||
|
||||
prelintBytes, err := x509.CreateCertificate(rand.Reader, &template, s.ca, template.PublicKey, s.lintPriv)
|
||||
if err != nil {
|
||||
return cferr.Wrap(cferr.CertificateError, cferr.Unknown, err)
|
||||
}
|
||||
prelintCert, err := zx509.ParseCertificate(prelintBytes)
|
||||
if err != nil {
|
||||
return cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err)
|
||||
}
|
||||
errorResults := map[string]lint.LintResult{}
|
||||
results := zlint.LintCertificateEx(prelintCert, lintRegistry)
|
||||
for name, res := range results.Results {
|
||||
if res.Status > errLevel {
|
||||
errorResults[name] = *res
|
||||
}
|
||||
}
|
||||
if len(errorResults) > 0 {
|
||||
return &LintError{
|
||||
ErrorResults: errorResults,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Signer) sign(template *x509.Certificate, lintErrLevel lint.LintStatus, lintRegistry lint.Registry) (cert []byte, err error) {
|
||||
var initRoot bool
|
||||
if s.ca == nil {
|
||||
if !template.IsCA {
|
||||
|
@ -105,10 +198,15 @@ func (s *Signer) sign(template *x509.Certificate) (cert []byte, err error) {
|
|||
}
|
||||
template.DNSNames = nil
|
||||
template.EmailAddresses = nil
|
||||
template.URIs = nil
|
||||
s.ca = template
|
||||
initRoot = true
|
||||
}
|
||||
|
||||
if err := s.lint(*template, lintErrLevel, lintRegistry); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv)
|
||||
if err != nil {
|
||||
return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err)
|
||||
|
@ -159,13 +257,14 @@ func PopulateSubjectFromCSR(s *signer.Subject, req pkix.Name) pkix.Name {
|
|||
return name
|
||||
}
|
||||
|
||||
// OverrideHosts fills template's IPAddresses, EmailAddresses, and DNSNames with the
|
||||
// OverrideHosts fills template's IPAddresses, EmailAddresses, DNSNames, and URIs with the
|
||||
// content of hosts, if it is not nil.
|
||||
func OverrideHosts(template *x509.Certificate, hosts []string) {
|
||||
if hosts != nil {
|
||||
template.IPAddresses = []net.IP{}
|
||||
template.EmailAddresses = []string{}
|
||||
template.DNSNames = []string{}
|
||||
template.URIs = []*url.URL{}
|
||||
}
|
||||
|
||||
for i := range hosts {
|
||||
|
@ -173,6 +272,8 @@ func OverrideHosts(template *x509.Certificate, hosts []string) {
|
|||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else if email, err := mail.ParseAddress(hosts[i]); err == nil && email != nil {
|
||||
template.EmailAddresses = append(template.EmailAddresses, email.Address)
|
||||
} else if uri, err := url.ParseRequestURI(hosts[i]); err == nil && uri != nil {
|
||||
template.URIs = append(template.URIs, uri)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, hosts[i])
|
||||
}
|
||||
|
@ -199,7 +300,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
cferr.BadRequest, errors.New("not a csr"))
|
||||
}
|
||||
|
||||
csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes)
|
||||
csrTemplate, err := signer.ParseCertificateRequest(s, profile, block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -232,6 +333,9 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
if profile.CSRWhitelist.EmailAddresses {
|
||||
safeTemplate.EmailAddresses = csrTemplate.EmailAddresses
|
||||
}
|
||||
if profile.CSRWhitelist.URIs {
|
||||
safeTemplate.URIs = csrTemplate.URIs
|
||||
}
|
||||
}
|
||||
|
||||
if req.CRLOverride != "" {
|
||||
|
@ -277,6 +381,11 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist)
|
||||
}
|
||||
}
|
||||
for _, name := range safeTemplate.URIs {
|
||||
if profile.NameWhitelist.Find([]byte(name.String())) == nil {
|
||||
return nil, cferr.New(cferr.PolicyError, cferr.UnmatchedWhitelist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if profile.ClientProvidesSerialNumbers {
|
||||
|
@ -342,7 +451,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
var poisonExtension = pkix.Extension{Id: signer.CTPoisonOID, Critical: true, Value: []byte{0x05, 0x00}}
|
||||
var poisonedPreCert = certTBS
|
||||
poisonedPreCert.ExtraExtensions = append(safeTemplate.ExtraExtensions, poisonExtension)
|
||||
cert, err = s.sign(&poisonedPreCert)
|
||||
cert, err = s.sign(&poisonedPreCert, profile.LintErrLevel, profile.LintRegistry)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -385,8 +494,9 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
var SCTListExtension = pkix.Extension{Id: signer.SCTListOID, Critical: false, Value: serializedSCTList}
|
||||
certTBS.ExtraExtensions = append(certTBS.ExtraExtensions, SCTListExtension)
|
||||
}
|
||||
|
||||
var signedCert []byte
|
||||
signedCert, err = s.sign(&certTBS)
|
||||
signedCert, err = s.sign(&certTBS, profile.LintErrLevel, profile.LintRegistry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -397,19 +507,29 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
parsedCert, _ := helpers.ParseCertificatePEM(signedCert)
|
||||
|
||||
if s.dbAccessor != nil {
|
||||
now := time.Now()
|
||||
var certRecord = certdb.CertificateRecord{
|
||||
Serial: certTBS.SerialNumber.String(),
|
||||
// this relies on the specific behavior of x509.CreateCertificate
|
||||
// which sets the AuthorityKeyId from the signer's SubjectKeyId
|
||||
AKI: hex.EncodeToString(parsedCert.AuthorityKeyId),
|
||||
CALabel: req.Label,
|
||||
Status: "good",
|
||||
Expiry: certTBS.NotAfter,
|
||||
PEM: string(signedCert),
|
||||
AKI: hex.EncodeToString(parsedCert.AuthorityKeyId),
|
||||
CALabel: req.Label,
|
||||
Status: "good",
|
||||
Expiry: certTBS.NotAfter,
|
||||
PEM: string(signedCert),
|
||||
IssuedAt: &now,
|
||||
NotBefore: &certTBS.NotBefore,
|
||||
CommonName: sql.NullString{String: certTBS.Subject.CommonName, Valid: true},
|
||||
}
|
||||
|
||||
err = s.dbAccessor.InsertCertificate(certRecord)
|
||||
if err != nil {
|
||||
if err := certRecord.SetMetadata(req.Metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := certRecord.SetSANs(certTBS.DNSNames); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.dbAccessor.InsertCertificate(certRecord); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Debug("saved certificate with serial number ", certTBS.SerialNumber)
|
||||
|
@ -424,7 +544,9 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
|
|||
// except for the removal of the poison extension and the addition of the SCT list
|
||||
// extension. SignFromPrecert does not verify that the contents of the certificate
|
||||
// still match the signing profile of the signer, it only requires that the precert
|
||||
// was previously signed by the Signers CA.
|
||||
// was previously signed by the Signers CA. Similarly, any linting configured
|
||||
// by the profile used to sign the precert will not be re-applied to the final
|
||||
// cert and must be done separately by the caller.
|
||||
func (s *Signer) SignFromPrecert(precert *x509.Certificate, scts []ct.SignedCertificateTimestamp) ([]byte, error) {
|
||||
// Verify certificate was signed by s.ca
|
||||
if err := precert.CheckSignatureFrom(s.ca); err != nil {
|
||||
|
@ -467,17 +589,17 @@ func (s *Signer) SignFromPrecert(precert *x509.Certificate, scts []ct.SignedCert
|
|||
// Create the new tbsCert from precert. Do explicit copies of any slices so that we don't
|
||||
// use memory that may be altered by us or the caller at a later stage.
|
||||
tbsCert := x509.Certificate{
|
||||
SignatureAlgorithm: precert.SignatureAlgorithm,
|
||||
PublicKeyAlgorithm: precert.PublicKeyAlgorithm,
|
||||
PublicKey: precert.PublicKey,
|
||||
Version: precert.Version,
|
||||
SerialNumber: precert.SerialNumber,
|
||||
Issuer: precert.Issuer,
|
||||
Subject: precert.Subject,
|
||||
NotBefore: precert.NotBefore,
|
||||
NotAfter: precert.NotAfter,
|
||||
KeyUsage: precert.KeyUsage,
|
||||
BasicConstraintsValid: precert.BasicConstraintsValid,
|
||||
SignatureAlgorithm: precert.SignatureAlgorithm,
|
||||
PublicKeyAlgorithm: precert.PublicKeyAlgorithm,
|
||||
PublicKey: precert.PublicKey,
|
||||
Version: precert.Version,
|
||||
SerialNumber: precert.SerialNumber,
|
||||
Issuer: precert.Issuer,
|
||||
Subject: precert.Subject,
|
||||
NotBefore: precert.NotBefore,
|
||||
NotAfter: precert.NotAfter,
|
||||
KeyUsage: precert.KeyUsage,
|
||||
BasicConstraintsValid: precert.BasicConstraintsValid,
|
||||
IsCA: precert.IsCA,
|
||||
MaxPathLen: precert.MaxPathLen,
|
||||
MaxPathLenZero: precert.MaxPathLenZero,
|
||||
|
@ -493,8 +615,10 @@ func (s *Signer) SignFromPrecert(precert *x509.Certificate, scts []ct.SignedCert
|
|||
// Insert the SCT list extension
|
||||
tbsCert.ExtraExtensions = append(tbsCert.ExtraExtensions, sctExt)
|
||||
|
||||
// Sign the tbsCert
|
||||
return s.sign(&tbsCert)
|
||||
// Sign the tbsCert. Linting is always disabled because there is no way for
|
||||
// this API to know the correct lint settings to use because there is no
|
||||
// reference to the signing profile of the precert available.
|
||||
return s.sign(&tbsCert, 0, nil)
|
||||
}
|
||||
|
||||
// Info return a populated info.Resp struct or an error.
|
||||
|
|
44
vendor/github.com/cloudflare/cfssl/signer/signer.go
generated
vendored
44
vendor/github.com/cloudflare/cfssl/signer/signer.go
generated
vendored
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/cloudflare/cfssl/config"
|
||||
"github.com/cloudflare/cfssl/csr"
|
||||
cferr "github.com/cloudflare/cfssl/errors"
|
||||
"github.com/cloudflare/cfssl/helpers"
|
||||
"github.com/cloudflare/cfssl/info"
|
||||
)
|
||||
|
||||
|
@ -45,7 +46,7 @@ type Extension struct {
|
|||
// Extensions provided in the signRequest are copied into the certificate, as
|
||||
// long as they are in the ExtensionWhitelist for the signer's policy.
|
||||
// Extensions requested in the CSR are ignored, except for those processed by
|
||||
// ParseCertificateRequest (mainly subjectAltName).
|
||||
// ParseCertificateRequest (mainly subjectAltName) and DelegationUsage.
|
||||
type SignRequest struct {
|
||||
Hosts []string `json:"hosts"`
|
||||
Request string `json:"certificate_request"`
|
||||
|
@ -70,6 +71,9 @@ type SignRequest struct {
|
|||
// be passed to SignFromPrecert with the SCTs in order to create a
|
||||
// valid certificate.
|
||||
ReturnPrecert bool
|
||||
|
||||
// Arbitrary metadata to be stored in certdb.
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
}
|
||||
|
||||
// appendIf appends to a if s is not an empty string.
|
||||
|
@ -169,15 +173,38 @@ func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm {
|
|||
}
|
||||
}
|
||||
|
||||
func isCommonAttr(t []int) bool {
|
||||
return (len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 && (t[3] == 3 || (t[3] >= 5 && t[3] <= 11) || t[3] == 17))
|
||||
}
|
||||
|
||||
// ParseCertificateRequest takes an incoming certificate request and
|
||||
// builds a certificate template from it.
|
||||
func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certificate, err error) {
|
||||
func ParseCertificateRequest(s Signer, p *config.SigningProfile, csrBytes []byte) (template *x509.Certificate, err error) {
|
||||
csrv, err := x509.ParseCertificateRequest(csrBytes)
|
||||
if err != nil {
|
||||
err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err)
|
||||
return
|
||||
}
|
||||
|
||||
var r pkix.RDNSequence
|
||||
_, err = asn1.Unmarshal(csrv.RawSubject, &r)
|
||||
|
||||
if err != nil {
|
||||
err = cferr.Wrap(cferr.CSRError, cferr.ParseFailed, err)
|
||||
return
|
||||
}
|
||||
|
||||
var subject pkix.Name
|
||||
subject.FillFromRDNSequence(&r)
|
||||
|
||||
for _, v := range r {
|
||||
for _, vv := range v {
|
||||
if !isCommonAttr(vv.Type) {
|
||||
subject.ExtraNames = append(subject.ExtraNames, vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = csrv.CheckSignature()
|
||||
if err != nil {
|
||||
err = cferr.Wrap(cferr.CSRError, cferr.KeyMismatch, err)
|
||||
|
@ -185,13 +212,16 @@ func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certific
|
|||
}
|
||||
|
||||
template = &x509.Certificate{
|
||||
Subject: csrv.Subject,
|
||||
Subject: subject,
|
||||
PublicKeyAlgorithm: csrv.PublicKeyAlgorithm,
|
||||
PublicKey: csrv.PublicKey,
|
||||
SignatureAlgorithm: s.SigAlgo(),
|
||||
DNSNames: csrv.DNSNames,
|
||||
IPAddresses: csrv.IPAddresses,
|
||||
EmailAddresses: csrv.EmailAddresses,
|
||||
URIs: csrv.URIs,
|
||||
Extensions: csrv.Extensions,
|
||||
ExtraExtensions: []pkix.Extension{},
|
||||
}
|
||||
|
||||
for _, val := range csrv.Extensions {
|
||||
|
@ -211,6 +241,13 @@ func ParseCertificateRequest(s Signer, csrBytes []byte) (template *x509.Certific
|
|||
template.IsCA = constraints.IsCA
|
||||
template.MaxPathLen = constraints.MaxPathLen
|
||||
template.MaxPathLenZero = template.MaxPathLen == 0
|
||||
} else if val.Id.Equal(helpers.DelegationUsage) {
|
||||
template.ExtraExtensions = append(template.ExtraExtensions, val)
|
||||
} else {
|
||||
// If the profile has 'copy_extensions' to true then lets add it
|
||||
if p.CopyExtensions {
|
||||
template.ExtraExtensions = append(template.ExtraExtensions, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,6 +357,7 @@ func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.Si
|
|||
}
|
||||
template.DNSNames = nil
|
||||
template.EmailAddresses = nil
|
||||
template.URIs = nil
|
||||
}
|
||||
template.SubjectKeyId = ski
|
||||
|
||||
|
|
23
vendor/github.com/jmoiron/sqlx/LICENSE
generated
vendored
Normal file
23
vendor/github.com/jmoiron/sqlx/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
Copyright (c) 2013, Jason Moiron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
5
vendor/github.com/jmoiron/sqlx/types/README.md
generated
vendored
Normal file
5
vendor/github.com/jmoiron/sqlx/types/README.md
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# types
|
||||
|
||||
The types package provides some useful types which implement the `sql.Scanner`
|
||||
and `driver.Valuer` interfaces, suitable for use as scan and value targets with
|
||||
database/sql.
|
172
vendor/github.com/jmoiron/sqlx/types/types.go
generated
vendored
Normal file
172
vendor/github.com/jmoiron/sqlx/types/types.go
generated
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
// GzippedText is a []byte which transparently gzips data being submitted to
|
||||
// a database and ungzips data being Scanned from a database.
|
||||
type GzippedText []byte
|
||||
|
||||
// Value implements the driver.Valuer interface, gzipping the raw value of
|
||||
// this GzippedText.
|
||||
func (g GzippedText) Value() (driver.Value, error) {
|
||||
b := make([]byte, 0, len(g))
|
||||
buf := bytes.NewBuffer(b)
|
||||
w := gzip.NewWriter(buf)
|
||||
w.Write(g)
|
||||
w.Close()
|
||||
return buf.Bytes(), nil
|
||||
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface, ungzipping the value coming off
|
||||
// the wire and storing the raw result in the GzippedText.
|
||||
func (g *GzippedText) Scan(src interface{}) error {
|
||||
var source []byte
|
||||
switch src := src.(type) {
|
||||
case string:
|
||||
source = []byte(src)
|
||||
case []byte:
|
||||
source = src
|
||||
default:
|
||||
return errors.New("Incompatible type for GzippedText")
|
||||
}
|
||||
reader, err := gzip.NewReader(bytes.NewReader(source))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer reader.Close()
|
||||
b, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*g = GzippedText(b)
|
||||
return nil
|
||||
}
|
||||
|
||||
// JSONText is a json.RawMessage, which is a []byte underneath.
|
||||
// Value() validates the json format in the source, and returns an error if
|
||||
// the json is not valid. Scan does no validation. JSONText additionally
|
||||
// implements `Unmarshal`, which unmarshals the json within to an interface{}
|
||||
type JSONText json.RawMessage
|
||||
|
||||
var emptyJSON = JSONText("{}")
|
||||
|
||||
// MarshalJSON returns the *j as the JSON encoding of j.
|
||||
func (j JSONText) MarshalJSON() ([]byte, error) {
|
||||
if len(j) == 0 {
|
||||
return emptyJSON, nil
|
||||
}
|
||||
return j, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets *j to a copy of data
|
||||
func (j *JSONText) UnmarshalJSON(data []byte) error {
|
||||
if j == nil {
|
||||
return errors.New("JSONText: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
*j = append((*j)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns j as a value. This does a validating unmarshal into another
|
||||
// RawMessage. If j is invalid json, it returns an error.
|
||||
func (j JSONText) Value() (driver.Value, error) {
|
||||
var m json.RawMessage
|
||||
var err = j.Unmarshal(&m)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return []byte(j), nil
|
||||
}
|
||||
|
||||
// Scan stores the src in *j. No validation is done.
|
||||
func (j *JSONText) Scan(src interface{}) error {
|
||||
var source []byte
|
||||
switch t := src.(type) {
|
||||
case string:
|
||||
source = []byte(t)
|
||||
case []byte:
|
||||
if len(t) == 0 {
|
||||
source = emptyJSON
|
||||
} else {
|
||||
source = t
|
||||
}
|
||||
case nil:
|
||||
*j = emptyJSON
|
||||
default:
|
||||
return errors.New("Incompatible type for JSONText")
|
||||
}
|
||||
*j = append((*j)[0:0], source...)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
|
||||
func (j *JSONText) Unmarshal(v interface{}) error {
|
||||
if len(*j) == 0 {
|
||||
*j = emptyJSON
|
||||
}
|
||||
return json.Unmarshal([]byte(*j), v)
|
||||
}
|
||||
|
||||
// String supports pretty printing for JSONText types.
|
||||
func (j JSONText) String() string {
|
||||
return string(j)
|
||||
}
|
||||
|
||||
// NullJSONText represents a JSONText that may be null.
|
||||
// NullJSONText implements the scanner interface so
|
||||
// it can be used as a scan destination, similar to NullString.
|
||||
type NullJSONText struct {
|
||||
JSONText
|
||||
Valid bool // Valid is true if JSONText is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
func (n *NullJSONText) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
n.JSONText, n.Valid = emptyJSON, false
|
||||
return nil
|
||||
}
|
||||
n.Valid = true
|
||||
return n.JSONText.Scan(value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (n NullJSONText) Value() (driver.Value, error) {
|
||||
if !n.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return n.JSONText.Value()
|
||||
}
|
||||
|
||||
// BitBool is an implementation of a bool for the MySQL type BIT(1).
|
||||
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
|
||||
type BitBool bool
|
||||
|
||||
// Value implements the driver.Valuer interface,
|
||||
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
|
||||
func (b BitBool) Value() (driver.Value, error) {
|
||||
if b {
|
||||
return []byte{1}, nil
|
||||
}
|
||||
return []byte{0}, nil
|
||||
}
|
||||
|
||||
// Scan implements the sql.Scanner interface,
|
||||
// and turns the bitfield incoming from MySQL into a BitBool
|
||||
func (b *BitBool) Scan(src interface{}) error {
|
||||
v, ok := src.([]byte)
|
||||
if !ok {
|
||||
return errors.New("bad []byte type assertion")
|
||||
}
|
||||
*b = v[0] == 1
|
||||
return nil
|
||||
}
|
4
vendor/github.com/moby/swarmkit/v2/agent/csi/volumes.go
generated
vendored
4
vendor/github.com/moby/swarmkit/v2/agent/csi/volumes.go
generated
vendored
|
@ -6,8 +6,6 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
|
||||
"github.com/moby/swarmkit/v2/agent/csi/plugin"
|
||||
|
@ -65,7 +63,7 @@ func (r *volumes) retryVolumes() {
|
|||
for {
|
||||
vid, attempt := r.pendingVolumes.Wait()
|
||||
|
||||
dctx := log.WithFields(ctx, logrus.Fields{
|
||||
dctx := log.WithFields(ctx, log.Fields{
|
||||
"volume.id": vid,
|
||||
"attempt": fmt.Sprintf("%d", attempt),
|
||||
})
|
||||
|
|
6
vendor/github.com/moby/swarmkit/v2/agent/exec/controller.go
generated
vendored
6
vendor/github.com/moby/swarmkit/v2/agent/exec/controller.go
generated
vendored
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/protobuf/ptypes"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Controller controls execution of a task.
|
||||
|
@ -348,11 +347,10 @@ func Do(ctx context.Context, task *api.Task, ctlr Controller) (*api.TaskStatus,
|
|||
|
||||
func logStateChange(ctx context.Context, desired, previous, next api.TaskState) {
|
||||
if previous != next {
|
||||
fields := logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"state.transition": fmt.Sprintf("%v->%v", previous, next),
|
||||
"state.desired": desired,
|
||||
}
|
||||
log.G(ctx).WithFields(fields).Debug("state changed")
|
||||
}).Debug("state changed")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
vendor/github.com/moby/swarmkit/v2/agent/session.go
generated
vendored
15
vendor/github.com/moby/swarmkit/v2/agent/session.go
generated
vendored
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/connectionbroker"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
@ -180,7 +179,7 @@ func (s *session) heartbeat(ctx context.Context) error {
|
|||
heartbeat := time.NewTimer(1) // send out a heartbeat right away
|
||||
defer heartbeat.Stop()
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"sessionID": s.sessionID,
|
||||
"method": "(*session).heartbeat",
|
||||
}
|
||||
|
@ -243,8 +242,8 @@ func (s *session) handleSessionMessage(ctx context.Context, msg *api.SessionMess
|
|||
}
|
||||
|
||||
func (s *session) logSubscriptions(ctx context.Context) error {
|
||||
log := log.G(ctx).WithFields(logrus.Fields{"method": "(*session).logSubscriptions"})
|
||||
log.Debugf("")
|
||||
logger := log.G(ctx).WithFields(log.Fields{"method": "(*session).logSubscriptions"})
|
||||
logger.Debugf("")
|
||||
|
||||
client := api.NewLogBrokerClient(s.conn.ClientConn)
|
||||
subscriptions, err := client.ListenSubscriptions(ctx, &api.ListenSubscriptionsRequest{})
|
||||
|
@ -257,7 +256,7 @@ func (s *session) logSubscriptions(ctx context.Context) error {
|
|||
resp, err := subscriptions.Recv()
|
||||
st, _ := status.FromError(err)
|
||||
if st.Code() == codes.Unimplemented {
|
||||
log.Warning("manager does not support log subscriptions")
|
||||
logger.Warning("manager does not support log subscriptions")
|
||||
// Don't return, because returning would bounce the session
|
||||
select {
|
||||
case <-s.closed:
|
||||
|
@ -281,8 +280,8 @@ func (s *session) logSubscriptions(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *session) watch(ctx context.Context) error {
|
||||
log := log.G(ctx).WithFields(logrus.Fields{"method": "(*session).watch"})
|
||||
log.Debugf("")
|
||||
logger := log.G(ctx).WithFields(log.Fields{"method": "(*session).watch"})
|
||||
logger.Debugf("")
|
||||
var (
|
||||
resp *api.AssignmentsMessage
|
||||
assignmentWatch api.Dispatcher_AssignmentsClient
|
||||
|
@ -313,7 +312,7 @@ func (s *session) watch(ctx context.Context) error {
|
|||
}
|
||||
tasksFallback = true
|
||||
assignmentWatch = nil
|
||||
log.WithError(err).Infof("falling back to Tasks")
|
||||
logger.WithError(err).Infof("falling back to Tasks")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
vendor/github.com/moby/swarmkit/v2/agent/worker.go
generated
vendored
23
vendor/github.com/moby/swarmkit/v2/agent/worker.go
generated
vendored
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/watch"
|
||||
"github.com/sirupsen/logrus"
|
||||
bolt "go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
|
@ -135,7 +134,7 @@ func (w *worker) Assign(ctx context.Context, assignments []*api.AssignmentChange
|
|||
return ErrClosed
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(assignments)": len(assignments),
|
||||
}).Debug("(*worker).Assign")
|
||||
|
||||
|
@ -174,7 +173,7 @@ func (w *worker) Update(ctx context.Context, assignments []*api.AssignmentChange
|
|||
return ErrClosed
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(assignments)": len(assignments),
|
||||
}).Debug("(*worker).Update")
|
||||
|
||||
|
@ -212,7 +211,7 @@ func reconcileTaskState(ctx context.Context, w *worker, assignments []*api.Assig
|
|||
}
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(updatedTasks)": len(updatedTasks),
|
||||
"len(removedTasks)": len(removedTasks),
|
||||
}).Debug("(*worker).reconcileTaskState")
|
||||
|
@ -227,10 +226,10 @@ func reconcileTaskState(ctx context.Context, w *worker, assignments []*api.Assig
|
|||
assigned := map[string]struct{}{}
|
||||
|
||||
for _, task := range updatedTasks {
|
||||
log.G(ctx).WithFields(
|
||||
logrus.Fields{
|
||||
"task.id": task.ID,
|
||||
"task.desiredstate": task.DesiredState}).Debug("assigned")
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"task.id": task.ID,
|
||||
"task.desiredstate": task.DesiredState,
|
||||
}).Debug("assigned")
|
||||
if err := PutTask(tx, task); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -359,7 +358,7 @@ func reconcileSecrets(ctx context.Context, w *worker, assignments []*api.Assignm
|
|||
|
||||
secrets := secretsProvider.Secrets()
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(updatedSecrets)": len(updatedSecrets),
|
||||
"len(removedSecrets)": len(removedSecrets),
|
||||
}).Debug("(*worker).reconcileSecrets")
|
||||
|
@ -402,7 +401,7 @@ func reconcileConfigs(ctx context.Context, w *worker, assignments []*api.Assignm
|
|||
|
||||
configs := configsProvider.Configs()
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(updatedConfigs)": len(updatedConfigs),
|
||||
"len(removedConfigs)": len(removedConfigs),
|
||||
}).Debug("(*worker).reconcileConfigs")
|
||||
|
@ -448,7 +447,7 @@ func reconcileVolumes(ctx context.Context, w *worker, assignments []*api.Assignm
|
|||
|
||||
volumes := volumesProvider.Volumes()
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"len(updatedVolumes)": len(updatedVolumes),
|
||||
"len(removedVolumes)": len(removedVolumes),
|
||||
}).Debug("(*worker).reconcileVolumes")
|
||||
|
@ -536,7 +535,7 @@ func (w *worker) taskManager(ctx context.Context, tx *bolt.Tx, task *api.Task) (
|
|||
}
|
||||
|
||||
func (w *worker) newTaskManager(ctx context.Context, tx *bolt.Tx, task *api.Task) (*taskManager, error) {
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{
|
||||
"task.id": task.ID,
|
||||
"service.id": task.ServiceID,
|
||||
}))
|
||||
|
|
4
vendor/github.com/moby/swarmkit/v2/ca/auth.go
generated
vendored
4
vendor/github.com/moby/swarmkit/v2/ca/auth.go
generated
vendored
|
@ -6,8 +6,6 @@ import (
|
|||
"crypto/x509/pkix"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"google.golang.org/grpc/codes"
|
||||
|
@ -43,7 +41,7 @@ func LogTLSState(ctx context.Context, tlsState *tls.ConnectionState) {
|
|||
verifiedChain = append(verifiedChain, strings.Join(subjects, ","))
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"peer.peerCert": peerCerts,
|
||||
// "peer.verifiedChain": verifiedChain},
|
||||
}).Debugf("")
|
||||
|
|
4
vendor/github.com/moby/swarmkit/v2/ca/certificates.go
generated
vendored
4
vendor/github.com/moby/swarmkit/v2/ca/certificates.go
generated
vendored
|
@ -769,7 +769,7 @@ func CreateRootCA(rootCN string) (RootCA, error) {
|
|||
// Create a simple CSR for the CA using the default CA validator and policy
|
||||
req := cfcsr.CertificateRequest{
|
||||
CN: rootCN,
|
||||
KeyRequest: &cfcsr.BasicKeyRequest{A: RootKeyAlgo, S: RootKeySize},
|
||||
KeyRequest: &cfcsr.KeyRequest{A: RootKeyAlgo, S: RootKeySize},
|
||||
CA: &cfcsr.CAConfig{Expiry: RootCAExpiration},
|
||||
}
|
||||
|
||||
|
@ -919,7 +919,7 @@ func SaveRootCA(rootCA RootCA, paths CertPaths) error {
|
|||
// GenerateNewCSR returns a newly generated key and CSR signed with said key
|
||||
func GenerateNewCSR() ([]byte, []byte, error) {
|
||||
req := &cfcsr.CertificateRequest{
|
||||
KeyRequest: cfcsr.NewBasicKeyRequest(),
|
||||
KeyRequest: cfcsr.NewKeyRequest(),
|
||||
}
|
||||
|
||||
csr, key, err := cfcsr.ParseRequest(req)
|
||||
|
|
13
vendor/github.com/moby/swarmkit/v2/ca/config.go
generated
vendored
13
vendor/github.com/moby/swarmkit/v2/ca/config.go
generated
vendored
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/watch"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
|
@ -463,7 +462,7 @@ func LoadSecurityConfig(ctx context.Context, rootCA RootCA, krw *KeyReadWriter,
|
|||
PublicKey: issuer.RawSubjectPublicKeyInfo,
|
||||
})
|
||||
if err == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": secConfig.ClientTLSCreds.NodeID(),
|
||||
"node.role": secConfig.ClientTLSCreds.Role(),
|
||||
}).Debug("loaded node credentials")
|
||||
|
@ -524,12 +523,12 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
|
|||
return nil, nil, err
|
||||
}
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": cn,
|
||||
"node.role": proposedRole,
|
||||
}).Debug("issued new TLS certificate")
|
||||
default:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": cn,
|
||||
"node.role": proposedRole,
|
||||
}).WithError(err).Errorf("failed to issue and save new certificate")
|
||||
|
@ -538,7 +537,7 @@ func (rootCA RootCA) CreateSecurityConfig(ctx context.Context, krw *KeyReadWrite
|
|||
|
||||
secConfig, cleanup, err := NewSecurityConfig(&rootCA, krw, tlsKeyPair, issuerInfo)
|
||||
if err == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": secConfig.ClientTLSCreds.NodeID(),
|
||||
"node.role": secConfig.ClientTLSCreds.Role(),
|
||||
}).Debugf("new node credentials generated: %s", krw.Target())
|
||||
|
@ -579,7 +578,7 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
|
|||
defer s.renewalMu.Unlock()
|
||||
|
||||
ctx = log.WithModule(ctx, "tls")
|
||||
log := log.G(ctx).WithFields(logrus.Fields{
|
||||
logger := log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": s.ClientTLSCreds.NodeID(),
|
||||
"node.role": s.ClientTLSCreds.Role(),
|
||||
})
|
||||
|
@ -602,7 +601,7 @@ func RenewTLSConfigNow(ctx context.Context, s *SecurityConfig, connBroker *conne
|
|||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("failed to renew the certificate")
|
||||
logger.WithError(err).Errorf("failed to renew the certificate")
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
3
vendor/github.com/moby/swarmkit/v2/ca/external.go
generated
vendored
3
vendor/github.com/moby/swarmkit/v2/ca/external.go
generated
vendored
|
@ -20,7 +20,6 @@ import (
|
|||
"github.com/cloudflare/cfssl/signer"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
|
||||
|
@ -203,7 +202,7 @@ func makeExternalSignRequest(ctx context.Context, client *http.Client, url strin
|
|||
|
||||
var apiResponse api.Response
|
||||
if err := json.Unmarshal(body, &apiResponse); err != nil {
|
||||
logrus.Debugf("unable to JSON-parse CFSSL API response body: %s", string(body))
|
||||
log.G(ctx).Debugf("unable to JSON-parse CFSSL API response body: %s", string(body))
|
||||
return nil, recoverableErr{err: errors.Wrap(err, "unable to parse JSON response")}
|
||||
}
|
||||
|
||||
|
|
21
vendor/github.com/moby/swarmkit/v2/ca/renewer.go
generated
vendored
21
vendor/github.com/moby/swarmkit/v2/ca/renewer.go
generated
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/connectionbroker"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// RenewTLSExponentialBackoff sets the exponential backoff when trying to renew TLS certificates that have expired
|
||||
|
@ -72,7 +71,7 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate {
|
|||
defer close(updates)
|
||||
for {
|
||||
ctx = log.WithModule(ctx, "tls")
|
||||
log := log.G(ctx).WithFields(logrus.Fields{
|
||||
logger := log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": t.s.ClientTLSCreds.NodeID(),
|
||||
"node.role": t.s.ClientTLSCreds.Role(),
|
||||
})
|
||||
|
@ -85,19 +84,19 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate {
|
|||
validFrom, validUntil, err := readCertValidity(t.s.KeyReader())
|
||||
if err != nil {
|
||||
// We failed to read the expiration, let's stick with the starting default
|
||||
log.Errorf("failed to read the expiration of the TLS certificate in: %s", t.s.KeyReader().Target())
|
||||
logger.Errorf("failed to read the expiration of the TLS certificate in: %s", t.s.KeyReader().Target())
|
||||
|
||||
select {
|
||||
case updates <- CertificateUpdate{Err: errors.New("failed to read certificate expiration")}:
|
||||
case <-ctx.Done():
|
||||
log.Info("shutting down certificate renewal routine")
|
||||
logger.Info("shutting down certificate renewal routine")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// If we have an expired certificate, try to renew immediately: the hope that this is a temporary clock skew, or
|
||||
// we can issue our own TLS certs.
|
||||
if validUntil.Before(time.Now()) {
|
||||
log.Warn("the current TLS certificate is expired, so an attempt to renew it will be made immediately")
|
||||
logger.Warn("the current TLS certificate is expired, so an attempt to renew it will be made immediately")
|
||||
// retry immediately(ish) with exponential backoff
|
||||
retry = expBackoff.Proceed(nil)
|
||||
} else if forceRetry {
|
||||
|
@ -110,16 +109,16 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate {
|
|||
}
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
logger.WithFields(log.Fields{
|
||||
"time": time.Now().Add(retry),
|
||||
}).Debugf("next certificate renewal scheduled for %v from now", retry)
|
||||
|
||||
select {
|
||||
case <-time.After(retry):
|
||||
log.Info("renewing certificate")
|
||||
logger.Info("renewing certificate")
|
||||
case <-t.renew:
|
||||
forceRetry = true
|
||||
log.Info("forced certificate renewal")
|
||||
logger.Info("forced certificate renewal")
|
||||
|
||||
// Pause briefly before attempting the renewal,
|
||||
// to give the CA a chance to reconcile the
|
||||
|
@ -127,11 +126,11 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate {
|
|||
select {
|
||||
case <-time.After(500 * time.Millisecond):
|
||||
case <-ctx.Done():
|
||||
log.Info("shutting down certificate renewal routine")
|
||||
logger.Info("shutting down certificate renewal routine")
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
log.Info("shutting down certificate renewal routine")
|
||||
logger.Info("shutting down certificate renewal routine")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -158,7 +157,7 @@ func (t *TLSRenewer) Start(ctx context.Context) <-chan CertificateUpdate {
|
|||
select {
|
||||
case updates <- certUpdate:
|
||||
case <-ctx.Done():
|
||||
log.Info("shutting down certificate renewal routine")
|
||||
logger.Info("shutting down certificate renewal routine")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
31
vendor/github.com/moby/swarmkit/v2/ca/server.go
generated
vendored
31
vendor/github.com/moby/swarmkit/v2/ca/server.go
generated
vendored
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -182,7 +181,7 @@ func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCer
|
|||
return nil, status.Errorf(codes.NotFound, codes.NotFound.String())
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": node.ID,
|
||||
"status": node.Certificate.Status,
|
||||
"method": "NodeCertificateStatus",
|
||||
|
@ -196,7 +195,7 @@ func (s *Server) NodeCertificateStatus(ctx context.Context, request *api.NodeCer
|
|||
}, nil
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": node.ID,
|
||||
"status": node.Certificate.Status,
|
||||
"method": "NodeCertificateStatus",
|
||||
|
@ -326,7 +325,7 @@ func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNod
|
|||
return store.CreateNode(tx, node)
|
||||
})
|
||||
if err == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.role": role,
|
||||
"method": "IssueNodeCertificate",
|
||||
|
@ -339,7 +338,7 @@ func (s *Server) IssueNodeCertificate(ctx context.Context, request *api.IssueNod
|
|||
if i == maxRetries {
|
||||
return nil, err
|
||||
}
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.role": role,
|
||||
"method": "IssueNodeCertificate",
|
||||
|
@ -363,7 +362,7 @@ func (s *Server) issueRenewCertificate(ctx context.Context, nodeID string, csr [
|
|||
// Attempt to retrieve the node with nodeID
|
||||
node = store.GetNode(tx, nodeID)
|
||||
if node == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"method": "issueRenewCertificate",
|
||||
}).Warnf("node does not exist")
|
||||
|
@ -388,7 +387,7 @@ func (s *Server) issueRenewCertificate(ctx context.Context, nodeID string, csr [
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"cert.cn": cert.CN,
|
||||
"cert.role": cert.Role,
|
||||
"method": "issueRenewCertificate",
|
||||
|
@ -404,7 +403,7 @@ func (s *Server) issueRenewCertificate(ctx context.Context, nodeID string, csr [
|
|||
// the root of trust for the swarm. Clients should be using the CA hash to verify if they weren't target to
|
||||
// a MiTM. If they fail to do so, node bootstrap works with TOFU semantics.
|
||||
func (s *Server) GetRootCACertificate(ctx context.Context, request *api.GetRootCACertificateRequest) (*api.GetRootCACertificateResponse, error) {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"method": "GetRootCACertificate",
|
||||
})
|
||||
|
||||
|
@ -477,7 +476,7 @@ func (s *Server) Run(ctx context.Context) error {
|
|||
s.mu.Unlock()
|
||||
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"method": "(*Server).Run",
|
||||
}).WithError(err).Errorf("snapshot store view failed")
|
||||
return err
|
||||
|
@ -489,7 +488,7 @@ func (s *Server) Run(ctx context.Context) error {
|
|||
if err := s.reconcileNodeCertificates(ctx, nodes); err != nil {
|
||||
// We don't return here because that means the Run loop would
|
||||
// never run. Log an error instead.
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"method": "(*Server).Run",
|
||||
}).WithError(err).Errorf("error attempting to reconcile certificates")
|
||||
}
|
||||
|
@ -668,7 +667,7 @@ func (s *Server) UpdateRootCA(ctx context.Context, cluster *api.Cluster, reconci
|
|||
firstSeenCluster := s.lastSeenClusterRootCA == nil && s.lastSeenExternalCAs == nil
|
||||
rootCAChanged := len(rCA.CACert) != 0 && !equality.RootCAEqualStable(s.lastSeenClusterRootCA, rCA)
|
||||
externalCAChanged := !equality.ExternalCAsEqualStable(s.lastSeenExternalCAs, cluster.Spec.CAConfig.ExternalCAs)
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(logrus.Fields{
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{
|
||||
"cluster.id": cluster.ID,
|
||||
"method": "(*Server).UpdateRootCA",
|
||||
}))
|
||||
|
@ -773,7 +772,7 @@ func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
|
|||
// Convert the role from proto format
|
||||
role, err := ParseRole(node.Certificate.Role)
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": node.ID,
|
||||
"method": "(*Server).signNodeCert",
|
||||
}).WithError(err).Errorf("failed to parse role")
|
||||
|
@ -798,7 +797,7 @@ func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": node.ID,
|
||||
"method": "(*Server).signNodeCert",
|
||||
}).WithError(err).Errorf("failed to sign CSR")
|
||||
|
@ -830,7 +829,7 @@ func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
|
|||
return store.UpdateNode(tx, node)
|
||||
})
|
||||
if err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"method": "(*Server).signNodeCert",
|
||||
}).WithError(err).Errorf("transaction failed when setting state to FAILED")
|
||||
|
@ -858,7 +857,7 @@ func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
|
|||
return err
|
||||
})
|
||||
if err == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": node.ID,
|
||||
"node.role": node.Certificate.Role,
|
||||
"method": "(*Server).signNodeCert",
|
||||
|
@ -870,7 +869,7 @@ func (s *Server) signNodeCert(ctx context.Context, node *api.Node) error {
|
|||
continue
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"method": "(*Server).signNodeCert",
|
||||
}).WithError(err).Errorf("transaction failed")
|
||||
|
|
7
vendor/github.com/moby/swarmkit/v2/log/context.go
generated
vendored
7
vendor/github.com/moby/swarmkit/v2/log/context.go
generated
vendored
|
@ -23,6 +23,9 @@ type (
|
|||
moduleKey struct{}
|
||||
)
|
||||
|
||||
// Fields type to pass to "WithFields".
|
||||
type Fields = map[string]any
|
||||
|
||||
// WithLogger returns a new context with the provided logger. Use in
|
||||
// combination with logger.WithField(s) for great effect.
|
||||
func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
|
||||
|
@ -30,7 +33,7 @@ func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context {
|
|||
}
|
||||
|
||||
// WithFields returns a new context with added fields to logger.
|
||||
func WithFields(ctx context.Context, fields logrus.Fields) context.Context {
|
||||
func WithFields(ctx context.Context, fields Fields) context.Context {
|
||||
logger := ctx.Value(loggerKey{})
|
||||
|
||||
if logger == nil {
|
||||
|
@ -41,7 +44,7 @@ func WithFields(ctx context.Context, fields logrus.Fields) context.Context {
|
|||
|
||||
// WithField is convenience wrapper around WithFields.
|
||||
func WithField(ctx context.Context, key, value string) context.Context {
|
||||
return WithFields(ctx, logrus.Fields{key: value})
|
||||
return WithFields(ctx, Fields{key: value})
|
||||
}
|
||||
|
||||
// GetLogger retrieves the current logger from the context. If no logger is
|
||||
|
|
5
vendor/github.com/moby/swarmkit/v2/manager/allocator/cnmallocator/drivers_ipam.go
generated
vendored
5
vendor/github.com/moby/swarmkit/v2/manager/allocator/cnmallocator/drivers_ipam.go
generated
vendored
|
@ -1,6 +1,7 @@
|
|||
package cnmallocator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -8,7 +9,7 @@ import (
|
|||
builtinIpam "github.com/docker/docker/libnetwork/ipams/builtin"
|
||||
nullIpam "github.com/docker/docker/libnetwork/ipams/null"
|
||||
"github.com/docker/docker/libnetwork/ipamutils"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
)
|
||||
|
||||
func initIPAMDrivers(r ipamapi.Registerer, netConfig *NetworkConfig) error {
|
||||
|
@ -35,7 +36,7 @@ func initIPAMDrivers(r ipamapi.Registerer, netConfig *NetworkConfig) error {
|
|||
return err
|
||||
}
|
||||
if addressPool != nil {
|
||||
logrus.Infof("Swarm initialized global default address pool to: " + str.String())
|
||||
log.G(context.TODO()).Infof("Swarm initialized global default address pool to: " + str.String())
|
||||
}
|
||||
|
||||
for _, fn := range [](func(ipamapi.Registerer) error){
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -261,7 +260,7 @@ vipLoop:
|
|||
}
|
||||
for _, nAttach := range specNetworks {
|
||||
if nAttach.Target == eAttach.NetworkID {
|
||||
log.L.WithFields(logrus.Fields{"service_id": s.ID, "vip": eAttach.Addr}).Debug("allocate vip")
|
||||
log.L.WithFields(log.Fields{"service_id": s.ID, "vip": eAttach.Addr}).Debug("allocate vip")
|
||||
if err = na.allocateVIP(eAttach); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
7
vendor/github.com/moby/swarmkit/v2/manager/controlapi/config.go
generated
vendored
7
vendor/github.com/moby/swarmkit/v2/manager/controlapi/config.go
generated
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/identity"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -80,7 +79,7 @@ func (s *Server) UpdateConfig(ctx context.Context, request *api.UpdateConfigRequ
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"config.ID": request.ConfigID,
|
||||
"config.Name": request.Spec.Annotations.Name,
|
||||
"method": "UpdateConfig",
|
||||
|
@ -166,7 +165,7 @@ func (s *Server) CreateConfig(ctx context.Context, request *api.CreateConfigRequ
|
|||
case store.ErrNameConflict:
|
||||
return nil, status.Errorf(codes.AlreadyExists, "config %s already exists", request.Spec.Annotations.Name)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"config.Name": request.Spec.Annotations.Name,
|
||||
"method": "CreateConfig",
|
||||
}).Debugf("config created")
|
||||
|
@ -222,7 +221,7 @@ func (s *Server) RemoveConfig(ctx context.Context, request *api.RemoveConfigRequ
|
|||
case store.ErrNotExist:
|
||||
return nil, status.Errorf(codes.NotFound, "config %s not found", request.ConfigID)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"config.ID": request.ConfigID,
|
||||
"method": "RemoveConfig",
|
||||
}).Debugf("config removed")
|
||||
|
|
5
vendor/github.com/moby/swarmkit/v2/manager/controlapi/extension.go
generated
vendored
5
vendor/github.com/moby/swarmkit/v2/manager/controlapi/extension.go
generated
vendored
|
@ -8,7 +8,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/identity"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -37,7 +36,7 @@ func (s *Server) CreateExtension(ctx context.Context, request *api.CreateExtensi
|
|||
case store.ErrNameConflict:
|
||||
return nil, status.Errorf(codes.AlreadyExists, "extension %s already exists", request.Annotations.Name)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"extension.Name": request.Annotations.Name,
|
||||
"method": "CreateExtension",
|
||||
}).Debugf("extension created")
|
||||
|
@ -121,7 +120,7 @@ func (s *Server) RemoveExtension(ctx context.Context, request *api.RemoveExtensi
|
|||
case store.ErrNotExist:
|
||||
return nil, status.Errorf(codes.NotFound, "extension %s not found", request.ExtensionID)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"extension.ID": request.ExtensionID,
|
||||
"method": "RemoveExtension",
|
||||
}).Debugf("extension removed")
|
||||
|
|
3
vendor/github.com/moby/swarmkit/v2/manager/controlapi/resource.go
generated
vendored
3
vendor/github.com/moby/swarmkit/v2/manager/controlapi/resource.go
generated
vendored
|
@ -3,7 +3,6 @@ package controlapi
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
|
@ -50,7 +49,7 @@ func (s *Server) CreateResource(ctx context.Context, request *api.CreateResource
|
|||
r.Annotations.Name,
|
||||
)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"resource.Name": r.Annotations.Name,
|
||||
"method": "CreateResource",
|
||||
}).Debugf("resource created")
|
||||
|
|
7
vendor/github.com/moby/swarmkit/v2/manager/controlapi/secret.go
generated
vendored
7
vendor/github.com/moby/swarmkit/v2/manager/controlapi/secret.go
generated
vendored
|
@ -10,7 +10,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/identity"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -78,7 +77,7 @@ func (s *Server) UpdateSecret(ctx context.Context, request *api.UpdateSecretRequ
|
|||
return nil, err
|
||||
}
|
||||
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"secret.ID": request.SecretID,
|
||||
"secret.Name": request.Spec.Annotations.Name,
|
||||
"method": "UpdateSecret",
|
||||
|
@ -174,7 +173,7 @@ func (s *Server) CreateSecret(ctx context.Context, request *api.CreateSecretRequ
|
|||
return nil, status.Errorf(codes.AlreadyExists, "secret %s already exists", request.Spec.Annotations.Name)
|
||||
case nil:
|
||||
secret.Spec.Data = nil // clean the actual secret data so it's never returned
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"secret.Name": request.Spec.Annotations.Name,
|
||||
"method": "CreateSecret",
|
||||
}).Debugf("secret created")
|
||||
|
@ -230,7 +229,7 @@ func (s *Server) RemoveSecret(ctx context.Context, request *api.RemoveSecretRequ
|
|||
case store.ErrNotExist:
|
||||
return nil, status.Errorf(codes.NotFound, "secret %s not found", request.SecretID)
|
||||
case nil:
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"secret.ID": request.SecretID,
|
||||
"method": "RemoveSecret",
|
||||
}).Debugf("secret removed")
|
||||
|
|
6
vendor/github.com/moby/swarmkit/v2/manager/csi/manager.go
generated
vendored
6
vendor/github.com/moby/swarmkit/v2/manager/csi/manager.go
generated
vendored
|
@ -7,10 +7,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/go-events"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/docker/docker/pkg/plugingetter"
|
||||
"github.com/docker/go-events"
|
||||
|
||||
"github.com/moby/swarmkit/v2/api"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
|
@ -154,7 +152,7 @@ func (vm *Manager) run(pctx context.Context) {
|
|||
// processVolumes encapuslates the logic for processing pending Volumes.
|
||||
func (vm *Manager) processVolume(ctx context.Context, id string, attempt uint) {
|
||||
// set up log fields for a derrived context to pass to handleVolume.
|
||||
logCtx := log.WithFields(ctx, logrus.Fields{
|
||||
logCtx := log.WithFields(ctx, log.Fields{
|
||||
"volume.id": id,
|
||||
"attempt": attempt,
|
||||
})
|
||||
|
|
5
vendor/github.com/moby/swarmkit/v2/manager/dispatcher/assignments.go
generated
vendored
5
vendor/github.com/moby/swarmkit/v2/manager/dispatcher/assignments.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/moby/swarmkit/v2/api/equality"
|
||||
"github.com/moby/swarmkit/v2/api/validation"
|
||||
"github.com/moby/swarmkit/v2/identity"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/drivers"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -53,7 +54,7 @@ func assignSecret(a *assignmentSet, readTx store.ReadTx, mapKey typeAndID, t *ap
|
|||
}
|
||||
secret, doNotReuse, err := a.secret(readTx, t, mapKey.id)
|
||||
if err != nil {
|
||||
a.log.WithFields(logrus.Fields{
|
||||
a.log.WithFields(log.Fields{
|
||||
"resource.type": "secret",
|
||||
"secret.id": mapKey.id,
|
||||
"error": err,
|
||||
|
@ -89,7 +90,7 @@ func assignConfig(a *assignmentSet, readTx store.ReadTx, mapKey typeAndID) {
|
|||
a.tasksUsingDependency[mapKey] = make(map[string]struct{})
|
||||
config := store.GetConfig(readTx, mapKey.id)
|
||||
if config == nil {
|
||||
a.log.WithFields(logrus.Fields{
|
||||
a.log.WithFields(log.Fields{
|
||||
"resource.type": "config",
|
||||
"config.id": mapKey.id,
|
||||
}).Debug("config not found")
|
||||
|
|
61
vendor/github.com/moby/swarmkit/v2/manager/dispatcher/dispatcher.go
generated
vendored
61
vendor/github.com/moby/swarmkit/v2/manager/dispatcher/dispatcher.go
generated
vendored
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/remotes"
|
||||
"github.com/moby/swarmkit/v2/watch"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -619,7 +618,7 @@ func (d *Dispatcher) UpdateTaskStatus(ctx context.Context, r *api.UpdateTaskStat
|
|||
return nil, err
|
||||
}
|
||||
nodeID := nodeInfo.NodeID
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.session": r.SessionID,
|
||||
"method": "(*Dispatcher).UpdateTaskStatus",
|
||||
|
@ -695,7 +694,7 @@ func (d *Dispatcher) UpdateVolumeStatus(ctx context.Context, r *api.UpdateVolume
|
|||
}
|
||||
|
||||
nodeID := nodeInfo.NodeID
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.session": r.SessionID,
|
||||
"method": "(*Dispatcher).UpdateVolumeStatus",
|
||||
|
@ -703,19 +702,19 @@ func (d *Dispatcher) UpdateVolumeStatus(ctx context.Context, r *api.UpdateVolume
|
|||
if nodeInfo.ForwardedBy != nil {
|
||||
fields["forwarder.id"] = nodeInfo.ForwardedBy.NodeID
|
||||
}
|
||||
log := log.G(ctx).WithFields(fields)
|
||||
logger := log.G(ctx).WithFields(fields)
|
||||
|
||||
if _, err := d.nodes.GetWithSession(nodeID, r.SessionID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.unpublishedVolumesLock.Lock()
|
||||
for _, status := range r.Updates {
|
||||
if status.Unpublished {
|
||||
for _, volumeStatus := range r.Updates {
|
||||
if volumeStatus.Unpublished {
|
||||
// it's ok if nodes is nil, because append works on a nil slice.
|
||||
nodes := append(d.unpublishedVolumes[status.ID], nodeID)
|
||||
d.unpublishedVolumes[status.ID] = nodes
|
||||
log.Debugf("volume %s unpublished on node %s", status.ID, nodeID)
|
||||
nodes := append(d.unpublishedVolumes[volumeStatus.ID], nodeID)
|
||||
d.unpublishedVolumes[volumeStatus.ID] = nodes
|
||||
logger.Debugf("volume %s unpublished on node %s", volumeStatus.ID, nodeID)
|
||||
}
|
||||
}
|
||||
d.unpublishedVolumesLock.Unlock()
|
||||
|
@ -756,14 +755,14 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
log := log.G(ctx).WithFields(logrus.Fields{
|
||||
logr := log.G(ctx).WithFields(log.Fields{
|
||||
"method": "(*Dispatcher).processUpdates",
|
||||
})
|
||||
|
||||
err := d.store.Batch(func(batch *store.Batch) error {
|
||||
for taskID, status := range taskUpdates {
|
||||
for taskID, taskStatus := range taskUpdates {
|
||||
err := batch.Update(func(tx store.Tx) error {
|
||||
logger := log.WithField("task.id", taskID)
|
||||
logger := logr.WithField("task.id", taskID)
|
||||
task := store.GetTask(tx, taskID)
|
||||
if task == nil {
|
||||
// Task may have been deleted
|
||||
|
@ -771,14 +770,14 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
return nil
|
||||
}
|
||||
|
||||
logger = logger.WithField("state.transition", fmt.Sprintf("%v->%v", task.Status.State, status.State))
|
||||
logger = logger.WithField("state.transition", fmt.Sprintf("%v->%v", task.Status.State, taskStatus.State))
|
||||
|
||||
if task.Status == *status {
|
||||
if task.Status == *taskStatus {
|
||||
logger.Debug("task status identical, ignoring")
|
||||
return nil
|
||||
}
|
||||
|
||||
if task.Status.State > status.State {
|
||||
if task.Status.State > taskStatus.State {
|
||||
logger.Debug("task status invalid transition")
|
||||
return nil
|
||||
}
|
||||
|
@ -789,12 +788,12 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
// the network delay between the worker and the leader.
|
||||
// This is not ideal, but its a known overestimation, rather than using the status update time
|
||||
// from the worker node, which may cause unknown incorrect results due to possible clock skew.
|
||||
if status.State == api.TaskStateRunning {
|
||||
start := time.Unix(status.AppliedAt.GetSeconds(), int64(status.AppliedAt.GetNanos()))
|
||||
if taskStatus.State == api.TaskStateRunning {
|
||||
start := time.Unix(taskStatus.AppliedAt.GetSeconds(), int64(taskStatus.AppliedAt.GetNanos()))
|
||||
schedulingDelayTimer.UpdateSince(start)
|
||||
}
|
||||
|
||||
task.Status = *status
|
||||
task.Status = *taskStatus
|
||||
task.Status.AppliedBy = d.securityConfig.ClientTLSCreds.NodeID()
|
||||
task.Status.AppliedAt = ptypes.MustTimestampProto(time.Now())
|
||||
logger.Debugf("state for task %v updated to %v", task.GetID(), task.Status.State)
|
||||
|
@ -806,13 +805,13 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.WithError(err).Error("dispatcher task update transaction failed")
|
||||
logr.WithError(err).Error("dispatcher task update transaction failed")
|
||||
}
|
||||
}
|
||||
|
||||
for nodeID, nodeUpdate := range nodeUpdates {
|
||||
err := batch.Update(func(tx store.Tx) error {
|
||||
logger := log.WithField("node.id", nodeID)
|
||||
logger := logr.WithField("node.id", nodeID)
|
||||
node := store.GetNode(tx, nodeID)
|
||||
if node == nil {
|
||||
logger.Error("node unavailable")
|
||||
|
@ -838,13 +837,13 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.WithError(err).Error("dispatcher node update transaction failed")
|
||||
logr.WithError(err).Error("dispatcher node update transaction failed")
|
||||
}
|
||||
}
|
||||
|
||||
for volumeID, nodes := range unpublishedVolumes {
|
||||
err := batch.Update(func(tx store.Tx) error {
|
||||
logger := log.WithField("volume.id", volumeID)
|
||||
logger := logr.WithField("volume.id", volumeID)
|
||||
volume := store.GetVolume(tx, volumeID)
|
||||
if volume == nil {
|
||||
logger.Error("volume unavailable")
|
||||
|
@ -869,14 +868,14 @@ func (d *Dispatcher) processUpdates(ctx context.Context) {
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Error("dispatcher volume update transaction failed")
|
||||
logr.WithError(err).Error("dispatcher volume update transaction failed")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.WithError(err).Error("dispatcher batch failed")
|
||||
logr.WithError(err).Error("dispatcher batch failed")
|
||||
}
|
||||
|
||||
d.processUpdatesCond.Broadcast()
|
||||
|
@ -900,7 +899,7 @@ func (d *Dispatcher) Tasks(r *api.TasksRequest, stream api.Dispatcher_TasksServe
|
|||
}
|
||||
nodeID := nodeInfo.NodeID
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.session": r.SessionID,
|
||||
"method": "(*Dispatcher).Tasks",
|
||||
|
@ -1026,7 +1025,7 @@ func (d *Dispatcher) Assignments(r *api.AssignmentsRequest, stream api.Dispatche
|
|||
}
|
||||
nodeID := nodeInfo.NodeID
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.session": r.SessionID,
|
||||
"method": "(*Dispatcher).Assignments",
|
||||
|
@ -1394,7 +1393,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
|
|||
}
|
||||
}
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.session": sessionID,
|
||||
"method": "(*Dispatcher).Session",
|
||||
|
@ -1402,7 +1401,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
|
|||
if nodeInfo.ForwardedBy != nil {
|
||||
fields["forwarder.id"] = nodeInfo.ForwardedBy.NodeID
|
||||
}
|
||||
log := log.G(ctx).WithFields(fields)
|
||||
logger := log.G(ctx).WithFields(fields)
|
||||
|
||||
var nodeObj *api.Node
|
||||
nodeUpdates, cancel, err := store.ViewAndWatch(d.store, func(readTx store.ReadTx) error {
|
||||
|
@ -1416,7 +1415,7 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
|
|||
}
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Error("ViewAndWatch Node failed")
|
||||
logger.WithError(err).Error("ViewAndWatch Node failed")
|
||||
}
|
||||
|
||||
if _, err = d.nodes.GetWithSession(nodeID, sessionID); err != nil {
|
||||
|
@ -1438,9 +1437,9 @@ func (d *Dispatcher) Session(r *api.SessionRequest, stream api.Dispatcher_Sessio
|
|||
|
||||
// disconnectNode is a helper forcibly shutdown connection
|
||||
disconnectNode := func() error {
|
||||
log.Infof("dispatcher session dropped, marking node %s down", nodeID)
|
||||
logger.Infof("dispatcher session dropped, marking node %s down", nodeID)
|
||||
if err := d.markNodeNotReady(nodeID, api.NodeStatus_DISCONNECTED, "node is currently trying to find new manager"); err != nil {
|
||||
log.WithError(err).Error("failed to remove node")
|
||||
logger.WithError(err).Error("failed to remove node")
|
||||
}
|
||||
// still return an abort if the transport closure was ineffective.
|
||||
return status.Errorf(codes.Aborted, "node must disconnect")
|
||||
|
|
17
vendor/github.com/moby/swarmkit/v2/manager/logbroker/broker.go
generated
vendored
17
vendor/github.com/moby/swarmkit/v2/manager/logbroker/broker.go
generated
vendored
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/log"
|
||||
"github.com/moby/swarmkit/v2/manager/state/store"
|
||||
"github.com/moby/swarmkit/v2/watch"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
@ -239,13 +238,13 @@ func (lb *LogBroker) SubscribeLogs(request *api.SubscribeLogsRequest, stream api
|
|||
subscription.Run(pctx)
|
||||
defer subscription.Stop()
|
||||
|
||||
log := log.G(ctx).WithFields(
|
||||
logrus.Fields{
|
||||
logger := log.G(ctx).WithFields(
|
||||
log.Fields{
|
||||
"method": "(*LogBroker).SubscribeLogs",
|
||||
"subscription.id": subscription.message.ID,
|
||||
},
|
||||
)
|
||||
log.Debug("subscribed")
|
||||
logger.Debug("subscribed")
|
||||
|
||||
publishCh, publishCancel := lb.subscribe(subscription.message.ID)
|
||||
defer publishCancel()
|
||||
|
@ -319,8 +318,8 @@ func (lb *LogBroker) ListenSubscriptions(request *api.ListenSubscriptionsRequest
|
|||
lb.nodeConnected(remote.NodeID)
|
||||
defer lb.nodeDisconnected(remote.NodeID)
|
||||
|
||||
log := log.G(stream.Context()).WithFields(
|
||||
logrus.Fields{
|
||||
logger := log.G(stream.Context()).WithFields(
|
||||
log.Fields{
|
||||
"method": "(*LogBroker).ListenSubscriptions",
|
||||
"node": remote.NodeID,
|
||||
},
|
||||
|
@ -328,7 +327,7 @@ func (lb *LogBroker) ListenSubscriptions(request *api.ListenSubscriptionsRequest
|
|||
subscriptions, subscriptionCh, subscriptionCancel := lb.watchSubscriptions(remote.NodeID)
|
||||
defer subscriptionCancel()
|
||||
|
||||
log.Debug("node registered")
|
||||
logger.Debug("node registered")
|
||||
|
||||
activeSubscriptions := make(map[string]*subscription)
|
||||
|
||||
|
@ -343,7 +342,7 @@ func (lb *LogBroker) ListenSubscriptions(request *api.ListenSubscriptionsRequest
|
|||
}
|
||||
|
||||
if err := stream.Send(subscription.message); err != nil {
|
||||
log.Error(err)
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
activeSubscriptions[subscription.message.ID] = subscription
|
||||
|
@ -365,7 +364,7 @@ func (lb *LogBroker) ListenSubscriptions(request *api.ListenSubscriptionsRequest
|
|||
activeSubscriptions[subscription.message.ID] = subscription
|
||||
}
|
||||
if err := stream.Send(subscription.message); err != nil {
|
||||
log.Error(err)
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
case <-stream.Context().Done():
|
||||
|
|
12
vendor/github.com/moby/swarmkit/v2/manager/manager.go
generated
vendored
12
vendor/github.com/moby/swarmkit/v2/manager/manager.go
generated
vendored
|
@ -49,7 +49,6 @@ import (
|
|||
"github.com/moby/swarmkit/v2/remotes"
|
||||
"github.com/moby/swarmkit/v2/xnet"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
@ -736,7 +735,7 @@ func (m *Manager) Stop(ctx context.Context, clearData bool) {
|
|||
func (m *Manager) updateKEK(ctx context.Context, cluster *api.Cluster) error {
|
||||
securityConfig := m.config.SecurityConfig
|
||||
nodeID := m.config.SecurityConfig.ClientTLSCreds.NodeID()
|
||||
logger := log.G(ctx).WithFields(logrus.Fields{
|
||||
logger := log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": nodeID,
|
||||
"node.role": ca.ManagerRole,
|
||||
})
|
||||
|
@ -899,11 +898,10 @@ func (m *Manager) serveListener(ctx context.Context, lCh <-chan net.Listener) {
|
|||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(
|
||||
logrus.Fields{
|
||||
"proto": l.Addr().Network(),
|
||||
"addr": l.Addr().String(),
|
||||
}))
|
||||
ctx = log.WithLogger(ctx, log.G(ctx).WithFields(log.Fields{
|
||||
"proto": l.Addr().Network(),
|
||||
"addr": l.Addr().String(),
|
||||
}))
|
||||
if _, ok := l.(*net.TCPListener); !ok {
|
||||
log.G(ctx).Info("Listening for local connections")
|
||||
// we need to disallow double closes because UnixListener.Close
|
||||
|
|
16
vendor/github.com/moby/swarmkit/v2/manager/scheduler/scheduler.go
generated
vendored
16
vendor/github.com/moby/swarmkit/v2/manager/scheduler/scheduler.go
generated
vendored
|
@ -488,6 +488,18 @@ func (s *Scheduler) tick(ctx context.Context) {
|
|||
}
|
||||
|
||||
func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDecisions map[string]schedulingDecision) (successful, failed []schedulingDecision) {
|
||||
// applySchedulingDecisions is the only place where we make store
|
||||
// transactions in the scheduler. the scheduler is responsible for freeing
|
||||
// volumes that are no longer in use. this means that volumes should be
|
||||
// freed in this function. sometimes, there are no scheduling decisions to
|
||||
// be made, so we return early in the if statement below.
|
||||
//
|
||||
// however, in all cases, any activity that results in a tick could result
|
||||
// in needing volumes to be freed, even if nothing new is scheduled. this
|
||||
// freeing of volumes should always happen *after* all of the scheduling
|
||||
// decisions have been committed, hence the defer.
|
||||
defer s.store.Batch(s.volumes.freeVolumes)
|
||||
|
||||
if len(schedulingDecisions) == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -619,9 +631,7 @@ func (s *Scheduler) applySchedulingDecisions(ctx context.Context, schedulingDeci
|
|||
}
|
||||
// finally, every time we make new scheduling decisions, take the
|
||||
// opportunity to release volumes.
|
||||
return batch.Update(func(tx store.Tx) error {
|
||||
return s.volumes.freeVolumes(tx)
|
||||
})
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
37
vendor/github.com/moby/swarmkit/v2/manager/scheduler/volumes.go
generated
vendored
37
vendor/github.com/moby/swarmkit/v2/manager/scheduler/volumes.go
generated
vendored
|
@ -183,24 +183,33 @@ func (vs *volumeSet) releaseVolume(volumeID, taskID string) {
|
|||
//
|
||||
// TODO(dperny): this is messy and has a lot of overhead. it should be reworked
|
||||
// to something more streamlined.
|
||||
func (vs *volumeSet) freeVolumes(tx store.Tx) error {
|
||||
func (vs *volumeSet) freeVolumes(batch *store.Batch) error {
|
||||
for volumeID, info := range vs.volumes {
|
||||
v := store.GetVolume(tx, volumeID)
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
if err := batch.Update(func(tx store.Tx) error {
|
||||
v := store.GetVolume(tx, volumeID)
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
changed := false
|
||||
for _, status := range v.PublishStatus {
|
||||
if info.nodes[status.NodeID] == 0 && status.State == api.VolumePublishStatus_PUBLISHED {
|
||||
status.State = api.VolumePublishStatus_PENDING_NODE_UNPUBLISH
|
||||
changed = true
|
||||
// when we are freeing a volume, we may update more than one of the
|
||||
// volume's PublishStatuses. this means we can't simply put the
|
||||
// Update call inside of the if statement; we need to know if we've
|
||||
// changed anything once we've checked *all* of the statuses.
|
||||
changed := false
|
||||
for _, status := range v.PublishStatus {
|
||||
if info.nodes[status.NodeID] == 0 && status.State == api.VolumePublishStatus_PUBLISHED {
|
||||
status.State = api.VolumePublishStatus_PENDING_NODE_UNPUBLISH
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
if err := store.UpdateVolume(tx, v); err != nil {
|
||||
return err
|
||||
if changed {
|
||||
if err := store.UpdateVolume(tx, v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
22
vendor/github.com/moby/swarmkit/v2/manager/state/raft/raft.go
generated
vendored
22
vendor/github.com/moby/swarmkit/v2/manager/state/raft/raft.go
generated
vendored
|
@ -929,7 +929,7 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeInfo.NodeID,
|
||||
"method": "(*Node).Join",
|
||||
"raft_id": fmt.Sprintf("%x", n.Config.ID),
|
||||
|
@ -937,8 +937,8 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
|
|||
if nodeInfo.ForwardedBy != nil {
|
||||
fields["forwarder.id"] = nodeInfo.ForwardedBy.NodeID
|
||||
}
|
||||
log := log.G(ctx).WithFields(fields)
|
||||
log.Debug("")
|
||||
logger := log.G(ctx).WithFields(fields)
|
||||
logger.Debug("")
|
||||
|
||||
// can't stop the raft node while an async RPC is in progress
|
||||
n.stopMu.RLock()
|
||||
|
@ -999,11 +999,11 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
|
|||
}
|
||||
|
||||
if err := n.updateNodeBlocking(ctx, m.RaftID, remoteAddr); err != nil {
|
||||
log.WithError(err).Error("failed to update node address")
|
||||
logger.WithError(err).Error("failed to update node address")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Info("updated node address")
|
||||
logger.Info("updated node address")
|
||||
return n.joinResponse(m.RaftID), nil
|
||||
}
|
||||
}
|
||||
|
@ -1019,11 +1019,11 @@ func (n *Node) Join(ctx context.Context, req *api.JoinRequest) (*api.JoinRespons
|
|||
|
||||
err = n.addMember(ctx, remoteAddr, raftID, nodeInfo.NodeID)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("failed to add member %x", raftID)
|
||||
logger.WithError(err).Errorf("failed to add member %x", raftID)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debug("node joined")
|
||||
logger.Debug("node joined")
|
||||
|
||||
return n.joinResponse(raftID), nil
|
||||
}
|
||||
|
@ -1126,7 +1126,7 @@ func (n *Node) UpdateNode(id uint64, addr string) {
|
|||
// spawn updating info in raft in background to unblock transport
|
||||
go func() {
|
||||
if err := n.updateNodeBlocking(ctx, id, addr); err != nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{"raft_id": n.Config.ID, "update_id": id}).WithError(err).Error("failed to update member address in cluster")
|
||||
log.G(ctx).WithFields(log.Fields{"raft_id": n.Config.ID, "update_id": id}).WithError(err).Error("failed to update member address in cluster")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -1148,7 +1148,7 @@ func (n *Node) Leave(ctx context.Context, req *api.LeaveRequest) (*api.LeaveResp
|
|||
ctx, cancel := n.WithContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeInfo.NodeID,
|
||||
"method": "(*Node).Leave",
|
||||
"raft_id": fmt.Sprintf("%x", n.Config.ID),
|
||||
|
@ -1273,7 +1273,7 @@ func (n *Node) RemoveMember(ctx context.Context, id uint64) error {
|
|||
// ProcessRaftMessage. Usually nothing will be logged, so it is useful to avoid
|
||||
// formatting strings and allocating a logger when it won't be used.
|
||||
func (n *Node) processRaftMessageLogger(ctx context.Context, msg *api.ProcessRaftMessageRequest) *logrus.Entry {
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"method": "(*Node).ProcessRaftMessage",
|
||||
}
|
||||
|
||||
|
@ -1474,7 +1474,7 @@ func (n *Node) ResolveAddress(ctx context.Context, msg *api.ResolveAddressReques
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fields := logrus.Fields{
|
||||
fields := log.Fields{
|
||||
"node.id": nodeInfo.NodeID,
|
||||
"method": "(*Node).ResolveAddress",
|
||||
"raft_id": fmt.Sprintf("%x", n.Config.ID),
|
||||
|
|
6
vendor/github.com/moby/swarmkit/v2/node/node.go
generated
vendored
6
vendor/github.com/moby/swarmkit/v2/node/node.go
generated
vendored
|
@ -276,7 +276,7 @@ func configVXLANUDPPort(ctx context.Context, vxlanUDPPort uint32) {
|
|||
log.G(ctx).WithError(err).Error("failed to configure VXLAN UDP port")
|
||||
return
|
||||
}
|
||||
logrus.Infof("initialized VXLAN UDP port to %d ", vxlanUDPPort)
|
||||
log.G(ctx).Infof("initialized VXLAN UDP port to %d ", vxlanUDPPort)
|
||||
}
|
||||
|
||||
func (n *Node) run(ctx context.Context) (err error) {
|
||||
|
@ -444,7 +444,7 @@ func (n *Node) run(ctx context.Context) (err error) {
|
|||
go func() {
|
||||
for certUpdate := range updates {
|
||||
if certUpdate.Err != nil {
|
||||
logrus.Warnf("error renewing TLS certificate: %v", certUpdate.Err)
|
||||
log.G(ctx).Warnf("error renewing TLS certificate: %v", certUpdate.Err)
|
||||
continue
|
||||
}
|
||||
// Set the new role, and notify our waiting role changing logic
|
||||
|
@ -862,7 +862,7 @@ func (n *Node) loadSecurityConfig(ctx context.Context, paths *ca.SecurityConfigP
|
|||
// Attempt to load certificate from disk
|
||||
securityConfig, cancel, err = ca.LoadSecurityConfig(ctx, rootCA, krw, n.config.ForceNewCluster)
|
||||
if err == nil {
|
||||
log.G(ctx).WithFields(logrus.Fields{
|
||||
log.G(ctx).WithFields(log.Fields{
|
||||
"node.id": securityConfig.ClientTLSCreds.NodeID(),
|
||||
}).Debugf("loaded TLS certificate")
|
||||
} else {
|
||||
|
|
4
vendor/github.com/moby/swarmkit/v2/watch/queue/queue.go
generated
vendored
4
vendor/github.com/moby/swarmkit/v2/watch/queue/queue.go
generated
vendored
|
@ -6,7 +6,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/docker/go-events"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/moby/swarmkit/v2/log"
|
||||
)
|
||||
|
||||
// ErrQueueFull is returned by a Write operation when that Write causes the
|
||||
|
@ -112,7 +112,7 @@ func (eq *LimitQueue) run() {
|
|||
// Eventually, go-events should not use logrus at all,
|
||||
// and should bubble up conditions like this through
|
||||
// error values.
|
||||
logrus.WithFields(logrus.Fields{
|
||||
log.L.WithFields(log.Fields{
|
||||
"event": event,
|
||||
"sink": eq.dst,
|
||||
}).WithError(err).Debug("eventqueue: dropped event")
|
||||
|
|
21
vendor/github.com/weppos/publicsuffix-go/LICENSE.txt
generated
vendored
Normal file
21
vendor/github.com/weppos/publicsuffix-go/LICENSE.txt
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Simone Carletti
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
544
vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go
generated
vendored
Normal file
544
vendor/github.com/weppos/publicsuffix-go/publicsuffix/publicsuffix.go
generated
vendored
Normal file
|
@ -0,0 +1,544 @@
|
|||
//go:generate go run ../cmd/gen/gen.go
|
||||
|
||||
// Package publicsuffix provides a domain name parser
|
||||
// based on data from the public suffix list http://publicsuffix.org/.
|
||||
// A public suffix is one under which Internet users can directly register names.
|
||||
package publicsuffix
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http/cookiejar"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
const (
|
||||
// Version identifies the current library version.
|
||||
// This is a pro forma convention given that Go dependencies
|
||||
// tends to be fetched directly from the repo.
|
||||
Version = "0.15.0"
|
||||
|
||||
// NormalType represents a normal rule such as "com"
|
||||
NormalType = 1
|
||||
// WildcardType represents a wildcard rule such as "*.com"
|
||||
WildcardType = 2
|
||||
// ExceptionType represents an exception to a wildard rule
|
||||
ExceptionType = 3
|
||||
|
||||
listTokenPrivateDomains = "===BEGIN PRIVATE DOMAINS==="
|
||||
listTokenComment = "//"
|
||||
)
|
||||
|
||||
// DefaultList is the default List and it is used by Parse and Domain.
|
||||
var DefaultList = NewList()
|
||||
|
||||
// DefaultRule is the default Rule that represents "*".
|
||||
var DefaultRule = MustNewRule("*")
|
||||
|
||||
// DefaultParserOptions are the default options used to parse a Public Suffix list.
|
||||
var DefaultParserOptions = &ParserOption{PrivateDomains: true, ASCIIEncoded: false}
|
||||
|
||||
// DefaultFindOptions are the default options used to perform the lookup of rules in the list.
|
||||
var DefaultFindOptions = &FindOptions{IgnorePrivate: false, DefaultRule: DefaultRule}
|
||||
|
||||
// Rule represents a single rule in a Public Suffix List.
|
||||
type Rule struct {
|
||||
Type int
|
||||
Value string
|
||||
Length int
|
||||
Private bool
|
||||
}
|
||||
|
||||
// ParserOption are the options you can use to customize the way a List
|
||||
// is parsed from a file or a string.
|
||||
type ParserOption struct {
|
||||
// Set to false to skip the private domains when parsing.
|
||||
// Default to true, which means the private domains are included.
|
||||
PrivateDomains bool
|
||||
|
||||
// Set to false if the input is encoded in U-labels (Unicode)
|
||||
// as opposite to A-labels.
|
||||
// Default to false, which means the list is containing Unicode domains.
|
||||
// This is the default because the original PSL currently contains Unicode.
|
||||
ASCIIEncoded bool
|
||||
}
|
||||
|
||||
// FindOptions are the options you can use to customize the way a Rule
|
||||
// is searched within the list.
|
||||
type FindOptions struct {
|
||||
// Set to true to ignore the rules within the "Private" section of the Public Suffix List.
|
||||
IgnorePrivate bool
|
||||
|
||||
// The default rule to use when no rule matches the input.
|
||||
// The format Public Suffix algorithm states that the rule "*" should be used when no other rule matches,
|
||||
// but some consumers may have different needs.
|
||||
DefaultRule *Rule
|
||||
}
|
||||
|
||||
// List represents a Public Suffix List.
|
||||
type List struct {
|
||||
// rules is kept private because you should not access rules directly
|
||||
rules map[string]*Rule
|
||||
}
|
||||
|
||||
// NewList creates a new empty list.
|
||||
func NewList() *List {
|
||||
return &List{
|
||||
rules: map[string]*Rule{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewListFromString parses a string that represents a Public Suffix source
|
||||
// and returns a List initialized with the rules in the source.
|
||||
func NewListFromString(src string, options *ParserOption) (*List, error) {
|
||||
l := NewList()
|
||||
_, err := l.LoadString(src, options)
|
||||
return l, err
|
||||
}
|
||||
|
||||
// NewListFromFile parses a string that represents a Public Suffix source
|
||||
// and returns a List initialized with the rules in the source.
|
||||
func NewListFromFile(path string, options *ParserOption) (*List, error) {
|
||||
l := NewList()
|
||||
_, err := l.LoadFile(path, options)
|
||||
return l, err
|
||||
}
|
||||
|
||||
// Load parses and loads a set of rules from an io.Reader into the current list.
|
||||
func (l *List) Load(r io.Reader, options *ParserOption) ([]Rule, error) {
|
||||
return l.parse(r, options)
|
||||
}
|
||||
|
||||
// LoadString parses and loads a set of rules from a String into the current list.
|
||||
func (l *List) LoadString(src string, options *ParserOption) ([]Rule, error) {
|
||||
r := strings.NewReader(src)
|
||||
return l.parse(r, options)
|
||||
}
|
||||
|
||||
// LoadFile parses and loads a set of rules from a File into the current list.
|
||||
func (l *List) LoadFile(path string, options *ParserOption) ([]Rule, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return l.parse(f, options)
|
||||
}
|
||||
|
||||
// AddRule adds a new rule to the list.
|
||||
//
|
||||
// The exact position of the rule into the list is unpredictable.
|
||||
// The list may be optimized internally for lookups, therefore the algorithm
|
||||
// will decide the best position for the new rule.
|
||||
func (l *List) AddRule(r *Rule) error {
|
||||
l.rules[r.Value] = r
|
||||
return nil
|
||||
}
|
||||
|
||||
// Size returns the size of the list, which is the number of rules.
|
||||
func (l *List) Size() int {
|
||||
return len(l.rules)
|
||||
}
|
||||
|
||||
func (l *List) parse(r io.Reader, options *ParserOption) ([]Rule, error) {
|
||||
if options == nil {
|
||||
options = DefaultParserOptions
|
||||
}
|
||||
var rules []Rule
|
||||
|
||||
scanner := bufio.NewScanner(r)
|
||||
var section int // 1 == ICANN, 2 == PRIVATE
|
||||
|
||||
Scanning:
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
switch {
|
||||
|
||||
// skip blank lines
|
||||
case line == "":
|
||||
break
|
||||
|
||||
// include private domains or stop scanner
|
||||
case strings.Contains(line, listTokenPrivateDomains):
|
||||
if !options.PrivateDomains {
|
||||
break Scanning
|
||||
}
|
||||
section = 2
|
||||
|
||||
// skip comments
|
||||
case strings.HasPrefix(line, listTokenComment):
|
||||
break
|
||||
|
||||
default:
|
||||
var rule *Rule
|
||||
var err error
|
||||
|
||||
if options.ASCIIEncoded {
|
||||
rule, err = NewRule(line)
|
||||
} else {
|
||||
rule, err = NewRuleUnicode(line)
|
||||
}
|
||||
if err != nil {
|
||||
return []Rule{}, err
|
||||
}
|
||||
|
||||
rule.Private = (section == 2)
|
||||
l.AddRule(rule)
|
||||
rules = append(rules, *rule)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rules, scanner.Err()
|
||||
}
|
||||
|
||||
// Find and returns the most appropriate rule for the domain name.
|
||||
func (l *List) Find(name string, options *FindOptions) *Rule {
|
||||
if options == nil {
|
||||
options = DefaultFindOptions
|
||||
}
|
||||
|
||||
part := name
|
||||
for {
|
||||
rule, ok := l.rules[part]
|
||||
|
||||
if ok && rule.Match(name) && !(options.IgnorePrivate && rule.Private) {
|
||||
return rule
|
||||
}
|
||||
|
||||
i := strings.IndexRune(part, '.')
|
||||
if i < 0 {
|
||||
return options.DefaultRule
|
||||
}
|
||||
|
||||
part = part[i+1:]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// NewRule parses the rule content, creates and returns a Rule.
|
||||
//
|
||||
// The content of the rule MUST be encoded in ASCII (A-labels).
|
||||
func NewRule(content string) (*Rule, error) {
|
||||
var rule *Rule
|
||||
var value string
|
||||
|
||||
switch content[0] {
|
||||
case '*': // wildcard
|
||||
if content == "*" {
|
||||
value = ""
|
||||
} else {
|
||||
value = content[2:]
|
||||
}
|
||||
rule = &Rule{Type: WildcardType, Value: value, Length: len(Labels(value)) + 1}
|
||||
case '!': // exception
|
||||
value = content[1:]
|
||||
rule = &Rule{Type: ExceptionType, Value: value, Length: len(Labels(value))}
|
||||
default: // normal
|
||||
value = content
|
||||
rule = &Rule{Type: NormalType, Value: value, Length: len(Labels(value))}
|
||||
}
|
||||
|
||||
return rule, nil
|
||||
}
|
||||
|
||||
// NewRuleUnicode is like NewRule, but expects the content to be encoded in Unicode (U-labels).
|
||||
func NewRuleUnicode(content string) (*Rule, error) {
|
||||
var err error
|
||||
|
||||
content, err = ToASCII(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewRule(content)
|
||||
}
|
||||
|
||||
// MustNewRule is like NewRule, but panics if the content cannot be parsed.
|
||||
func MustNewRule(content string) *Rule {
|
||||
rule, err := NewRule(content)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return rule
|
||||
}
|
||||
|
||||
// Match checks if the rule matches the name.
|
||||
//
|
||||
// A domain name is said to match a rule if and only if all of the following conditions are met:
|
||||
// - When the domain and rule are split into corresponding labels,
|
||||
// that the domain contains as many or more labels than the rule.
|
||||
// - Beginning with the right-most labels of both the domain and the rule,
|
||||
// and continuing for all labels in the rule, one finds that for every pair,
|
||||
// either they are identical, or that the label from the rule is "*".
|
||||
//
|
||||
// See https://publicsuffix.org/list/
|
||||
func (r *Rule) Match(name string) bool {
|
||||
left := strings.TrimSuffix(name, r.Value)
|
||||
|
||||
// the name contains as many labels than the rule
|
||||
// this is a match, unless it's a wildcard
|
||||
// because the wildcard requires one more label
|
||||
if left == "" {
|
||||
return r.Type != WildcardType
|
||||
}
|
||||
|
||||
// if there is one more label, the rule match
|
||||
// because either the rule is shorter than the domain
|
||||
// or the rule is a wildcard and there is one more label
|
||||
return left[len(left)-1:] == "."
|
||||
}
|
||||
|
||||
// Decompose takes a name as input and decomposes it into a tuple of <TRD+SLD, TLD>,
|
||||
// according to the rule definition and type.
|
||||
func (r *Rule) Decompose(name string) (result [2]string) {
|
||||
if r == DefaultRule {
|
||||
i := strings.LastIndexByte(name, '.')
|
||||
if i < 0 {
|
||||
return
|
||||
}
|
||||
result[0], result[1] = name[:i], name[i+1:]
|
||||
return
|
||||
}
|
||||
switch r.Type {
|
||||
case NormalType:
|
||||
name = strings.TrimSuffix(name, r.Value)
|
||||
if len(name) == 0 {
|
||||
return
|
||||
}
|
||||
result[0], result[1] = name[:len(name)-1], r.Value
|
||||
case WildcardType:
|
||||
name := strings.TrimSuffix(name, r.Value)
|
||||
if len(name) == 0 {
|
||||
return
|
||||
}
|
||||
name = name[:len(name)-1]
|
||||
i := strings.LastIndexByte(name, '.')
|
||||
if i < 0 {
|
||||
return
|
||||
}
|
||||
result[0], result[1] = name[:i], name[i+1:]+"."+r.Value
|
||||
case ExceptionType:
|
||||
i := strings.IndexRune(r.Value, '.')
|
||||
if i < 0 {
|
||||
return
|
||||
}
|
||||
suffix := r.Value[i+1:]
|
||||
name = strings.TrimSuffix(name, suffix)
|
||||
if len(name) == 0 {
|
||||
return
|
||||
}
|
||||
result[0], result[1] = name[:len(name)-1], suffix
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Labels decomposes given domain name into labels,
|
||||
// corresponding to the dot-separated tokens.
|
||||
func Labels(name string) []string {
|
||||
return strings.Split(name, ".")
|
||||
}
|
||||
|
||||
// DomainName represents a domain name.
|
||||
type DomainName struct {
|
||||
TLD string
|
||||
SLD string
|
||||
TRD string
|
||||
Rule *Rule
|
||||
}
|
||||
|
||||
// String joins the components of the domain name into a single string.
|
||||
// Empty labels are skipped.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// DomainName{"com", "example"}.String()
|
||||
// // example.com
|
||||
// DomainName{"com", "example", "www"}.String()
|
||||
// // www.example.com
|
||||
//
|
||||
func (d *DomainName) String() string {
|
||||
switch {
|
||||
case d.TLD == "":
|
||||
return ""
|
||||
case d.SLD == "":
|
||||
return d.TLD
|
||||
case d.TRD == "":
|
||||
return d.SLD + "." + d.TLD
|
||||
default:
|
||||
return d.TRD + "." + d.SLD + "." + d.TLD
|
||||
}
|
||||
}
|
||||
|
||||
// Domain extract and return the domain name from the input
|
||||
// using the default (Public Suffix) List.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// publicsuffix.Domain("example.com")
|
||||
// // example.com
|
||||
// publicsuffix.Domain("www.example.com")
|
||||
// // example.com
|
||||
// publicsuffix.Domain("www.example.co.uk")
|
||||
// // example.co.uk
|
||||
//
|
||||
func Domain(name string) (string, error) {
|
||||
return DomainFromListWithOptions(DefaultList, name, DefaultFindOptions)
|
||||
}
|
||||
|
||||
// Parse decomposes the name into TLD, SLD, TRD
|
||||
// using the default (Public Suffix) List,
|
||||
// and returns the result as a DomainName
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// list := NewList()
|
||||
//
|
||||
// publicsuffix.Parse("example.com")
|
||||
// // &DomainName{"com", "example"}
|
||||
// publicsuffix.Parse("www.example.com")
|
||||
// // &DomainName{"com", "example", "www"}
|
||||
// publicsuffix.Parse("www.example.co.uk")
|
||||
// // &DomainName{"co.uk", "example"}
|
||||
//
|
||||
func Parse(name string) (*DomainName, error) {
|
||||
return ParseFromListWithOptions(DefaultList, name, DefaultFindOptions)
|
||||
}
|
||||
|
||||
// DomainFromListWithOptions extract and return the domain name from the input
|
||||
// using the (Public Suffix) list passed as argument.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// list := NewList()
|
||||
//
|
||||
// publicsuffix.DomainFromListWithOptions(list, "example.com")
|
||||
// // example.com
|
||||
// publicsuffix.DomainFromListWithOptions(list, "www.example.com")
|
||||
// // example.com
|
||||
// publicsuffix.DomainFromListWithOptions(list, "www.example.co.uk")
|
||||
// // example.co.uk
|
||||
//
|
||||
func DomainFromListWithOptions(l *List, name string, options *FindOptions) (string, error) {
|
||||
dn, err := ParseFromListWithOptions(l, name, options)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return dn.SLD + "." + dn.TLD, nil
|
||||
}
|
||||
|
||||
// ParseFromListWithOptions decomposes the name into TLD, SLD, TRD
|
||||
// using the (Public Suffix) list passed as argument,
|
||||
// and returns the result as a DomainName
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// list := NewList()
|
||||
//
|
||||
// publicsuffix.ParseFromListWithOptions(list, "example.com")
|
||||
// // &DomainName{"com", "example"}
|
||||
// publicsuffix.ParseFromListWithOptions(list, "www.example.com")
|
||||
// // &DomainName{"com", "example", "www"}
|
||||
// publicsuffix.ParseFromListWithOptions(list, "www.example.co.uk")
|
||||
// // &DomainName{"co.uk", "example"}
|
||||
//
|
||||
func ParseFromListWithOptions(l *List, name string, options *FindOptions) (*DomainName, error) {
|
||||
n, err := normalize(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
r := l.Find(n, options)
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("no rule matching name %s", name)
|
||||
}
|
||||
|
||||
parts := r.Decompose(n)
|
||||
left, tld := parts[0], parts[1]
|
||||
if tld == "" {
|
||||
return nil, fmt.Errorf("%s is a suffix", n)
|
||||
}
|
||||
|
||||
dn := &DomainName{
|
||||
Rule: r,
|
||||
TLD: tld,
|
||||
}
|
||||
if i := strings.LastIndexByte(left, '.'); i < 0 {
|
||||
dn.SLD = left
|
||||
} else {
|
||||
dn.TRD = left[:i]
|
||||
dn.SLD = left[i+1:]
|
||||
}
|
||||
return dn, nil
|
||||
}
|
||||
|
||||
func normalize(name string) (string, error) {
|
||||
ret := strings.ToLower(name)
|
||||
|
||||
if ret == "" {
|
||||
return "", fmt.Errorf("name is blank")
|
||||
}
|
||||
if ret[0] == '.' {
|
||||
return "", fmt.Errorf("name %s starts with a dot", ret)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// ToASCII is a wrapper for idna.ToASCII.
|
||||
//
|
||||
// This wrapper exists because idna.ToASCII backward-compatibility was broken twice in few months
|
||||
// and I can't call this package directly anymore. The wrapper performs some terrible-but-necessary
|
||||
// before-after replacements to make sure an already ASCII input always results in the same output
|
||||
// even if passed through ToASCII.
|
||||
//
|
||||
// See golang/net@67957fd0b1, golang/net@f2499483f9, golang/net@78ebe5c8b6,
|
||||
// and weppos/publicsuffix-go#66.
|
||||
func ToASCII(s string) (string, error) {
|
||||
// .example.com should be .example.com
|
||||
// ..example.com should be ..example.com
|
||||
if strings.HasPrefix(s, ".") {
|
||||
dotIndex := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == '.' {
|
||||
dotIndex = i
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
out, err := idna.ToASCII(s[dotIndex+1:])
|
||||
out = s[:dotIndex+1] + out
|
||||
return out, err
|
||||
}
|
||||
|
||||
return idna.ToASCII(s)
|
||||
}
|
||||
|
||||
// ToUnicode is a wrapper for idna.ToUnicode.
|
||||
//
|
||||
// See ToASCII for more details about why this wrapper exists.
|
||||
func ToUnicode(s string) (string, error) {
|
||||
return idna.ToUnicode(s)
|
||||
}
|
||||
|
||||
// CookieJarList implements the cookiejar.PublicSuffixList interface.
|
||||
var CookieJarList cookiejar.PublicSuffixList = cookiejarList{DefaultList}
|
||||
|
||||
type cookiejarList struct {
|
||||
List *List
|
||||
}
|
||||
|
||||
// PublicSuffix implements cookiejar.PublicSuffixList.
|
||||
func (l cookiejarList) PublicSuffix(domain string) string {
|
||||
rule := l.List.Find(domain, nil)
|
||||
return rule.Decompose(domain)[1]
|
||||
}
|
||||
|
||||
// PublicSuffix implements cookiejar.String.
|
||||
func (cookiejarList) String() string {
|
||||
return defaultListVersion
|
||||
}
|
9188
vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go
generated
vendored
Normal file
9188
vendor/github.com/weppos/publicsuffix-go/publicsuffix/rules.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
257
vendor/github.com/zmap/zcrypto/LICENSE
generated
vendored
Normal file
257
vendor/github.com/zmap/zcrypto/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
ZCrypto is an original work created at the University of Michigan, and is
|
||||
licensed under the Apache 2.0 license. However, ZCrypto contains a fork of
|
||||
several packages from Golang standard library, as well as code from the
|
||||
BoringSSL test runner. Files that were created by Google, and new files in
|
||||
forks of packages maintained by Google have a Google copyright and fall under
|
||||
the ISC license. In addition ZCrypto includes a `util/isURL.go` file created by
|
||||
Alex Saskevich and licensed under the MIT license. All other files are copyright
|
||||
Regents of the University of Michigan, and fall under the Apache 2.0 license.
|
||||
All three licenses are reproduced at the bottom of this file.
|
||||
|
||||
--------
|
||||
|
||||
ISC License used for Google code
|
||||
|
||||
/* Copyright (c) 2015, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
--------
|
||||
|
||||
MIT License used for util/isURL.go adopted from https://github.com/asaskevich/govalidator
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Alex Saskevich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
--------
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
ZCrypto Copyright 2015 Regents of the University of Michigan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
309
vendor/github.com/zmap/zcrypto/dsa/dsa.go
generated
vendored
Normal file
309
vendor/github.com/zmap/zcrypto/dsa/dsa.go
generated
vendored
Normal file
|
@ -0,0 +1,309 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3.
|
||||
//
|
||||
// The DSA operations in this package are not implemented using constant-time algorithms.
|
||||
//
|
||||
// Warning: DSA is a legacy algorithm, and modern alternatives such as
|
||||
// Ed25519 (implemented by package crypto/ed25519) should be used instead. Keys
|
||||
// with 1024-bit moduli (L1024N160 parameters) are cryptographically weak, while
|
||||
// bigger keys are not widely supported. Note that FIPS 186-5 no longer approves
|
||||
// DSA for signature generation.
|
||||
package dsa
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"github.com/zmap/zcrypto/internal/randutil"
|
||||
)
|
||||
|
||||
// Parameters represents the domain parameters for a key. These parameters can
|
||||
// be shared across many keys. The bit length of Q must be a multiple of 8.
|
||||
type Parameters struct {
|
||||
P, Q, G *big.Int
|
||||
}
|
||||
|
||||
// PublicKey represents a DSA public key.
|
||||
type PublicKey struct {
|
||||
Parameters
|
||||
Y *big.Int
|
||||
}
|
||||
|
||||
// PrivateKey represents a DSA private key.
|
||||
type PrivateKey struct {
|
||||
PublicKey
|
||||
X *big.Int
|
||||
}
|
||||
|
||||
// ErrInvalidPublicKey results when a public key is not usable by this code.
|
||||
// FIPS is quite strict about the format of DSA keys, but other code may be
|
||||
// less so. Thus, when using keys which may have been generated by other code,
|
||||
// this error must be handled.
|
||||
var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
|
||||
|
||||
// ParameterSizes is an enumeration of the acceptable bit lengths of the primes
|
||||
// in a set of DSA parameters. See FIPS 186-3, section 4.2.
|
||||
type ParameterSizes int
|
||||
|
||||
const (
|
||||
L1024N160 ParameterSizes = iota
|
||||
L2048N224
|
||||
L2048N256
|
||||
L3072N256
|
||||
)
|
||||
|
||||
// numMRTests is the number of Miller-Rabin primality tests that we perform. We
|
||||
// pick the largest recommended number from table C.1 of FIPS 186-3.
|
||||
const numMRTests = 64
|
||||
|
||||
// GenerateParameters puts a random, valid set of DSA parameters into params.
|
||||
// This function can take many seconds, even on fast machines.
|
||||
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) error {
|
||||
// This function doesn't follow FIPS 186-3 exactly in that it doesn't
|
||||
// use a verification seed to generate the primes. The verification
|
||||
// seed doesn't appear to be exported or used by other code and
|
||||
// omitting it makes the code cleaner.
|
||||
|
||||
var L, N int
|
||||
switch sizes {
|
||||
case L1024N160:
|
||||
L = 1024
|
||||
N = 160
|
||||
case L2048N224:
|
||||
L = 2048
|
||||
N = 224
|
||||
case L2048N256:
|
||||
L = 2048
|
||||
N = 256
|
||||
case L3072N256:
|
||||
L = 3072
|
||||
N = 256
|
||||
default:
|
||||
return errors.New("crypto/dsa: invalid ParameterSizes")
|
||||
}
|
||||
|
||||
qBytes := make([]byte, N/8)
|
||||
pBytes := make([]byte, L/8)
|
||||
|
||||
q := new(big.Int)
|
||||
p := new(big.Int)
|
||||
rem := new(big.Int)
|
||||
one := new(big.Int)
|
||||
one.SetInt64(1)
|
||||
|
||||
GeneratePrimes:
|
||||
for {
|
||||
if _, err := io.ReadFull(rand, qBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
qBytes[len(qBytes)-1] |= 1
|
||||
qBytes[0] |= 0x80
|
||||
q.SetBytes(qBytes)
|
||||
|
||||
if !q.ProbablyPrime(numMRTests) {
|
||||
continue
|
||||
}
|
||||
|
||||
for i := 0; i < 4*L; i++ {
|
||||
if _, err := io.ReadFull(rand, pBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pBytes[len(pBytes)-1] |= 1
|
||||
pBytes[0] |= 0x80
|
||||
|
||||
p.SetBytes(pBytes)
|
||||
rem.Mod(p, q)
|
||||
rem.Sub(rem, one)
|
||||
p.Sub(p, rem)
|
||||
if p.BitLen() < L {
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.ProbablyPrime(numMRTests) {
|
||||
continue
|
||||
}
|
||||
|
||||
params.P = p
|
||||
params.Q = q
|
||||
break GeneratePrimes
|
||||
}
|
||||
}
|
||||
|
||||
h := new(big.Int)
|
||||
h.SetInt64(2)
|
||||
g := new(big.Int)
|
||||
|
||||
pm1 := new(big.Int).Sub(p, one)
|
||||
e := new(big.Int).Div(pm1, q)
|
||||
|
||||
for {
|
||||
g.Exp(h, e, p)
|
||||
if g.Cmp(one) == 0 {
|
||||
h.Add(h, one)
|
||||
continue
|
||||
}
|
||||
|
||||
params.G = g
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateKey generates a public&private key pair. The Parameters of the
|
||||
// PrivateKey must already be valid (see GenerateParameters).
|
||||
func GenerateKey(priv *PrivateKey, rand io.Reader) error {
|
||||
if priv.P == nil || priv.Q == nil || priv.G == nil {
|
||||
return errors.New("crypto/dsa: parameters not set up before generating key")
|
||||
}
|
||||
|
||||
x := new(big.Int)
|
||||
xBytes := make([]byte, priv.Q.BitLen()/8)
|
||||
|
||||
for {
|
||||
_, err := io.ReadFull(rand, xBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
x.SetBytes(xBytes)
|
||||
if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
priv.X = x
|
||||
priv.Y = new(big.Int)
|
||||
priv.Y.Exp(priv.G, x, priv.P)
|
||||
return nil
|
||||
}
|
||||
|
||||
// fermatInverse calculates the inverse of k in GF(P) using Fermat's method.
|
||||
// This has better constant-time properties than Euclid's method (implemented
|
||||
// in math/big.Int.ModInverse) although math/big itself isn't strictly
|
||||
// constant-time so it's not perfect.
|
||||
func fermatInverse(k, P *big.Int) *big.Int {
|
||||
two := big.NewInt(2)
|
||||
pMinus2 := new(big.Int).Sub(P, two)
|
||||
return new(big.Int).Exp(k, pMinus2, P)
|
||||
}
|
||||
|
||||
// Sign signs an arbitrary length hash (which should be the result of hashing a
|
||||
// larger message) using the private key, priv. It returns the signature as a
|
||||
// pair of integers. The security of the private key depends on the entropy of
|
||||
// rand.
|
||||
//
|
||||
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
|
||||
// to the byte-length of the subgroup. This function does not perform that
|
||||
// truncation itself.
|
||||
//
|
||||
// Be aware that calling Sign with an attacker-controlled PrivateKey may
|
||||
// require an arbitrary amount of CPU.
|
||||
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
|
||||
randutil.MaybeReadByte(rand)
|
||||
|
||||
// FIPS 186-3, section 4.6
|
||||
|
||||
n := priv.Q.BitLen()
|
||||
if priv.Q.Sign() <= 0 || priv.P.Sign() <= 0 || priv.G.Sign() <= 0 || priv.X.Sign() <= 0 || n%8 != 0 {
|
||||
err = ErrInvalidPublicKey
|
||||
return
|
||||
}
|
||||
n >>= 3
|
||||
|
||||
var attempts int
|
||||
for attempts = 10; attempts > 0; attempts-- {
|
||||
k := new(big.Int)
|
||||
buf := make([]byte, n)
|
||||
for {
|
||||
_, err = io.ReadFull(rand, buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
k.SetBytes(buf)
|
||||
// priv.Q must be >= 128 because the test above
|
||||
// requires it to be > 0 and that
|
||||
// ceil(log_2(Q)) mod 8 = 0
|
||||
// Thus this loop will quickly terminate.
|
||||
if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
kInv := fermatInverse(k, priv.Q)
|
||||
|
||||
r = new(big.Int).Exp(priv.G, k, priv.P)
|
||||
r.Mod(r, priv.Q)
|
||||
|
||||
if r.Sign() == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
z := k.SetBytes(hash)
|
||||
|
||||
s = new(big.Int).Mul(priv.X, r)
|
||||
s.Add(s, z)
|
||||
s.Mod(s, priv.Q)
|
||||
s.Mul(s, kInv)
|
||||
s.Mod(s, priv.Q)
|
||||
|
||||
if s.Sign() != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Only degenerate private keys will require more than a handful of
|
||||
// attempts.
|
||||
if attempts == 0 {
|
||||
return nil, nil, ErrInvalidPublicKey
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Verify verifies the signature in r, s of hash using the public key, pub. It
|
||||
// reports whether the signature is valid.
|
||||
//
|
||||
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
|
||||
// to the byte-length of the subgroup. This function does not perform that
|
||||
// truncation itself.
|
||||
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
|
||||
// FIPS 186-3, section 4.7
|
||||
|
||||
if pub.P.Sign() == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
|
||||
return false
|
||||
}
|
||||
if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
w := new(big.Int).ModInverse(s, pub.Q)
|
||||
if w == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
n := pub.Q.BitLen()
|
||||
if n%8 != 0 {
|
||||
return false
|
||||
}
|
||||
z := new(big.Int).SetBytes(hash)
|
||||
|
||||
u1 := new(big.Int).Mul(z, w)
|
||||
u1.Mod(u1, pub.Q)
|
||||
u2 := w.Mul(r, w)
|
||||
u2.Mod(u2, pub.Q)
|
||||
v := u1.Exp(pub.G, u1, pub.P)
|
||||
u2.Exp(pub.Y, u2, pub.P)
|
||||
v.Mul(v, u2)
|
||||
v.Mod(v, pub.P)
|
||||
v.Mod(v, pub.Q)
|
||||
|
||||
return v.Cmp(r) == 0
|
||||
}
|
38
vendor/github.com/zmap/zcrypto/internal/randutil/randutil.go
generated
vendored
Normal file
38
vendor/github.com/zmap/zcrypto/internal/randutil/randutil.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package randutil contains internal randomness utilities for various
|
||||
// crypto packages.
|
||||
package randutil
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
closedChanOnce sync.Once
|
||||
closedChan chan struct{}
|
||||
)
|
||||
|
||||
// MaybeReadByte reads a single byte from r with ~50% probability. This is used
|
||||
// to ensure that callers do not depend on non-guaranteed behaviour, e.g.
|
||||
// assuming that rsa.GenerateKey is deterministic w.r.t. a given random stream.
|
||||
//
|
||||
// This does not affect tests that pass a stream of fixed bytes as the random
|
||||
// source (e.g. a zeroReader).
|
||||
func MaybeReadByte(r io.Reader) {
|
||||
closedChanOnce.Do(func() {
|
||||
closedChan = make(chan struct{})
|
||||
close(closedChan)
|
||||
})
|
||||
|
||||
select {
|
||||
case <-closedChan:
|
||||
return
|
||||
case <-closedChan:
|
||||
var buf [1]byte
|
||||
r.Read(buf[:])
|
||||
}
|
||||
}
|
130
vendor/github.com/zmap/zcrypto/json/dhe.go
generated
vendored
Normal file
130
vendor/github.com/zmap/zcrypto/json/dhe.go
generated
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* ZGrab Copyright 2015 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// DHParams can be used to store finite-field Diffie-Hellman parameters. At any
|
||||
// point in time, it is unlikely that both OurPrivate and TheirPrivate will be
|
||||
// non-nil.
|
||||
type DHParams struct {
|
||||
Prime *big.Int
|
||||
Generator *big.Int
|
||||
ServerPublic *big.Int
|
||||
ServerPrivate *big.Int
|
||||
ClientPublic *big.Int
|
||||
ClientPrivate *big.Int
|
||||
SessionKey *big.Int
|
||||
}
|
||||
|
||||
type auxDHParams struct {
|
||||
Prime *cryptoParameter `json:"prime"`
|
||||
Generator *cryptoParameter `json:"generator"`
|
||||
ServerPublic *cryptoParameter `json:"server_public,omitempty"`
|
||||
ServerPrivate *cryptoParameter `json:"server_private,omitempty"`
|
||||
ClientPublic *cryptoParameter `json:"client_public,omitempty"`
|
||||
ClientPrivate *cryptoParameter `json:"client_private,omitempty"`
|
||||
SessionKey *cryptoParameter `json:"session_key,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshal interface
|
||||
func (p *DHParams) MarshalJSON() ([]byte, error) {
|
||||
aux := auxDHParams{
|
||||
Prime: &cryptoParameter{Int: p.Prime},
|
||||
Generator: &cryptoParameter{Int: p.Generator},
|
||||
}
|
||||
if p.ServerPublic != nil {
|
||||
aux.ServerPublic = &cryptoParameter{Int: p.ServerPublic}
|
||||
}
|
||||
if p.ServerPrivate != nil {
|
||||
aux.ServerPrivate = &cryptoParameter{Int: p.ServerPrivate}
|
||||
}
|
||||
if p.ClientPublic != nil {
|
||||
aux.ClientPublic = &cryptoParameter{Int: p.ClientPublic}
|
||||
}
|
||||
if p.ClientPrivate != nil {
|
||||
aux.ClientPrivate = &cryptoParameter{Int: p.ClientPrivate}
|
||||
}
|
||||
if p.SessionKey != nil {
|
||||
aux.SessionKey = &cryptoParameter{Int: p.SessionKey}
|
||||
}
|
||||
return json.Marshal(aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implement the json.Unmarshaler interface
|
||||
func (p *DHParams) UnmarshalJSON(b []byte) error {
|
||||
var aux auxDHParams
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
if aux.Prime != nil {
|
||||
p.Prime = aux.Prime.Int
|
||||
}
|
||||
if aux.Generator != nil {
|
||||
p.Generator = aux.Generator.Int
|
||||
}
|
||||
if aux.ServerPublic != nil {
|
||||
p.ServerPublic = aux.ServerPublic.Int
|
||||
}
|
||||
if aux.ServerPrivate != nil {
|
||||
p.ServerPrivate = aux.ServerPrivate.Int
|
||||
}
|
||||
if aux.ClientPublic != nil {
|
||||
p.ClientPublic = aux.ClientPublic.Int
|
||||
}
|
||||
if aux.ClientPrivate != nil {
|
||||
p.ClientPrivate = aux.ClientPrivate.Int
|
||||
}
|
||||
if aux.SessionKey != nil {
|
||||
p.SessionKey = aux.SessionKey.Int
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CryptoParameter represents a big.Int used a parameter in some cryptography.
|
||||
// It serializes to json as a tupe of a base64-encoded number and a length in
|
||||
// bits.
|
||||
type cryptoParameter struct {
|
||||
*big.Int
|
||||
}
|
||||
|
||||
type auxCryptoParameter struct {
|
||||
Raw []byte `json:"value"`
|
||||
Length int `json:"length"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (p *cryptoParameter) MarshalJSON() ([]byte, error) {
|
||||
var aux auxCryptoParameter
|
||||
if p.Int != nil {
|
||||
aux.Raw = p.Bytes()
|
||||
aux.Length = 8 * len(aux.Raw)
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface
|
||||
func (p *cryptoParameter) UnmarshalJSON(b []byte) error {
|
||||
var aux auxCryptoParameter
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
p.Int = new(big.Int)
|
||||
p.SetBytes(aux.Raw)
|
||||
return nil
|
||||
}
|
107
vendor/github.com/zmap/zcrypto/json/ecdhe.go
generated
vendored
Normal file
107
vendor/github.com/zmap/zcrypto/json/ecdhe.go
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* ZGrab Copyright 2015 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// TLSCurveID is the type of a TLS identifier for an elliptic curve. See
|
||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
|
||||
type TLSCurveID uint16
|
||||
|
||||
// ECDHPrivateParams are the TLS key exchange parameters for ECDH keys.
|
||||
type ECDHPrivateParams struct {
|
||||
Value []byte `json:"value,omitempty"`
|
||||
Length int `json:"length,omitempty"`
|
||||
}
|
||||
|
||||
// ECDHParams stores elliptic-curve Diffie-Hellman paramters.At any point in
|
||||
// time, it is unlikely that both ServerPrivate and ClientPrivate will be non-nil.
|
||||
type ECDHParams struct {
|
||||
TLSCurveID TLSCurveID `json:"curve_id,omitempty"`
|
||||
Curve elliptic.Curve `json:"-"`
|
||||
ServerPublic *ECPoint `json:"server_public,omitempty"`
|
||||
ServerPrivate *ECDHPrivateParams `json:"server_private,omitempty"`
|
||||
ClientPublic *ECPoint `json:"client_public,omitempty"`
|
||||
ClientPrivate *ECDHPrivateParams `json:"client_private,omitempty"`
|
||||
}
|
||||
|
||||
// ECPoint represents an elliptic curve point and serializes nicely to JSON
|
||||
type ECPoint struct {
|
||||
X *big.Int
|
||||
Y *big.Int
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshler interface
|
||||
func (p *ECPoint) MarshalJSON() ([]byte, error) {
|
||||
aux := struct {
|
||||
X *cryptoParameter `json:"x"`
|
||||
Y *cryptoParameter `json:"y"`
|
||||
}{
|
||||
X: &cryptoParameter{Int: p.X},
|
||||
Y: &cryptoParameter{Int: p.Y},
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshler interface
|
||||
func (p *ECPoint) UnmarshalJSON(b []byte) error {
|
||||
aux := struct {
|
||||
X *cryptoParameter `json:"x"`
|
||||
Y *cryptoParameter `json:"y"`
|
||||
}{}
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
p.X = aux.X.Int
|
||||
p.Y = aux.Y.Int
|
||||
return nil
|
||||
}
|
||||
|
||||
// Description returns the description field for the given ID. See
|
||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
|
||||
func (c *TLSCurveID) Description() string {
|
||||
if desc, ok := ecIDToName[*c]; ok {
|
||||
return desc
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (c *TLSCurveID) MarshalJSON() ([]byte, error) {
|
||||
aux := struct {
|
||||
Name string `json:"name"`
|
||||
ID uint16 `json:"id"`
|
||||
}{
|
||||
Name: c.Description(),
|
||||
ID: uint16(*c),
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
//UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (c *TLSCurveID) UnmarshalJSON(b []byte) error {
|
||||
aux := struct {
|
||||
ID uint16 `json:"id"`
|
||||
}{}
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
*c = TLSCurveID(aux.ID)
|
||||
return nil
|
||||
}
|
113
vendor/github.com/zmap/zcrypto/json/names.go
generated
vendored
Normal file
113
vendor/github.com/zmap/zcrypto/json/names.go
generated
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* ZGrab Copyright 2015 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package json
|
||||
|
||||
// IANA-assigned curve ID values, see
|
||||
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
|
||||
const (
|
||||
Sect163k1 TLSCurveID = 1
|
||||
Sect163r1 TLSCurveID = 2
|
||||
Sect163r2 TLSCurveID = 3
|
||||
Sect193r1 TLSCurveID = 4
|
||||
Sect193r2 TLSCurveID = 5
|
||||
Sect233k1 TLSCurveID = 6
|
||||
Sect233r1 TLSCurveID = 7
|
||||
Sect239k1 TLSCurveID = 8
|
||||
Sect283k1 TLSCurveID = 9
|
||||
Sect283r1 TLSCurveID = 10
|
||||
Sect409k1 TLSCurveID = 11
|
||||
Sect409r1 TLSCurveID = 12
|
||||
Sect571k1 TLSCurveID = 13
|
||||
Sect571r1 TLSCurveID = 14
|
||||
Secp160k1 TLSCurveID = 15
|
||||
Secp160r1 TLSCurveID = 16
|
||||
Secp160r2 TLSCurveID = 17
|
||||
Secp192k1 TLSCurveID = 18
|
||||
Secp192r1 TLSCurveID = 19
|
||||
Secp224k1 TLSCurveID = 20
|
||||
Secp224r1 TLSCurveID = 21
|
||||
Secp256k1 TLSCurveID = 22
|
||||
Secp256r1 TLSCurveID = 23
|
||||
Secp384r1 TLSCurveID = 24
|
||||
Secp521r1 TLSCurveID = 25
|
||||
BrainpoolP256r1 TLSCurveID = 26
|
||||
BrainpoolP384r1 TLSCurveID = 27
|
||||
BrainpoolP512r1 TLSCurveID = 28
|
||||
)
|
||||
|
||||
var ecIDToName map[TLSCurveID]string
|
||||
var ecNameToID map[string]TLSCurveID
|
||||
|
||||
func init() {
|
||||
ecIDToName = make(map[TLSCurveID]string, 64)
|
||||
ecIDToName[Sect163k1] = "sect163k1"
|
||||
ecIDToName[Sect163r1] = "sect163r1"
|
||||
ecIDToName[Sect163r2] = "sect163r2"
|
||||
ecIDToName[Sect193r1] = "sect193r1"
|
||||
ecIDToName[Sect193r2] = "sect193r2"
|
||||
ecIDToName[Sect233k1] = "sect233k1"
|
||||
ecIDToName[Sect233r1] = "sect233r1"
|
||||
ecIDToName[Sect239k1] = "sect239k1"
|
||||
ecIDToName[Sect283k1] = "sect283k1"
|
||||
ecIDToName[Sect283r1] = "sect283r1"
|
||||
ecIDToName[Sect409k1] = "sect409k1"
|
||||
ecIDToName[Sect409r1] = "sect409r1"
|
||||
ecIDToName[Sect571k1] = "sect571k1"
|
||||
ecIDToName[Sect571r1] = "sect571r1"
|
||||
ecIDToName[Secp160k1] = "secp160k1"
|
||||
ecIDToName[Secp160r1] = "secp160r1"
|
||||
ecIDToName[Secp160r2] = "secp160r2"
|
||||
ecIDToName[Secp192k1] = "secp192k1"
|
||||
ecIDToName[Secp192r1] = "secp192r1"
|
||||
ecIDToName[Secp224k1] = "secp224k1"
|
||||
ecIDToName[Secp224r1] = "secp224r1"
|
||||
ecIDToName[Secp256k1] = "secp256k1"
|
||||
ecIDToName[Secp256r1] = "secp256r1"
|
||||
ecIDToName[Secp384r1] = "secp384r1"
|
||||
ecIDToName[Secp521r1] = "secp521r1"
|
||||
ecIDToName[BrainpoolP256r1] = "brainpoolp256r1"
|
||||
ecIDToName[BrainpoolP384r1] = "brainpoolp384r1"
|
||||
ecIDToName[BrainpoolP512r1] = "brainpoolp512r1"
|
||||
|
||||
ecNameToID = make(map[string]TLSCurveID, 64)
|
||||
ecNameToID["sect163k1"] = Sect163k1
|
||||
ecNameToID["sect163r1"] = Sect163r1
|
||||
ecNameToID["sect163r2"] = Sect163r2
|
||||
ecNameToID["sect193r1"] = Sect193r1
|
||||
ecNameToID["sect193r2"] = Sect193r2
|
||||
ecNameToID["sect233k1"] = Sect233k1
|
||||
ecNameToID["sect233r1"] = Sect233r1
|
||||
ecNameToID["sect239k1"] = Sect239k1
|
||||
ecNameToID["sect283k1"] = Sect283k1
|
||||
ecNameToID["sect283r1"] = Sect283r1
|
||||
ecNameToID["sect409k1"] = Sect409k1
|
||||
ecNameToID["sect409r1"] = Sect409r1
|
||||
ecNameToID["sect571k1"] = Sect571k1
|
||||
ecNameToID["sect571r1"] = Sect571r1
|
||||
ecNameToID["secp160k1"] = Secp160k1
|
||||
ecNameToID["secp160r1"] = Secp160r1
|
||||
ecNameToID["secp160r2"] = Secp160r2
|
||||
ecNameToID["secp192k1"] = Secp192k1
|
||||
ecNameToID["secp192r1"] = Secp192r1
|
||||
ecNameToID["secp224k1"] = Secp224k1
|
||||
ecNameToID["secp224r1"] = Secp224r1
|
||||
ecNameToID["secp256k1"] = Secp256k1
|
||||
ecNameToID["secp256r1"] = Secp256r1
|
||||
ecNameToID["secp384r1"] = Secp384r1
|
||||
ecNameToID["secp521r1"] = Secp521r1
|
||||
ecNameToID["brainpoolp256r1"] = BrainpoolP256r1
|
||||
ecNameToID["brainpoolp384r1"] = BrainpoolP384r1
|
||||
ecNameToID["brainpoolp512r1"] = BrainpoolP512r1
|
||||
}
|
67
vendor/github.com/zmap/zcrypto/json/rsa.go
generated
vendored
Normal file
67
vendor/github.com/zmap/zcrypto/json/rsa.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* ZGrab Copyright 2015 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package json
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// RSAPublicKey provides JSON methods for the standard rsa.PublicKey.
|
||||
type RSAPublicKey struct {
|
||||
*rsa.PublicKey
|
||||
}
|
||||
|
||||
type auxRSAPublicKey struct {
|
||||
Exponent int `json:"exponent"`
|
||||
Modulus []byte `json:"modulus"`
|
||||
Length int `json:"length"`
|
||||
}
|
||||
|
||||
// RSAClientParams are the TLS key exchange parameters for RSA keys.
|
||||
type RSAClientParams struct {
|
||||
Length uint16 `json:"length,omitempty"`
|
||||
EncryptedPMS []byte `json:"encrypted_pre_master_secret,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshal interface
|
||||
func (rp *RSAPublicKey) MarshalJSON() ([]byte, error) {
|
||||
var aux auxRSAPublicKey
|
||||
if rp.PublicKey != nil {
|
||||
aux.Exponent = rp.E
|
||||
aux.Modulus = rp.N.Bytes()
|
||||
aux.Length = len(aux.Modulus) * 8
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshal interface
|
||||
func (rp *RSAPublicKey) UnmarshalJSON(b []byte) error {
|
||||
var aux auxRSAPublicKey
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
if rp.PublicKey == nil {
|
||||
rp.PublicKey = new(rsa.PublicKey)
|
||||
}
|
||||
rp.E = aux.Exponent
|
||||
rp.N = big.NewInt(0).SetBytes(aux.Modulus)
|
||||
if len(aux.Modulus)*8 != aux.Length {
|
||||
return fmt.Errorf("mismatched length (got %d, field specified %d)", len(aux.Modulus), aux.Length)
|
||||
}
|
||||
return nil
|
||||
}
|
77
vendor/github.com/zmap/zcrypto/util/isURL.go
generated
vendored
Normal file
77
vendor/github.com/zmap/zcrypto/util/isURL.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Alex Saskevich
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
maxURLRuneCount = 2083
|
||||
minURLRuneCount = 3
|
||||
|
||||
IP = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
|
||||
URLSchema = `((ftp|tcp|udp|wss?|https?):\/\/)`
|
||||
URLUsername = `(\S+(:\S*)?@)`
|
||||
URLPath = `((\/|\?|#)[^\s]*)`
|
||||
URLPort = `(:(\d{1,5}))`
|
||||
URLIP = `([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))`
|
||||
URLSubdomain = `((www\.)|([a-zA-Z0-9]+([-_\.]?[a-zA-Z0-9])*[a-zA-Z0-9]\.[a-zA-Z0-9]+))`
|
||||
)
|
||||
|
||||
var (
|
||||
URL = `^` + URLSchema + `?` + URLUsername + `?` + `((` + URLIP + `|(\[` + IP + `\])|(([a-zA-Z0-9]([a-zA-Z0-9-_]+)?[a-zA-Z0-9]([-\.][a-zA-Z0-9]+)*)|(` + URLSubdomain + `?))?(([a-zA-Z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-zA-Z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-zA-Z\x{00a1}-\x{ffff}]{1,}))?))\.?` + URLPort + `?` + URLPath + `?$`
|
||||
rxURL = regexp.MustCompile(URL)
|
||||
)
|
||||
|
||||
// IsURL check if the string is an URL.
|
||||
// This function is (graciously) adopted from
|
||||
// https://github.com/asaskevich/govalidator to avoid needing a full dependency on
|
||||
// `govalidator` for the one `IsURL` function.
|
||||
func IsURL(str string) bool {
|
||||
if str == "" || utf8.RuneCountInString(str) >= maxURLRuneCount || len(str) <= minURLRuneCount || strings.HasPrefix(str, ".") {
|
||||
return false
|
||||
}
|
||||
strTemp := str
|
||||
if strings.Contains(str, ":") && !strings.Contains(str, "://") {
|
||||
// support no indicated urlscheme but with colon for port number
|
||||
// http:// is appended so url.Parse will succeed, strTemp used so it does not impact rxURL.MatchString
|
||||
strTemp = "http://" + str
|
||||
}
|
||||
u, err := url.Parse(strTemp)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(u.Host, ".") {
|
||||
return false
|
||||
}
|
||||
if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
|
||||
return false
|
||||
}
|
||||
return rxURL.MatchString(str)
|
||||
}
|
8
vendor/github.com/zmap/zcrypto/x509/README.md
generated
vendored
Normal file
8
vendor/github.com/zmap/zcrypto/x509/README.md
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
Originally based on the go/crypto/x509 standard library,
|
||||
this package has now diverged enough that it is no longer
|
||||
updated with direct correspondence to new go releases.
|
||||
|
||||
Approximately supports all the features of
|
||||
github.com/golang/go/crypto/x509 package at:
|
||||
branch: release-branch.go1.10
|
||||
revision: dea961ebd9f871b39b3bdaab32f952037f28cd71
|
171
vendor/github.com/zmap/zcrypto/x509/cert_pool.go
generated
vendored
Normal file
171
vendor/github.com/zmap/zcrypto/x509/cert_pool.go
generated
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
)
|
||||
|
||||
// CertPool is a set of certificates.
|
||||
type CertPool struct {
|
||||
bySubjectKeyId map[string][]int
|
||||
byName map[string][]int
|
||||
bySHA256 map[string]int
|
||||
certs []*Certificate
|
||||
}
|
||||
|
||||
// NewCertPool returns a new, empty CertPool.
|
||||
func NewCertPool() *CertPool {
|
||||
return &CertPool{
|
||||
bySubjectKeyId: make(map[string][]int),
|
||||
byName: make(map[string][]int),
|
||||
bySHA256: make(map[string]int),
|
||||
}
|
||||
}
|
||||
|
||||
// findVerifiedParents attempts to find certificates in s which have signed the
|
||||
// given certificate. If any candidates were rejected then errCert will be set
|
||||
// to one of them, arbitrarily, and err will contain the reason that it was
|
||||
// rejected.
|
||||
func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCert *Certificate, err error) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
var candidates []int
|
||||
|
||||
if len(cert.AuthorityKeyId) > 0 {
|
||||
candidates, _ = s.bySubjectKeyId[string(cert.AuthorityKeyId)]
|
||||
}
|
||||
if len(candidates) == 0 {
|
||||
candidates, _ = s.byName[string(cert.RawIssuer)]
|
||||
}
|
||||
|
||||
for _, c := range candidates {
|
||||
if err = cert.CheckSignatureFrom(s.certs[c]); err == nil {
|
||||
cert.validSignature = true
|
||||
parents = append(parents, c)
|
||||
} else {
|
||||
errCert = s.certs[c]
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Contains returns true if c is in s.
|
||||
func (s *CertPool) Contains(c *Certificate) bool {
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
_, ok := s.bySHA256[string(c.FingerprintSHA256)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Covers returns true if all certs in pool are in s.
|
||||
func (s *CertPool) Covers(pool *CertPool) bool {
|
||||
if pool == nil {
|
||||
return true
|
||||
}
|
||||
for _, c := range pool.certs {
|
||||
if !s.Contains(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Certificates returns a list of parsed certificates in the pool.
|
||||
func (s *CertPool) Certificates() []*Certificate {
|
||||
out := make([]*Certificate, 0, len(s.certs))
|
||||
out = append(out, s.certs...)
|
||||
return out
|
||||
}
|
||||
|
||||
// Size returns the number of unique certificates in the CertPool.
|
||||
func (s *CertPool) Size() int {
|
||||
if s == nil {
|
||||
return 0
|
||||
}
|
||||
return len(s.certs)
|
||||
}
|
||||
|
||||
// Sum returns the union of two certificate pools as a new certificate pool.
|
||||
func (s *CertPool) Sum(other *CertPool) (sum *CertPool) {
|
||||
sum = NewCertPool()
|
||||
if s != nil {
|
||||
for _, c := range s.certs {
|
||||
sum.AddCert(c)
|
||||
}
|
||||
}
|
||||
if other != nil {
|
||||
for _, c := range other.certs {
|
||||
sum.AddCert(c)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddCert adds a certificate to a pool.
|
||||
func (s *CertPool) AddCert(cert *Certificate) {
|
||||
if cert == nil {
|
||||
panic("adding nil Certificate to CertPool")
|
||||
}
|
||||
|
||||
// Check that the certificate isn't being added twice.
|
||||
sha256fp := string(cert.FingerprintSHA256)
|
||||
if _, ok := s.bySHA256[sha256fp]; ok {
|
||||
return
|
||||
}
|
||||
|
||||
n := len(s.certs)
|
||||
s.certs = append(s.certs, cert)
|
||||
|
||||
if len(cert.SubjectKeyId) > 0 {
|
||||
keyId := string(cert.SubjectKeyId)
|
||||
s.bySubjectKeyId[keyId] = append(s.bySubjectKeyId[keyId], n)
|
||||
}
|
||||
name := string(cert.RawSubject)
|
||||
s.byName[name] = append(s.byName[name], n)
|
||||
s.bySHA256[sha256fp] = n
|
||||
}
|
||||
|
||||
// AppendCertsFromPEM attempts to parse a series of PEM encoded certificates.
|
||||
// It appends any certificates found to s and reports whether any certificates
|
||||
// were successfully parsed.
|
||||
//
|
||||
// On many Linux systems, /etc/ssl/cert.pem will contain the system wide set
|
||||
// of root CAs in a format suitable for this function.
|
||||
func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
|
||||
for len(pemCerts) > 0 {
|
||||
var block *pem.Block
|
||||
block, pemCerts = pem.Decode(pemCerts)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
cert, err := ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
s.AddCert(cert)
|
||||
ok = true
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Subjects returns a list of the DER-encoded subjects of
|
||||
// all of the certificates in the pool.
|
||||
func (s *CertPool) Subjects() [][]byte {
|
||||
res := make([][]byte, len(s.certs))
|
||||
for i, c := range s.certs {
|
||||
res[i] = c.RawSubject
|
||||
}
|
||||
return res
|
||||
}
|
64
vendor/github.com/zmap/zcrypto/x509/certificate_type.go
generated
vendored
Normal file
64
vendor/github.com/zmap/zcrypto/x509/certificate_type.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// TODO: Automatically generate this file from a CSV
|
||||
|
||||
// CertificateType represents whether a certificate is a root, intermediate, or
|
||||
// leaf.
|
||||
type CertificateType int
|
||||
|
||||
// CertificateType constants. Values should not be considered significant aside
|
||||
// from CertificateTypeUnknown is the zero value.
|
||||
const (
|
||||
CertificateTypeUnknown CertificateType = 0
|
||||
CertificateTypeLeaf CertificateType = 1
|
||||
CertificateTypeIntermediate CertificateType = 2
|
||||
CertificateTypeRoot CertificateType = 3
|
||||
)
|
||||
|
||||
const (
|
||||
certificateTypeStringLeaf = "leaf"
|
||||
certificateTypeStringIntermediate = "intermediate"
|
||||
certificateTypeStringRoot = "root"
|
||||
certificateTypeStringUnknown = "unknown"
|
||||
)
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface. Any unknown integer
|
||||
// value is considered the same as CertificateTypeUnknown.
|
||||
func (t CertificateType) MarshalJSON() ([]byte, error) {
|
||||
switch t {
|
||||
case CertificateTypeLeaf:
|
||||
return json.Marshal(certificateTypeStringLeaf)
|
||||
case CertificateTypeIntermediate:
|
||||
return json.Marshal(certificateTypeStringIntermediate)
|
||||
case CertificateTypeRoot:
|
||||
return json.Marshal(certificateTypeStringRoot)
|
||||
default:
|
||||
return json.Marshal(certificateTypeStringUnknown)
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface. Any unknown string
|
||||
// is considered the same CertificateTypeUnknown.
|
||||
func (t *CertificateType) UnmarshalJSON(b []byte) error {
|
||||
var certificateTypeString string
|
||||
if err := json.Unmarshal(b, &certificateTypeString); err != nil {
|
||||
return err
|
||||
}
|
||||
switch certificateTypeString {
|
||||
case certificateTypeStringLeaf:
|
||||
*t = CertificateTypeLeaf
|
||||
case certificateTypeStringIntermediate:
|
||||
*t = CertificateTypeIntermediate
|
||||
case certificateTypeStringRoot:
|
||||
*t = CertificateTypeRoot
|
||||
default:
|
||||
*t = CertificateTypeUnknown
|
||||
}
|
||||
return nil
|
||||
}
|
70
vendor/github.com/zmap/zcrypto/x509/chain.go
generated
vendored
Normal file
70
vendor/github.com/zmap/zcrypto/x509/chain.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CertificateChain is a slice of certificates. The 0'th element is the leaf,
|
||||
// and the last element is a root. Successive elements have a child-parent
|
||||
// relationship.
|
||||
type CertificateChain []*Certificate
|
||||
|
||||
// Range runs a function on each element of chain. It can modify each
|
||||
// certificate in place.
|
||||
func (chain CertificateChain) Range(f func(int, *Certificate)) {
|
||||
for i, c := range chain {
|
||||
f(i, c)
|
||||
}
|
||||
}
|
||||
|
||||
// SubjectAndKeyInChain returns true if the given SubjectAndKey is found in any
|
||||
// certificate in the chain.
|
||||
func (chain CertificateChain) SubjectAndKeyInChain(sk *SubjectAndKey) bool {
|
||||
for _, cert := range chain {
|
||||
if bytes.Equal(sk.RawSubject, cert.RawSubject) && bytes.Equal(sk.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CertificateSubjectAndKeyInChain returns true if the SubjectAndKey from c is
|
||||
// found in any certificate in the chain.
|
||||
func (chain CertificateChain) CertificateSubjectAndKeyInChain(c *Certificate) bool {
|
||||
for _, cert := range chain {
|
||||
if bytes.Equal(c.RawSubject, cert.RawSubject) && bytes.Equal(c.RawSubjectPublicKeyInfo, cert.RawSubjectPublicKeyInfo) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CertificateInChain returns true if c is in the chain.
|
||||
func (chain CertificateChain) CertificateInChain(c *Certificate) bool {
|
||||
for _, cert := range chain {
|
||||
if bytes.Equal(c.Raw, cert.Raw) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (chain CertificateChain) AppendToFreshChain(c *Certificate) CertificateChain {
|
||||
n := make([]*Certificate, len(chain)+1)
|
||||
copy(n, chain)
|
||||
n[len(chain)] = c
|
||||
return n
|
||||
}
|
||||
|
||||
func (chain CertificateChain) chainID() string {
|
||||
var parts []string
|
||||
for _, c := range chain {
|
||||
parts = append(parts, string(c.FingerprintSHA256))
|
||||
}
|
||||
return strings.Join(parts, "")
|
||||
}
|
168
vendor/github.com/zmap/zcrypto/x509/ct/serialization.go
generated
vendored
Normal file
168
vendor/github.com/zmap/zcrypto/x509/ct/serialization.go
generated
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
package ct
|
||||
|
||||
// This file contains selectively chosen snippets of
|
||||
// github.com/google/certificate-transparency-go@ 5cfe585726ad9d990d4db524d6ce2567b13e2f80
|
||||
//
|
||||
// These snippets only perform deserialization for SCTs and are recreated here to prevent pulling in the whole of the ct
|
||||
// which contains yet another version of x509,asn1 and tls
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Variable size structure prefix-header byte lengths
|
||||
const (
|
||||
CertificateLengthBytes = 3
|
||||
PreCertificateLengthBytes = 3
|
||||
ExtensionsLengthBytes = 2
|
||||
CertificateChainLengthBytes = 3
|
||||
SignatureLengthBytes = 2
|
||||
)
|
||||
|
||||
func writeUint(w io.Writer, value uint64, numBytes int) error {
|
||||
buf := make([]uint8, numBytes)
|
||||
for i := 0; i < numBytes; i++ {
|
||||
buf[numBytes-i-1] = uint8(value & 0xff)
|
||||
value >>= 8
|
||||
}
|
||||
if value != 0 {
|
||||
return errors.New("numBytes was insufficiently large to represent value")
|
||||
}
|
||||
if _, err := w.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeVarBytes(w io.Writer, value []byte, numLenBytes int) error {
|
||||
if err := writeUint(w, uint64(len(value)), numLenBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(value); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readUint(r io.Reader, numBytes int) (uint64, error) {
|
||||
var l uint64
|
||||
for i := 0; i < numBytes; i++ {
|
||||
l <<= 8
|
||||
var t uint8
|
||||
if err := binary.Read(r, binary.BigEndian, &t); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l |= uint64(t)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// Reads a variable length array of bytes from |r|. |numLenBytes| specifies the
|
||||
// number of (BigEndian) prefix-bytes which contain the length of the actual
|
||||
// array data bytes that follow.
|
||||
// Allocates an array to hold the contents and returns a slice view into it if
|
||||
// the read was successful, or an error otherwise.
|
||||
func readVarBytes(r io.Reader, numLenBytes int) ([]byte, error) {
|
||||
switch {
|
||||
case numLenBytes > 8:
|
||||
return nil, fmt.Errorf("numLenBytes too large (%d)", numLenBytes)
|
||||
case numLenBytes == 0:
|
||||
return nil, errors.New("numLenBytes should be > 0")
|
||||
}
|
||||
l, err := readUint(r, numLenBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := make([]byte, l)
|
||||
if n, err := io.ReadFull(r, data); err != nil {
|
||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||
return nil, fmt.Errorf("short read: expected %d but got %d", l, n)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// UnmarshalDigitallySigned reconstructs a DigitallySigned structure from a Reader
|
||||
func UnmarshalDigitallySigned(r io.Reader) (*DigitallySigned, error) {
|
||||
var h byte
|
||||
if err := binary.Read(r, binary.BigEndian, &h); err != nil {
|
||||
return nil, fmt.Errorf("failed to read HashAlgorithm: %v", err)
|
||||
}
|
||||
|
||||
var s byte
|
||||
if err := binary.Read(r, binary.BigEndian, &s); err != nil {
|
||||
return nil, fmt.Errorf("failed to read SignatureAlgorithm: %v", err)
|
||||
}
|
||||
|
||||
sig, err := readVarBytes(r, SignatureLengthBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read Signature bytes: %v", err)
|
||||
}
|
||||
|
||||
return &DigitallySigned{
|
||||
HashAlgorithm: HashAlgorithm(h),
|
||||
SignatureAlgorithm: SignatureAlgorithm(s),
|
||||
Signature: sig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func marshalDigitallySignedHere(ds DigitallySigned, here []byte) ([]byte, error) {
|
||||
sigLen := len(ds.Signature)
|
||||
dsOutLen := 2 + SignatureLengthBytes + sigLen
|
||||
if here == nil {
|
||||
here = make([]byte, dsOutLen)
|
||||
}
|
||||
if len(here) < dsOutLen {
|
||||
return nil, ErrNotEnoughBuffer
|
||||
}
|
||||
here = here[0:dsOutLen]
|
||||
|
||||
here[0] = byte(ds.HashAlgorithm)
|
||||
here[1] = byte(ds.SignatureAlgorithm)
|
||||
binary.BigEndian.PutUint16(here[2:4], uint16(sigLen))
|
||||
copy(here[4:], ds.Signature)
|
||||
|
||||
return here, nil
|
||||
}
|
||||
|
||||
// MarshalDigitallySigned marshalls a DigitallySigned structure into a byte array
|
||||
func MarshalDigitallySigned(ds DigitallySigned) ([]byte, error) {
|
||||
return marshalDigitallySignedHere(ds, nil)
|
||||
}
|
||||
|
||||
func deserializeSCTV1(r io.Reader, sct *SignedCertificateTimestamp) error {
|
||||
if err := binary.Read(r, binary.BigEndian, &sct.LogID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(r, binary.BigEndian, &sct.Timestamp); err != nil {
|
||||
return err
|
||||
}
|
||||
ext, err := readVarBytes(r, ExtensionsLengthBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sct.Extensions = ext
|
||||
ds, err := UnmarshalDigitallySigned(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sct.Signature = *ds
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeserializeSCT(r io.Reader) (*SignedCertificateTimestamp, error) {
|
||||
var sct SignedCertificateTimestamp
|
||||
if err := binary.Read(r, binary.BigEndian, &sct.SCTVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch sct.SCTVersion {
|
||||
case V1:
|
||||
return &sct, deserializeSCTV1(r, &sct)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown SCT version %d", sct.SCTVersion)
|
||||
}
|
||||
}
|
229
vendor/github.com/zmap/zcrypto/x509/ct/types.go
generated
vendored
Normal file
229
vendor/github.com/zmap/zcrypto/x509/ct/types.go
generated
vendored
Normal file
|
@ -0,0 +1,229 @@
|
|||
package ct
|
||||
|
||||
// This file contains selectively chosen snippets of
|
||||
// github.com/google/certificate-transparency-go@ 5cfe585726ad9d990d4db524d6ce2567b13e2f80
|
||||
//
|
||||
// These snippets only perform deserialization for SCTs and are recreated here to prevent pulling in the whole of the ct
|
||||
// which contains yet another version of x509,asn1 and tls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// CTExtensions is a representation of the raw bytes of any CtExtension
|
||||
// structure (see section 3.2)
|
||||
type CTExtensions []byte
|
||||
|
||||
// SHA256Hash represents the output from the SHA256 hash function.
|
||||
type SHA256Hash [sha256.Size]byte
|
||||
|
||||
// FromBase64String populates the SHA256 struct with the contents of the base64 data passed in.
|
||||
func (s *SHA256Hash) FromBase64String(b64 string) error {
|
||||
bs, err := base64.StdEncoding.DecodeString(b64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unbase64 LogID: %v", err)
|
||||
}
|
||||
if len(bs) != sha256.Size {
|
||||
return fmt.Errorf("invalid SHA256 length, expected 32 but got %d", len(bs))
|
||||
}
|
||||
copy(s[:], bs)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Base64String returns the base64 representation of this SHA256Hash.
|
||||
func (s SHA256Hash) Base64String() string {
|
||||
return base64.StdEncoding.EncodeToString(s[:])
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface for SHA256Hash.
|
||||
func (s SHA256Hash) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"` + s.Base64String() + `"`), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaller interface.
|
||||
func (s *SHA256Hash) UnmarshalJSON(b []byte) error {
|
||||
var content string
|
||||
if err := json.Unmarshal(b, &content); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal SHA256Hash: %v", err)
|
||||
}
|
||||
return s.FromBase64String(content)
|
||||
}
|
||||
|
||||
// HashAlgorithm from the DigitallySigned struct
|
||||
type HashAlgorithm byte
|
||||
|
||||
// HashAlgorithm constants
|
||||
const (
|
||||
None HashAlgorithm = 0
|
||||
MD5 HashAlgorithm = 1
|
||||
SHA1 HashAlgorithm = 2
|
||||
SHA224 HashAlgorithm = 3
|
||||
SHA256 HashAlgorithm = 4
|
||||
SHA384 HashAlgorithm = 5
|
||||
SHA512 HashAlgorithm = 6
|
||||
)
|
||||
|
||||
func (h HashAlgorithm) String() string {
|
||||
switch h {
|
||||
case None:
|
||||
return "None"
|
||||
case MD5:
|
||||
return "MD5"
|
||||
case SHA1:
|
||||
return "SHA1"
|
||||
case SHA224:
|
||||
return "SHA224"
|
||||
case SHA256:
|
||||
return "SHA256"
|
||||
case SHA384:
|
||||
return "SHA384"
|
||||
case SHA512:
|
||||
return "SHA512"
|
||||
default:
|
||||
return fmt.Sprintf("UNKNOWN(%d)", h)
|
||||
}
|
||||
}
|
||||
|
||||
// SignatureAlgorithm from the the DigitallySigned struct
|
||||
type SignatureAlgorithm byte
|
||||
|
||||
// SignatureAlgorithm constants
|
||||
const (
|
||||
Anonymous SignatureAlgorithm = 0
|
||||
RSA SignatureAlgorithm = 1
|
||||
DSA SignatureAlgorithm = 2
|
||||
ECDSA SignatureAlgorithm = 3
|
||||
)
|
||||
|
||||
func (s SignatureAlgorithm) String() string {
|
||||
switch s {
|
||||
case Anonymous:
|
||||
return "Anonymous"
|
||||
case RSA:
|
||||
return "RSA"
|
||||
case DSA:
|
||||
return "DSA"
|
||||
case ECDSA:
|
||||
return "ECDSA"
|
||||
default:
|
||||
return fmt.Sprintf("UNKNOWN(%d)", s)
|
||||
}
|
||||
}
|
||||
|
||||
// DigitallySigned represents an RFC5246 DigitallySigned structure
|
||||
type DigitallySigned struct {
|
||||
HashAlgorithm HashAlgorithm
|
||||
SignatureAlgorithm SignatureAlgorithm
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
// FromBase64String populates the DigitallySigned structure from the base64 data passed in.
|
||||
// Returns an error if the base64 data is invalid.
|
||||
func (d *DigitallySigned) FromBase64String(b64 string) error {
|
||||
raw, err := base64.StdEncoding.DecodeString(b64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unbase64 DigitallySigned: %v", err)
|
||||
}
|
||||
ds, err := UnmarshalDigitallySigned(bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err)
|
||||
}
|
||||
*d = *ds
|
||||
return nil
|
||||
}
|
||||
|
||||
// Base64String returns the base64 representation of the DigitallySigned struct.
|
||||
func (d DigitallySigned) Base64String() (string, error) {
|
||||
b, err := MarshalDigitallySigned(d)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaller interface.
|
||||
func (d DigitallySigned) MarshalJSON() ([]byte, error) {
|
||||
b64, err := d.Base64String()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return []byte(`"` + b64 + `"`), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (d *DigitallySigned) UnmarshalJSON(b []byte) error {
|
||||
var content string
|
||||
if err := json.Unmarshal(b, &content); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal DigitallySigned: %v", err)
|
||||
}
|
||||
return d.FromBase64String(content)
|
||||
}
|
||||
|
||||
// Version represents the Version enum from section 3.2 of the RFC:
|
||||
// enum { v1(0), (255) } Version;
|
||||
type Version uint8
|
||||
|
||||
func (v Version) String() string {
|
||||
switch v {
|
||||
case V1:
|
||||
return "V1"
|
||||
default:
|
||||
return fmt.Sprintf("UnknownVersion(%d)", v)
|
||||
}
|
||||
}
|
||||
|
||||
// CT Version constants, see section 3.2 of the RFC.
|
||||
const (
|
||||
V1 Version = 0
|
||||
)
|
||||
|
||||
// SignedCertificateTimestamp represents the structure returned by the
|
||||
// add-chain and add-pre-chain methods after base64 decoding. (see RFC sections
|
||||
// 3.2 ,4.1 and 4.2)
|
||||
type SignedCertificateTimestamp struct {
|
||||
SCTVersion Version `json:"version"` // The version of the protocol to which the SCT conforms
|
||||
LogID SHA256Hash `json:"log_id"` // the SHA-256 hash of the log's public key, calculated over
|
||||
// the DER encoding of the key represented as SubjectPublicKeyInfo.
|
||||
Timestamp uint64 `json:"timestamp,omitempty"` // Timestamp (in ms since unix epoc) at which the SCT was issued. NOTE: When this is serialized, the output is in seconds, not milliseconds.
|
||||
Extensions CTExtensions `json:"extensions,omitempty"` // For future extensions to the protocol
|
||||
Signature DigitallySigned `json:"signature"` // The Log's signature for this SCT
|
||||
}
|
||||
|
||||
// Copied from ct/types.go 2018/06/15 to deal with BQ timestamp overflow; output
|
||||
// is expected to be seconds, not milliseconds.
|
||||
type auxSignedCertificateTimestamp SignedCertificateTimestamp
|
||||
|
||||
const kMaxTimestamp = 253402300799
|
||||
|
||||
// MarshalJSON implements the JSON.Marshaller interface.
|
||||
func (sct *SignedCertificateTimestamp) MarshalJSON() ([]byte, error) {
|
||||
aux := auxSignedCertificateTimestamp(*sct)
|
||||
aux.Timestamp = sct.Timestamp / 1000 // convert ms to sec
|
||||
if aux.Timestamp > kMaxTimestamp {
|
||||
aux.Timestamp = 0
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
type sctError int
|
||||
|
||||
// Preallocate errors for performance
|
||||
var (
|
||||
ErrInvalidVersion error = sctError(1)
|
||||
ErrNotEnoughBuffer error = sctError(2)
|
||||
)
|
||||
|
||||
func (e sctError) Error() string {
|
||||
switch e {
|
||||
case ErrInvalidVersion:
|
||||
return "invalid SCT version detected"
|
||||
case ErrNotEnoughBuffer:
|
||||
return "provided buffer was too small"
|
||||
default:
|
||||
return "unknown error"
|
||||
}
|
||||
}
|
65
vendor/github.com/zmap/zcrypto/x509/example.json
generated
vendored
Normal file
65
vendor/github.com/zmap/zcrypto/x509/example.json
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"domain": null,
|
||||
"certificate": {
|
||||
"version": 3,
|
||||
"serial_number": 123893,
|
||||
"signature_algorithm": {
|
||||
"id": 123,
|
||||
"name": "SHA1"
|
||||
},
|
||||
"issuer": {
|
||||
"common_name": "Starfield CA",
|
||||
"attributes": [
|
||||
{ "organization": "Startfield" },
|
||||
{ "location": "Scottsdale" },
|
||||
{ "state": "Arizona" },
|
||||
{ "country": "US" }
|
||||
]
|
||||
},
|
||||
"validity": {
|
||||
"start": "20140102",
|
||||
"end": "20150102",
|
||||
"length" :8760
|
||||
},
|
||||
"subject": {
|
||||
"common_name": "*.tools.ieft.org",
|
||||
"attributes": [
|
||||
{ "organization_unit": "Domain Control Validated" }
|
||||
]
|
||||
},
|
||||
"subject_key_info": {
|
||||
"algorithm": {
|
||||
"id": 234,
|
||||
"name": "RSA"
|
||||
},
|
||||
"key": {
|
||||
"modulus": "base64encodedmodulus",
|
||||
"exponent": 65537
|
||||
}
|
||||
},
|
||||
"extensions": [
|
||||
{
|
||||
"id": 345,
|
||||
"name": "Certificate Basic Constraints",
|
||||
"is_ca": false
|
||||
},
|
||||
{
|
||||
"id": 456,
|
||||
"name": "Alt Names",
|
||||
"alt_names": [
|
||||
"*.tools.ietf.org",
|
||||
"tools.ietf.org"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"signature_algorithm": {
|
||||
"id": 123,
|
||||
"name": "SHA1"
|
||||
},
|
||||
"signature": {
|
||||
"value": "base64encodedsignature",
|
||||
"is_valid": true,
|
||||
"matches_domain": null
|
||||
}
|
||||
}
|
679
vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go
generated
vendored
Normal file
679
vendor/github.com/zmap/zcrypto/x509/extended_key_usage.go
generated
vendored
Normal file
|
@ -0,0 +1,679 @@
|
|||
// Created by extended_key_usage_gen; DO NOT EDIT
|
||||
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
)
|
||||
|
||||
const (
|
||||
OID_EKU_APPLE_CODE_SIGNING = "1.2.840.113635.100.4.1"
|
||||
OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT = "1.2.840.113635.100.4.1.1"
|
||||
OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING = "1.2.840.113635.100.4.1.2"
|
||||
OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY = "1.2.840.113635.100.4.1.3"
|
||||
OID_EKU_APPLE_RESOURCE_SIGNING = "1.2.840.113635.100.4.1.4"
|
||||
OID_EKU_APPLE_ICHAT_SIGNING = "1.2.840.113635.100.4.2"
|
||||
OID_EKU_APPLE_ICHAT_ENCRYPTION = "1.2.840.113635.100.4.3"
|
||||
OID_EKU_APPLE_SYSTEM_IDENTITY = "1.2.840.113635.100.4.4"
|
||||
OID_EKU_APPLE_CRYPTO_ENV = "1.2.840.113635.100.4.5"
|
||||
OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV = "1.2.840.113635.100.4.5.1"
|
||||
OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV = "1.2.840.113635.100.4.5.2"
|
||||
OID_EKU_APPLE_CRYPTO_TEST_ENV = "1.2.840.113635.100.4.5.3"
|
||||
OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV = "1.2.840.113635.100.4.5.4"
|
||||
OID_EKU_APPLE_CRYPTO_QOS = "1.2.840.113635.100.4.6"
|
||||
OID_EKU_APPLE_CRYPTO_TIER0_QOS = "1.2.840.113635.100.4.6.1"
|
||||
OID_EKU_APPLE_CRYPTO_TIER1_QOS = "1.2.840.113635.100.4.6.2"
|
||||
OID_EKU_APPLE_CRYPTO_TIER2_QOS = "1.2.840.113635.100.4.6.3"
|
||||
OID_EKU_APPLE_CRYPTO_TIER3_QOS = "1.2.840.113635.100.4.6.4"
|
||||
OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING = "1.3.6.1.4.1.311.10.3.1"
|
||||
OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE = "1.3.6.1.4.1.311.10.3.10"
|
||||
OID_EKU_MICROSOFT_KEY_RECOVERY_3 = "1.3.6.1.4.1.311.10.3.11"
|
||||
OID_EKU_MICROSOFT_DOCUMENT_SIGNING = "1.3.6.1.4.1.311.10.3.12"
|
||||
OID_EKU_MICROSOFT_LIFETIME_SIGNING = "1.3.6.1.4.1.311.10.3.13"
|
||||
OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE = "1.3.6.1.4.1.311.10.3.14"
|
||||
OID_EKU_MICROSOFT_SMART_DISPLAY = "1.3.6.1.4.1.311.10.3.15"
|
||||
OID_EKU_MICROSOFT_CSP_SIGNATURE = "1.3.6.1.4.1.311.10.3.16"
|
||||
OID_EKU_MICROSOFT_TIMESTAMP_SIGNING = "1.3.6.1.4.1.311.10.3.2"
|
||||
OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO = "1.3.6.1.4.1.311.10.3.3"
|
||||
OID_EKU_MICROSOFT_SGC_SERIALIZED = "1.3.6.1.4.1.311.10.3.3.1"
|
||||
OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM = "1.3.6.1.4.1.311.10.3.4"
|
||||
OID_EKU_MICROSOFT_EFS_RECOVERY = "1.3.6.1.4.1.311.10.3.4.1"
|
||||
OID_EKU_MICROSOFT_WHQL_CRYPTO = "1.3.6.1.4.1.311.10.3.5"
|
||||
OID_EKU_MICROSOFT_NT5_CRYPTO = "1.3.6.1.4.1.311.10.3.6"
|
||||
OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO = "1.3.6.1.4.1.311.10.3.7"
|
||||
OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO = "1.3.6.1.4.1.311.10.3.8"
|
||||
OID_EKU_MICROSOFT_ROOT_LIST_SIGNER = "1.3.6.1.4.1.311.10.3.9"
|
||||
OID_EKU_MICROSOFT_DRM = "1.3.6.1.4.1.311.10.5.1"
|
||||
OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION = "1.3.6.1.4.1.311.10.5.2"
|
||||
OID_EKU_MICROSOFT_LICENSES = "1.3.6.1.4.1.311.10.5.3"
|
||||
OID_EKU_MICROSOFT_LICENSE_SERVER = "1.3.6.1.4.1.311.10.5.4"
|
||||
OID_EKU_MICROSOFT_ENROLLMENT_AGENT = "1.3.6.1.4.1.311.20.2.1"
|
||||
OID_EKU_MICROSOFT_SMARTCARD_LOGON = "1.3.6.1.4.1.311.20.2.2"
|
||||
OID_EKU_MICROSOFT_CA_EXCHANGE = "1.3.6.1.4.1.311.21.5"
|
||||
OID_EKU_MICROSOFT_KEY_RECOVERY_21 = "1.3.6.1.4.1.311.21.6"
|
||||
OID_EKU_MICROSOFT_SYSTEM_HEALTH = "1.3.6.1.4.1.311.47.1.1"
|
||||
OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE = "1.3.6.1.4.1.311.47.1.3"
|
||||
OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING = "1.3.6.1.4.1.311.61.1.1"
|
||||
OID_EKU_SERVER_AUTH = "1.3.6.1.5.5.7.3.1"
|
||||
OID_EKU_DVCS = "1.3.6.1.5.5.7.3.10"
|
||||
OID_EKU_SBGP_CERT_AA_SERVICE_AUTH = "1.3.6.1.5.5.7.3.11"
|
||||
OID_EKU_EAP_OVER_PPP = "1.3.6.1.5.5.7.3.13"
|
||||
OID_EKU_EAP_OVER_LAN = "1.3.6.1.5.5.7.3.14"
|
||||
OID_EKU_CLIENT_AUTH = "1.3.6.1.5.5.7.3.2"
|
||||
OID_EKU_CODE_SIGNING = "1.3.6.1.5.5.7.3.3"
|
||||
OID_EKU_EMAIL_PROTECTION = "1.3.6.1.5.5.7.3.4"
|
||||
OID_EKU_IPSEC_END_SYSTEM = "1.3.6.1.5.5.7.3.5"
|
||||
OID_EKU_IPSEC_TUNNEL = "1.3.6.1.5.5.7.3.6"
|
||||
OID_EKU_IPSEC_USER = "1.3.6.1.5.5.7.3.7"
|
||||
OID_EKU_TIME_STAMPING = "1.3.6.1.5.5.7.3.8"
|
||||
OID_EKU_OCSP_SIGNING = "1.3.6.1.5.5.7.3.9"
|
||||
OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE = "1.3.6.1.5.5.8.2.2"
|
||||
OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO = "2.16.840.1.113730.4.1"
|
||||
OID_EKU_ANY = "2.5.29.37.0"
|
||||
)
|
||||
|
||||
var (
|
||||
oidExtKeyUsageAppleCodeSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1}
|
||||
oidExtKeyUsageAppleCodeSigningDevelopment = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 1}
|
||||
oidExtKeyUsageAppleSoftwareUpdateSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 2}
|
||||
oidExtKeyUsageAppleCodeSigningThirdParty = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 3}
|
||||
oidExtKeyUsageAppleResourceSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 1, 4}
|
||||
oidExtKeyUsageAppleIchatSigning = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 2}
|
||||
oidExtKeyUsageAppleIchatEncryption = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 3}
|
||||
oidExtKeyUsageAppleSystemIdentity = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 4}
|
||||
oidExtKeyUsageAppleCryptoEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5}
|
||||
oidExtKeyUsageAppleCryptoProductionEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 1}
|
||||
oidExtKeyUsageAppleCryptoMaintenanceEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 2}
|
||||
oidExtKeyUsageAppleCryptoTestEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 3}
|
||||
oidExtKeyUsageAppleCryptoDevelopmentEnv = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 5, 4}
|
||||
oidExtKeyUsageAppleCryptoQos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6}
|
||||
oidExtKeyUsageAppleCryptoTier0Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 1}
|
||||
oidExtKeyUsageAppleCryptoTier1Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 2}
|
||||
oidExtKeyUsageAppleCryptoTier2Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 3}
|
||||
oidExtKeyUsageAppleCryptoTier3Qos = asn1.ObjectIdentifier{1, 2, 840, 113635, 100, 4, 6, 4}
|
||||
oidExtKeyUsageMicrosoftCertTrustListSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 1}
|
||||
oidExtKeyUsageMicrosoftQualifiedSubordinate = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 10}
|
||||
oidExtKeyUsageMicrosoftKeyRecovery3 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 11}
|
||||
oidExtKeyUsageMicrosoftDocumentSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 12}
|
||||
oidExtKeyUsageMicrosoftLifetimeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 13}
|
||||
oidExtKeyUsageMicrosoftMobileDeviceSoftware = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 14}
|
||||
oidExtKeyUsageMicrosoftSmartDisplay = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 15}
|
||||
oidExtKeyUsageMicrosoftCspSignature = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 16}
|
||||
oidExtKeyUsageMicrosoftTimestampSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 2}
|
||||
oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
|
||||
oidExtKeyUsageMicrosoftSgcSerialized = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3, 1}
|
||||
oidExtKeyUsageMicrosoftEncryptedFileSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 4}
|
||||
oidExtKeyUsageMicrosoftEfsRecovery = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 4, 1}
|
||||
oidExtKeyUsageMicrosoftWhqlCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 5}
|
||||
oidExtKeyUsageMicrosoftNt5Crypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 6}
|
||||
oidExtKeyUsageMicrosoftOemWhqlCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 7}
|
||||
oidExtKeyUsageMicrosoftEmbeddedNtCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 8}
|
||||
oidExtKeyUsageMicrosoftRootListSigner = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 9}
|
||||
oidExtKeyUsageMicrosoftDrm = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 1}
|
||||
oidExtKeyUsageMicrosoftDrmIndividualization = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 2}
|
||||
oidExtKeyUsageMicrosoftLicenses = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 3}
|
||||
oidExtKeyUsageMicrosoftLicenseServer = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 5, 4}
|
||||
oidExtKeyUsageMicrosoftEnrollmentAgent = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 1}
|
||||
oidExtKeyUsageMicrosoftSmartcardLogon = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 20, 2, 2}
|
||||
oidExtKeyUsageMicrosoftCaExchange = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 21, 5}
|
||||
oidExtKeyUsageMicrosoftKeyRecovery21 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 21, 6}
|
||||
oidExtKeyUsageMicrosoftSystemHealth = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 47, 1, 1}
|
||||
oidExtKeyUsageMicrosoftSystemHealthLoophole = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 47, 1, 3}
|
||||
oidExtKeyUsageMicrosoftKernelModeCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
|
||||
oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
|
||||
oidExtKeyUsageDvcs = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 10}
|
||||
oidExtKeyUsageSbgpCertAaServiceAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 11}
|
||||
oidExtKeyUsageEapOverPpp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 13}
|
||||
oidExtKeyUsageEapOverLan = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 14}
|
||||
oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
|
||||
oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
|
||||
oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
|
||||
oidExtKeyUsageIpsecEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
|
||||
oidExtKeyUsageIpsecTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
|
||||
oidExtKeyUsageIpsecUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
|
||||
oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
|
||||
oidExtKeyUsageOcspSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
|
||||
oidExtKeyUsageIpsecIntermediateSystemUsage = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 8, 2, 2}
|
||||
oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
|
||||
oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
|
||||
)
|
||||
|
||||
const (
|
||||
ExtKeyUsageAppleCodeSigning ExtKeyUsage = iota
|
||||
ExtKeyUsageAppleCodeSigningDevelopment
|
||||
ExtKeyUsageAppleSoftwareUpdateSigning
|
||||
ExtKeyUsageAppleCodeSigningThirdParty
|
||||
ExtKeyUsageAppleResourceSigning
|
||||
ExtKeyUsageAppleIchatSigning
|
||||
ExtKeyUsageAppleIchatEncryption
|
||||
ExtKeyUsageAppleSystemIdentity
|
||||
ExtKeyUsageAppleCryptoEnv
|
||||
ExtKeyUsageAppleCryptoProductionEnv
|
||||
ExtKeyUsageAppleCryptoMaintenanceEnv
|
||||
ExtKeyUsageAppleCryptoTestEnv
|
||||
ExtKeyUsageAppleCryptoDevelopmentEnv
|
||||
ExtKeyUsageAppleCryptoQos
|
||||
ExtKeyUsageAppleCryptoTier0Qos
|
||||
ExtKeyUsageAppleCryptoTier1Qos
|
||||
ExtKeyUsageAppleCryptoTier2Qos
|
||||
ExtKeyUsageAppleCryptoTier3Qos
|
||||
ExtKeyUsageMicrosoftCertTrustListSigning
|
||||
ExtKeyUsageMicrosoftQualifiedSubordinate
|
||||
ExtKeyUsageMicrosoftKeyRecovery3
|
||||
ExtKeyUsageMicrosoftDocumentSigning
|
||||
ExtKeyUsageMicrosoftLifetimeSigning
|
||||
ExtKeyUsageMicrosoftMobileDeviceSoftware
|
||||
ExtKeyUsageMicrosoftSmartDisplay
|
||||
ExtKeyUsageMicrosoftCspSignature
|
||||
ExtKeyUsageMicrosoftTimestampSigning
|
||||
ExtKeyUsageMicrosoftServerGatedCrypto
|
||||
ExtKeyUsageMicrosoftSgcSerialized
|
||||
ExtKeyUsageMicrosoftEncryptedFileSystem
|
||||
ExtKeyUsageMicrosoftEfsRecovery
|
||||
ExtKeyUsageMicrosoftWhqlCrypto
|
||||
ExtKeyUsageMicrosoftNt5Crypto
|
||||
ExtKeyUsageMicrosoftOemWhqlCrypto
|
||||
ExtKeyUsageMicrosoftEmbeddedNtCrypto
|
||||
ExtKeyUsageMicrosoftRootListSigner
|
||||
ExtKeyUsageMicrosoftDrm
|
||||
ExtKeyUsageMicrosoftDrmIndividualization
|
||||
ExtKeyUsageMicrosoftLicenses
|
||||
ExtKeyUsageMicrosoftLicenseServer
|
||||
ExtKeyUsageMicrosoftEnrollmentAgent
|
||||
ExtKeyUsageMicrosoftSmartcardLogon
|
||||
ExtKeyUsageMicrosoftCaExchange
|
||||
ExtKeyUsageMicrosoftKeyRecovery21
|
||||
ExtKeyUsageMicrosoftSystemHealth
|
||||
ExtKeyUsageMicrosoftSystemHealthLoophole
|
||||
ExtKeyUsageMicrosoftKernelModeCodeSigning
|
||||
ExtKeyUsageServerAuth
|
||||
ExtKeyUsageDvcs
|
||||
ExtKeyUsageSbgpCertAaServiceAuth
|
||||
ExtKeyUsageEapOverPpp
|
||||
ExtKeyUsageEapOverLan
|
||||
ExtKeyUsageClientAuth
|
||||
ExtKeyUsageCodeSigning
|
||||
ExtKeyUsageEmailProtection
|
||||
ExtKeyUsageIpsecEndSystem
|
||||
ExtKeyUsageIpsecTunnel
|
||||
ExtKeyUsageIpsecUser
|
||||
ExtKeyUsageTimeStamping
|
||||
ExtKeyUsageOcspSigning
|
||||
ExtKeyUsageIpsecIntermediateSystemUsage
|
||||
ExtKeyUsageNetscapeServerGatedCrypto
|
||||
ExtKeyUsageAny
|
||||
)
|
||||
|
||||
type auxExtendedKeyUsage struct {
|
||||
AppleCodeSigning bool `json:"apple_code_signing,omitempty" oid:"1.2.840.113635.100.4.1"`
|
||||
AppleCodeSigningDevelopment bool `json:"apple_code_signing_development,omitempty" oid:"1.2.840.113635.100.4.1.1"`
|
||||
AppleSoftwareUpdateSigning bool `json:"apple_software_update_signing,omitempty" oid:"1.2.840.113635.100.4.1.2"`
|
||||
AppleCodeSigningThirdParty bool `json:"apple_code_signing_third_party,omitempty" oid:"1.2.840.113635.100.4.1.3"`
|
||||
AppleResourceSigning bool `json:"apple_resource_signing,omitempty" oid:"1.2.840.113635.100.4.1.4"`
|
||||
AppleIchatSigning bool `json:"apple_ichat_signing,omitempty" oid:"1.2.840.113635.100.4.2"`
|
||||
AppleIchatEncryption bool `json:"apple_ichat_encryption,omitempty" oid:"1.2.840.113635.100.4.3"`
|
||||
AppleSystemIdentity bool `json:"apple_system_identity,omitempty" oid:"1.2.840.113635.100.4.4"`
|
||||
AppleCryptoEnv bool `json:"apple_crypto_env,omitempty" oid:"1.2.840.113635.100.4.5"`
|
||||
AppleCryptoProductionEnv bool `json:"apple_crypto_production_env,omitempty" oid:"1.2.840.113635.100.4.5.1"`
|
||||
AppleCryptoMaintenanceEnv bool `json:"apple_crypto_maintenance_env,omitempty" oid:"1.2.840.113635.100.4.5.2"`
|
||||
AppleCryptoTestEnv bool `json:"apple_crypto_test_env,omitempty" oid:"1.2.840.113635.100.4.5.3"`
|
||||
AppleCryptoDevelopmentEnv bool `json:"apple_crypto_development_env,omitempty" oid:"1.2.840.113635.100.4.5.4"`
|
||||
AppleCryptoQos bool `json:"apple_crypto_qos,omitempty" oid:"1.2.840.113635.100.4.6"`
|
||||
AppleCryptoTier0Qos bool `json:"apple_crypto_tier0_qos,omitempty" oid:"1.2.840.113635.100.4.6.1"`
|
||||
AppleCryptoTier1Qos bool `json:"apple_crypto_tier1_qos,omitempty" oid:"1.2.840.113635.100.4.6.2"`
|
||||
AppleCryptoTier2Qos bool `json:"apple_crypto_tier2_qos,omitempty" oid:"1.2.840.113635.100.4.6.3"`
|
||||
AppleCryptoTier3Qos bool `json:"apple_crypto_tier3_qos,omitempty" oid:"1.2.840.113635.100.4.6.4"`
|
||||
MicrosoftCertTrustListSigning bool `json:"microsoft_cert_trust_list_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.1"`
|
||||
MicrosoftQualifiedSubordinate bool `json:"microsoft_qualified_subordinate,omitempty" oid:"1.3.6.1.4.1.311.10.3.10"`
|
||||
MicrosoftKeyRecovery3 bool `json:"microsoft_key_recovery_3,omitempty" oid:"1.3.6.1.4.1.311.10.3.11"`
|
||||
MicrosoftDocumentSigning bool `json:"microsoft_document_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.12"`
|
||||
MicrosoftLifetimeSigning bool `json:"microsoft_lifetime_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.13"`
|
||||
MicrosoftMobileDeviceSoftware bool `json:"microsoft_mobile_device_software,omitempty" oid:"1.3.6.1.4.1.311.10.3.14"`
|
||||
MicrosoftSmartDisplay bool `json:"microsoft_smart_display,omitempty" oid:"1.3.6.1.4.1.311.10.3.15"`
|
||||
MicrosoftCspSignature bool `json:"microsoft_csp_signature,omitempty" oid:"1.3.6.1.4.1.311.10.3.16"`
|
||||
MicrosoftTimestampSigning bool `json:"microsoft_timestamp_signing,omitempty" oid:"1.3.6.1.4.1.311.10.3.2"`
|
||||
MicrosoftServerGatedCrypto bool `json:"microsoft_server_gated_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.3"`
|
||||
MicrosoftSgcSerialized bool `json:"microsoft_sgc_serialized,omitempty" oid:"1.3.6.1.4.1.311.10.3.3.1"`
|
||||
MicrosoftEncryptedFileSystem bool `json:"microsoft_encrypted_file_system,omitempty" oid:"1.3.6.1.4.1.311.10.3.4"`
|
||||
MicrosoftEfsRecovery bool `json:"microsoft_efs_recovery,omitempty" oid:"1.3.6.1.4.1.311.10.3.4.1"`
|
||||
MicrosoftWhqlCrypto bool `json:"microsoft_whql_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.5"`
|
||||
MicrosoftNt5Crypto bool `json:"microsoft_nt5_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.6"`
|
||||
MicrosoftOemWhqlCrypto bool `json:"microsoft_oem_whql_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.7"`
|
||||
MicrosoftEmbeddedNtCrypto bool `json:"microsoft_embedded_nt_crypto,omitempty" oid:"1.3.6.1.4.1.311.10.3.8"`
|
||||
MicrosoftRootListSigner bool `json:"microsoft_root_list_signer,omitempty" oid:"1.3.6.1.4.1.311.10.3.9"`
|
||||
MicrosoftDrm bool `json:"microsoft_drm,omitempty" oid:"1.3.6.1.4.1.311.10.5.1"`
|
||||
MicrosoftDrmIndividualization bool `json:"microsoft_drm_individualization,omitempty" oid:"1.3.6.1.4.1.311.10.5.2"`
|
||||
MicrosoftLicenses bool `json:"microsoft_licenses,omitempty" oid:"1.3.6.1.4.1.311.10.5.3"`
|
||||
MicrosoftLicenseServer bool `json:"microsoft_license_server,omitempty" oid:"1.3.6.1.4.1.311.10.5.4"`
|
||||
MicrosoftEnrollmentAgent bool `json:"microsoft_enrollment_agent,omitempty" oid:"1.3.6.1.4.1.311.20.2.1"`
|
||||
MicrosoftSmartcardLogon bool `json:"microsoft_smartcard_logon,omitempty" oid:"1.3.6.1.4.1.311.20.2.2"`
|
||||
MicrosoftCaExchange bool `json:"microsoft_ca_exchange,omitempty" oid:"1.3.6.1.4.1.311.21.5"`
|
||||
MicrosoftKeyRecovery21 bool `json:"microsoft_key_recovery_21,omitempty" oid:"1.3.6.1.4.1.311.21.6"`
|
||||
MicrosoftSystemHealth bool `json:"microsoft_system_health,omitempty" oid:"1.3.6.1.4.1.311.47.1.1"`
|
||||
MicrosoftSystemHealthLoophole bool `json:"microsoft_system_health_loophole,omitempty" oid:"1.3.6.1.4.1.311.47.1.3"`
|
||||
MicrosoftKernelModeCodeSigning bool `json:"microsoft_kernel_mode_code_signing,omitempty" oid:"1.3.6.1.4.1.311.61.1.1"`
|
||||
ServerAuth bool `json:"server_auth,omitempty" oid:"1.3.6.1.5.5.7.3.1"`
|
||||
Dvcs bool `json:"dvcs,omitempty" oid:"1.3.6.1.5.5.7.3.10"`
|
||||
SbgpCertAaServiceAuth bool `json:"sbgp_cert_aa_service_auth,omitempty" oid:"1.3.6.1.5.5.7.3.11"`
|
||||
EapOverPpp bool `json:"eap_over_ppp,omitempty" oid:"1.3.6.1.5.5.7.3.13"`
|
||||
EapOverLan bool `json:"eap_over_lan,omitempty" oid:"1.3.6.1.5.5.7.3.14"`
|
||||
ClientAuth bool `json:"client_auth,omitempty" oid:"1.3.6.1.5.5.7.3.2"`
|
||||
CodeSigning bool `json:"code_signing,omitempty" oid:"1.3.6.1.5.5.7.3.3"`
|
||||
EmailProtection bool `json:"email_protection,omitempty" oid:"1.3.6.1.5.5.7.3.4"`
|
||||
IpsecEndSystem bool `json:"ipsec_end_system,omitempty" oid:"1.3.6.1.5.5.7.3.5"`
|
||||
IpsecTunnel bool `json:"ipsec_tunnel,omitempty" oid:"1.3.6.1.5.5.7.3.6"`
|
||||
IpsecUser bool `json:"ipsec_user,omitempty" oid:"1.3.6.1.5.5.7.3.7"`
|
||||
TimeStamping bool `json:"time_stamping,omitempty" oid:"1.3.6.1.5.5.7.3.8"`
|
||||
OcspSigning bool `json:"ocsp_signing,omitempty" oid:"1.3.6.1.5.5.7.3.9"`
|
||||
IpsecIntermediateSystemUsage bool `json:"ipsec_intermediate_system_usage,omitempty" oid:"1.3.6.1.5.5.8.2.2"`
|
||||
NetscapeServerGatedCrypto bool `json:"netscape_server_gated_crypto,omitempty" oid:"2.16.840.1.113730.4.1"`
|
||||
Any bool `json:"any,omitempty" oid:"2.5.29.37.0"`
|
||||
Unknown []string `json:"unknown,omitempty"`
|
||||
}
|
||||
|
||||
func (aux *auxExtendedKeyUsage) populateFromASN1(oid asn1.ObjectIdentifier) {
|
||||
s := oid.String()
|
||||
switch s {
|
||||
case OID_EKU_APPLE_CODE_SIGNING:
|
||||
aux.AppleCodeSigning = true
|
||||
case OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT:
|
||||
aux.AppleCodeSigningDevelopment = true
|
||||
case OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING:
|
||||
aux.AppleSoftwareUpdateSigning = true
|
||||
case OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY:
|
||||
aux.AppleCodeSigningThirdParty = true
|
||||
case OID_EKU_APPLE_RESOURCE_SIGNING:
|
||||
aux.AppleResourceSigning = true
|
||||
case OID_EKU_APPLE_ICHAT_SIGNING:
|
||||
aux.AppleIchatSigning = true
|
||||
case OID_EKU_APPLE_ICHAT_ENCRYPTION:
|
||||
aux.AppleIchatEncryption = true
|
||||
case OID_EKU_APPLE_SYSTEM_IDENTITY:
|
||||
aux.AppleSystemIdentity = true
|
||||
case OID_EKU_APPLE_CRYPTO_ENV:
|
||||
aux.AppleCryptoEnv = true
|
||||
case OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV:
|
||||
aux.AppleCryptoProductionEnv = true
|
||||
case OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV:
|
||||
aux.AppleCryptoMaintenanceEnv = true
|
||||
case OID_EKU_APPLE_CRYPTO_TEST_ENV:
|
||||
aux.AppleCryptoTestEnv = true
|
||||
case OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV:
|
||||
aux.AppleCryptoDevelopmentEnv = true
|
||||
case OID_EKU_APPLE_CRYPTO_QOS:
|
||||
aux.AppleCryptoQos = true
|
||||
case OID_EKU_APPLE_CRYPTO_TIER0_QOS:
|
||||
aux.AppleCryptoTier0Qos = true
|
||||
case OID_EKU_APPLE_CRYPTO_TIER1_QOS:
|
||||
aux.AppleCryptoTier1Qos = true
|
||||
case OID_EKU_APPLE_CRYPTO_TIER2_QOS:
|
||||
aux.AppleCryptoTier2Qos = true
|
||||
case OID_EKU_APPLE_CRYPTO_TIER3_QOS:
|
||||
aux.AppleCryptoTier3Qos = true
|
||||
case OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING:
|
||||
aux.MicrosoftCertTrustListSigning = true
|
||||
case OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE:
|
||||
aux.MicrosoftQualifiedSubordinate = true
|
||||
case OID_EKU_MICROSOFT_KEY_RECOVERY_3:
|
||||
aux.MicrosoftKeyRecovery3 = true
|
||||
case OID_EKU_MICROSOFT_DOCUMENT_SIGNING:
|
||||
aux.MicrosoftDocumentSigning = true
|
||||
case OID_EKU_MICROSOFT_LIFETIME_SIGNING:
|
||||
aux.MicrosoftLifetimeSigning = true
|
||||
case OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE:
|
||||
aux.MicrosoftMobileDeviceSoftware = true
|
||||
case OID_EKU_MICROSOFT_SMART_DISPLAY:
|
||||
aux.MicrosoftSmartDisplay = true
|
||||
case OID_EKU_MICROSOFT_CSP_SIGNATURE:
|
||||
aux.MicrosoftCspSignature = true
|
||||
case OID_EKU_MICROSOFT_TIMESTAMP_SIGNING:
|
||||
aux.MicrosoftTimestampSigning = true
|
||||
case OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO:
|
||||
aux.MicrosoftServerGatedCrypto = true
|
||||
case OID_EKU_MICROSOFT_SGC_SERIALIZED:
|
||||
aux.MicrosoftSgcSerialized = true
|
||||
case OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM:
|
||||
aux.MicrosoftEncryptedFileSystem = true
|
||||
case OID_EKU_MICROSOFT_EFS_RECOVERY:
|
||||
aux.MicrosoftEfsRecovery = true
|
||||
case OID_EKU_MICROSOFT_WHQL_CRYPTO:
|
||||
aux.MicrosoftWhqlCrypto = true
|
||||
case OID_EKU_MICROSOFT_NT5_CRYPTO:
|
||||
aux.MicrosoftNt5Crypto = true
|
||||
case OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO:
|
||||
aux.MicrosoftOemWhqlCrypto = true
|
||||
case OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO:
|
||||
aux.MicrosoftEmbeddedNtCrypto = true
|
||||
case OID_EKU_MICROSOFT_ROOT_LIST_SIGNER:
|
||||
aux.MicrosoftRootListSigner = true
|
||||
case OID_EKU_MICROSOFT_DRM:
|
||||
aux.MicrosoftDrm = true
|
||||
case OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION:
|
||||
aux.MicrosoftDrmIndividualization = true
|
||||
case OID_EKU_MICROSOFT_LICENSES:
|
||||
aux.MicrosoftLicenses = true
|
||||
case OID_EKU_MICROSOFT_LICENSE_SERVER:
|
||||
aux.MicrosoftLicenseServer = true
|
||||
case OID_EKU_MICROSOFT_ENROLLMENT_AGENT:
|
||||
aux.MicrosoftEnrollmentAgent = true
|
||||
case OID_EKU_MICROSOFT_SMARTCARD_LOGON:
|
||||
aux.MicrosoftSmartcardLogon = true
|
||||
case OID_EKU_MICROSOFT_CA_EXCHANGE:
|
||||
aux.MicrosoftCaExchange = true
|
||||
case OID_EKU_MICROSOFT_KEY_RECOVERY_21:
|
||||
aux.MicrosoftKeyRecovery21 = true
|
||||
case OID_EKU_MICROSOFT_SYSTEM_HEALTH:
|
||||
aux.MicrosoftSystemHealth = true
|
||||
case OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE:
|
||||
aux.MicrosoftSystemHealthLoophole = true
|
||||
case OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING:
|
||||
aux.MicrosoftKernelModeCodeSigning = true
|
||||
case OID_EKU_SERVER_AUTH:
|
||||
aux.ServerAuth = true
|
||||
case OID_EKU_DVCS:
|
||||
aux.Dvcs = true
|
||||
case OID_EKU_SBGP_CERT_AA_SERVICE_AUTH:
|
||||
aux.SbgpCertAaServiceAuth = true
|
||||
case OID_EKU_EAP_OVER_PPP:
|
||||
aux.EapOverPpp = true
|
||||
case OID_EKU_EAP_OVER_LAN:
|
||||
aux.EapOverLan = true
|
||||
case OID_EKU_CLIENT_AUTH:
|
||||
aux.ClientAuth = true
|
||||
case OID_EKU_CODE_SIGNING:
|
||||
aux.CodeSigning = true
|
||||
case OID_EKU_EMAIL_PROTECTION:
|
||||
aux.EmailProtection = true
|
||||
case OID_EKU_IPSEC_END_SYSTEM:
|
||||
aux.IpsecEndSystem = true
|
||||
case OID_EKU_IPSEC_TUNNEL:
|
||||
aux.IpsecTunnel = true
|
||||
case OID_EKU_IPSEC_USER:
|
||||
aux.IpsecUser = true
|
||||
case OID_EKU_TIME_STAMPING:
|
||||
aux.TimeStamping = true
|
||||
case OID_EKU_OCSP_SIGNING:
|
||||
aux.OcspSigning = true
|
||||
case OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE:
|
||||
aux.IpsecIntermediateSystemUsage = true
|
||||
case OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO:
|
||||
aux.NetscapeServerGatedCrypto = true
|
||||
case OID_EKU_ANY:
|
||||
aux.Any = true
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (aux *auxExtendedKeyUsage) populateFromExtKeyUsage(eku ExtKeyUsage) {
|
||||
switch eku {
|
||||
case ExtKeyUsageAppleCodeSigning:
|
||||
aux.AppleCodeSigning = true
|
||||
case ExtKeyUsageAppleCodeSigningDevelopment:
|
||||
aux.AppleCodeSigningDevelopment = true
|
||||
case ExtKeyUsageAppleSoftwareUpdateSigning:
|
||||
aux.AppleSoftwareUpdateSigning = true
|
||||
case ExtKeyUsageAppleCodeSigningThirdParty:
|
||||
aux.AppleCodeSigningThirdParty = true
|
||||
case ExtKeyUsageAppleResourceSigning:
|
||||
aux.AppleResourceSigning = true
|
||||
case ExtKeyUsageAppleIchatSigning:
|
||||
aux.AppleIchatSigning = true
|
||||
case ExtKeyUsageAppleIchatEncryption:
|
||||
aux.AppleIchatEncryption = true
|
||||
case ExtKeyUsageAppleSystemIdentity:
|
||||
aux.AppleSystemIdentity = true
|
||||
case ExtKeyUsageAppleCryptoEnv:
|
||||
aux.AppleCryptoEnv = true
|
||||
case ExtKeyUsageAppleCryptoProductionEnv:
|
||||
aux.AppleCryptoProductionEnv = true
|
||||
case ExtKeyUsageAppleCryptoMaintenanceEnv:
|
||||
aux.AppleCryptoMaintenanceEnv = true
|
||||
case ExtKeyUsageAppleCryptoTestEnv:
|
||||
aux.AppleCryptoTestEnv = true
|
||||
case ExtKeyUsageAppleCryptoDevelopmentEnv:
|
||||
aux.AppleCryptoDevelopmentEnv = true
|
||||
case ExtKeyUsageAppleCryptoQos:
|
||||
aux.AppleCryptoQos = true
|
||||
case ExtKeyUsageAppleCryptoTier0Qos:
|
||||
aux.AppleCryptoTier0Qos = true
|
||||
case ExtKeyUsageAppleCryptoTier1Qos:
|
||||
aux.AppleCryptoTier1Qos = true
|
||||
case ExtKeyUsageAppleCryptoTier2Qos:
|
||||
aux.AppleCryptoTier2Qos = true
|
||||
case ExtKeyUsageAppleCryptoTier3Qos:
|
||||
aux.AppleCryptoTier3Qos = true
|
||||
case ExtKeyUsageMicrosoftCertTrustListSigning:
|
||||
aux.MicrosoftCertTrustListSigning = true
|
||||
case ExtKeyUsageMicrosoftQualifiedSubordinate:
|
||||
aux.MicrosoftQualifiedSubordinate = true
|
||||
case ExtKeyUsageMicrosoftKeyRecovery3:
|
||||
aux.MicrosoftKeyRecovery3 = true
|
||||
case ExtKeyUsageMicrosoftDocumentSigning:
|
||||
aux.MicrosoftDocumentSigning = true
|
||||
case ExtKeyUsageMicrosoftLifetimeSigning:
|
||||
aux.MicrosoftLifetimeSigning = true
|
||||
case ExtKeyUsageMicrosoftMobileDeviceSoftware:
|
||||
aux.MicrosoftMobileDeviceSoftware = true
|
||||
case ExtKeyUsageMicrosoftSmartDisplay:
|
||||
aux.MicrosoftSmartDisplay = true
|
||||
case ExtKeyUsageMicrosoftCspSignature:
|
||||
aux.MicrosoftCspSignature = true
|
||||
case ExtKeyUsageMicrosoftTimestampSigning:
|
||||
aux.MicrosoftTimestampSigning = true
|
||||
case ExtKeyUsageMicrosoftServerGatedCrypto:
|
||||
aux.MicrosoftServerGatedCrypto = true
|
||||
case ExtKeyUsageMicrosoftSgcSerialized:
|
||||
aux.MicrosoftSgcSerialized = true
|
||||
case ExtKeyUsageMicrosoftEncryptedFileSystem:
|
||||
aux.MicrosoftEncryptedFileSystem = true
|
||||
case ExtKeyUsageMicrosoftEfsRecovery:
|
||||
aux.MicrosoftEfsRecovery = true
|
||||
case ExtKeyUsageMicrosoftWhqlCrypto:
|
||||
aux.MicrosoftWhqlCrypto = true
|
||||
case ExtKeyUsageMicrosoftNt5Crypto:
|
||||
aux.MicrosoftNt5Crypto = true
|
||||
case ExtKeyUsageMicrosoftOemWhqlCrypto:
|
||||
aux.MicrosoftOemWhqlCrypto = true
|
||||
case ExtKeyUsageMicrosoftEmbeddedNtCrypto:
|
||||
aux.MicrosoftEmbeddedNtCrypto = true
|
||||
case ExtKeyUsageMicrosoftRootListSigner:
|
||||
aux.MicrosoftRootListSigner = true
|
||||
case ExtKeyUsageMicrosoftDrm:
|
||||
aux.MicrosoftDrm = true
|
||||
case ExtKeyUsageMicrosoftDrmIndividualization:
|
||||
aux.MicrosoftDrmIndividualization = true
|
||||
case ExtKeyUsageMicrosoftLicenses:
|
||||
aux.MicrosoftLicenses = true
|
||||
case ExtKeyUsageMicrosoftLicenseServer:
|
||||
aux.MicrosoftLicenseServer = true
|
||||
case ExtKeyUsageMicrosoftEnrollmentAgent:
|
||||
aux.MicrosoftEnrollmentAgent = true
|
||||
case ExtKeyUsageMicrosoftSmartcardLogon:
|
||||
aux.MicrosoftSmartcardLogon = true
|
||||
case ExtKeyUsageMicrosoftCaExchange:
|
||||
aux.MicrosoftCaExchange = true
|
||||
case ExtKeyUsageMicrosoftKeyRecovery21:
|
||||
aux.MicrosoftKeyRecovery21 = true
|
||||
case ExtKeyUsageMicrosoftSystemHealth:
|
||||
aux.MicrosoftSystemHealth = true
|
||||
case ExtKeyUsageMicrosoftSystemHealthLoophole:
|
||||
aux.MicrosoftSystemHealthLoophole = true
|
||||
case ExtKeyUsageMicrosoftKernelModeCodeSigning:
|
||||
aux.MicrosoftKernelModeCodeSigning = true
|
||||
case ExtKeyUsageServerAuth:
|
||||
aux.ServerAuth = true
|
||||
case ExtKeyUsageDvcs:
|
||||
aux.Dvcs = true
|
||||
case ExtKeyUsageSbgpCertAaServiceAuth:
|
||||
aux.SbgpCertAaServiceAuth = true
|
||||
case ExtKeyUsageEapOverPpp:
|
||||
aux.EapOverPpp = true
|
||||
case ExtKeyUsageEapOverLan:
|
||||
aux.EapOverLan = true
|
||||
case ExtKeyUsageClientAuth:
|
||||
aux.ClientAuth = true
|
||||
case ExtKeyUsageCodeSigning:
|
||||
aux.CodeSigning = true
|
||||
case ExtKeyUsageEmailProtection:
|
||||
aux.EmailProtection = true
|
||||
case ExtKeyUsageIpsecEndSystem:
|
||||
aux.IpsecEndSystem = true
|
||||
case ExtKeyUsageIpsecTunnel:
|
||||
aux.IpsecTunnel = true
|
||||
case ExtKeyUsageIpsecUser:
|
||||
aux.IpsecUser = true
|
||||
case ExtKeyUsageTimeStamping:
|
||||
aux.TimeStamping = true
|
||||
case ExtKeyUsageOcspSigning:
|
||||
aux.OcspSigning = true
|
||||
case ExtKeyUsageIpsecIntermediateSystemUsage:
|
||||
aux.IpsecIntermediateSystemUsage = true
|
||||
case ExtKeyUsageNetscapeServerGatedCrypto:
|
||||
aux.NetscapeServerGatedCrypto = true
|
||||
case ExtKeyUsageAny:
|
||||
aux.Any = true
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var ekuOIDs map[string]asn1.ObjectIdentifier
|
||||
|
||||
var ekuConstants map[string]ExtKeyUsage
|
||||
|
||||
func init() {
|
||||
ekuOIDs = make(map[string]asn1.ObjectIdentifier)
|
||||
ekuOIDs[OID_EKU_APPLE_CODE_SIGNING] = oidExtKeyUsageAppleCodeSigning
|
||||
ekuOIDs[OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT] = oidExtKeyUsageAppleCodeSigningDevelopment
|
||||
ekuOIDs[OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING] = oidExtKeyUsageAppleSoftwareUpdateSigning
|
||||
ekuOIDs[OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY] = oidExtKeyUsageAppleCodeSigningThirdParty
|
||||
ekuOIDs[OID_EKU_APPLE_RESOURCE_SIGNING] = oidExtKeyUsageAppleResourceSigning
|
||||
ekuOIDs[OID_EKU_APPLE_ICHAT_SIGNING] = oidExtKeyUsageAppleIchatSigning
|
||||
ekuOIDs[OID_EKU_APPLE_ICHAT_ENCRYPTION] = oidExtKeyUsageAppleIchatEncryption
|
||||
ekuOIDs[OID_EKU_APPLE_SYSTEM_IDENTITY] = oidExtKeyUsageAppleSystemIdentity
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_ENV] = oidExtKeyUsageAppleCryptoEnv
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV] = oidExtKeyUsageAppleCryptoProductionEnv
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV] = oidExtKeyUsageAppleCryptoMaintenanceEnv
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_TEST_ENV] = oidExtKeyUsageAppleCryptoTestEnv
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV] = oidExtKeyUsageAppleCryptoDevelopmentEnv
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_QOS] = oidExtKeyUsageAppleCryptoQos
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER0_QOS] = oidExtKeyUsageAppleCryptoTier0Qos
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER1_QOS] = oidExtKeyUsageAppleCryptoTier1Qos
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER2_QOS] = oidExtKeyUsageAppleCryptoTier2Qos
|
||||
ekuOIDs[OID_EKU_APPLE_CRYPTO_TIER3_QOS] = oidExtKeyUsageAppleCryptoTier3Qos
|
||||
ekuOIDs[OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING] = oidExtKeyUsageMicrosoftCertTrustListSigning
|
||||
ekuOIDs[OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE] = oidExtKeyUsageMicrosoftQualifiedSubordinate
|
||||
ekuOIDs[OID_EKU_MICROSOFT_KEY_RECOVERY_3] = oidExtKeyUsageMicrosoftKeyRecovery3
|
||||
ekuOIDs[OID_EKU_MICROSOFT_DOCUMENT_SIGNING] = oidExtKeyUsageMicrosoftDocumentSigning
|
||||
ekuOIDs[OID_EKU_MICROSOFT_LIFETIME_SIGNING] = oidExtKeyUsageMicrosoftLifetimeSigning
|
||||
ekuOIDs[OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE] = oidExtKeyUsageMicrosoftMobileDeviceSoftware
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SMART_DISPLAY] = oidExtKeyUsageMicrosoftSmartDisplay
|
||||
ekuOIDs[OID_EKU_MICROSOFT_CSP_SIGNATURE] = oidExtKeyUsageMicrosoftCspSignature
|
||||
ekuOIDs[OID_EKU_MICROSOFT_TIMESTAMP_SIGNING] = oidExtKeyUsageMicrosoftTimestampSigning
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO] = oidExtKeyUsageMicrosoftServerGatedCrypto
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SGC_SERIALIZED] = oidExtKeyUsageMicrosoftSgcSerialized
|
||||
ekuOIDs[OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM] = oidExtKeyUsageMicrosoftEncryptedFileSystem
|
||||
ekuOIDs[OID_EKU_MICROSOFT_EFS_RECOVERY] = oidExtKeyUsageMicrosoftEfsRecovery
|
||||
ekuOIDs[OID_EKU_MICROSOFT_WHQL_CRYPTO] = oidExtKeyUsageMicrosoftWhqlCrypto
|
||||
ekuOIDs[OID_EKU_MICROSOFT_NT5_CRYPTO] = oidExtKeyUsageMicrosoftNt5Crypto
|
||||
ekuOIDs[OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO] = oidExtKeyUsageMicrosoftOemWhqlCrypto
|
||||
ekuOIDs[OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO] = oidExtKeyUsageMicrosoftEmbeddedNtCrypto
|
||||
ekuOIDs[OID_EKU_MICROSOFT_ROOT_LIST_SIGNER] = oidExtKeyUsageMicrosoftRootListSigner
|
||||
ekuOIDs[OID_EKU_MICROSOFT_DRM] = oidExtKeyUsageMicrosoftDrm
|
||||
ekuOIDs[OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION] = oidExtKeyUsageMicrosoftDrmIndividualization
|
||||
ekuOIDs[OID_EKU_MICROSOFT_LICENSES] = oidExtKeyUsageMicrosoftLicenses
|
||||
ekuOIDs[OID_EKU_MICROSOFT_LICENSE_SERVER] = oidExtKeyUsageMicrosoftLicenseServer
|
||||
ekuOIDs[OID_EKU_MICROSOFT_ENROLLMENT_AGENT] = oidExtKeyUsageMicrosoftEnrollmentAgent
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SMARTCARD_LOGON] = oidExtKeyUsageMicrosoftSmartcardLogon
|
||||
ekuOIDs[OID_EKU_MICROSOFT_CA_EXCHANGE] = oidExtKeyUsageMicrosoftCaExchange
|
||||
ekuOIDs[OID_EKU_MICROSOFT_KEY_RECOVERY_21] = oidExtKeyUsageMicrosoftKeyRecovery21
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SYSTEM_HEALTH] = oidExtKeyUsageMicrosoftSystemHealth
|
||||
ekuOIDs[OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE] = oidExtKeyUsageMicrosoftSystemHealthLoophole
|
||||
ekuOIDs[OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING] = oidExtKeyUsageMicrosoftKernelModeCodeSigning
|
||||
ekuOIDs[OID_EKU_SERVER_AUTH] = oidExtKeyUsageServerAuth
|
||||
ekuOIDs[OID_EKU_DVCS] = oidExtKeyUsageDvcs
|
||||
ekuOIDs[OID_EKU_SBGP_CERT_AA_SERVICE_AUTH] = oidExtKeyUsageSbgpCertAaServiceAuth
|
||||
ekuOIDs[OID_EKU_EAP_OVER_PPP] = oidExtKeyUsageEapOverPpp
|
||||
ekuOIDs[OID_EKU_EAP_OVER_LAN] = oidExtKeyUsageEapOverLan
|
||||
ekuOIDs[OID_EKU_CLIENT_AUTH] = oidExtKeyUsageClientAuth
|
||||
ekuOIDs[OID_EKU_CODE_SIGNING] = oidExtKeyUsageCodeSigning
|
||||
ekuOIDs[OID_EKU_EMAIL_PROTECTION] = oidExtKeyUsageEmailProtection
|
||||
ekuOIDs[OID_EKU_IPSEC_END_SYSTEM] = oidExtKeyUsageIpsecEndSystem
|
||||
ekuOIDs[OID_EKU_IPSEC_TUNNEL] = oidExtKeyUsageIpsecTunnel
|
||||
ekuOIDs[OID_EKU_IPSEC_USER] = oidExtKeyUsageIpsecUser
|
||||
ekuOIDs[OID_EKU_TIME_STAMPING] = oidExtKeyUsageTimeStamping
|
||||
ekuOIDs[OID_EKU_OCSP_SIGNING] = oidExtKeyUsageOcspSigning
|
||||
ekuOIDs[OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE] = oidExtKeyUsageIpsecIntermediateSystemUsage
|
||||
ekuOIDs[OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO] = oidExtKeyUsageNetscapeServerGatedCrypto
|
||||
ekuOIDs[OID_EKU_ANY] = oidExtKeyUsageAny
|
||||
|
||||
ekuConstants = make(map[string]ExtKeyUsage)
|
||||
ekuConstants[OID_EKU_APPLE_CODE_SIGNING] = ExtKeyUsageAppleCodeSigning
|
||||
ekuConstants[OID_EKU_APPLE_CODE_SIGNING_DEVELOPMENT] = ExtKeyUsageAppleCodeSigningDevelopment
|
||||
ekuConstants[OID_EKU_APPLE_SOFTWARE_UPDATE_SIGNING] = ExtKeyUsageAppleSoftwareUpdateSigning
|
||||
ekuConstants[OID_EKU_APPLE_CODE_SIGNING_THIRD_PARTY] = ExtKeyUsageAppleCodeSigningThirdParty
|
||||
ekuConstants[OID_EKU_APPLE_RESOURCE_SIGNING] = ExtKeyUsageAppleResourceSigning
|
||||
ekuConstants[OID_EKU_APPLE_ICHAT_SIGNING] = ExtKeyUsageAppleIchatSigning
|
||||
ekuConstants[OID_EKU_APPLE_ICHAT_ENCRYPTION] = ExtKeyUsageAppleIchatEncryption
|
||||
ekuConstants[OID_EKU_APPLE_SYSTEM_IDENTITY] = ExtKeyUsageAppleSystemIdentity
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_ENV] = ExtKeyUsageAppleCryptoEnv
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_PRODUCTION_ENV] = ExtKeyUsageAppleCryptoProductionEnv
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_MAINTENANCE_ENV] = ExtKeyUsageAppleCryptoMaintenanceEnv
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_TEST_ENV] = ExtKeyUsageAppleCryptoTestEnv
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_DEVELOPMENT_ENV] = ExtKeyUsageAppleCryptoDevelopmentEnv
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_QOS] = ExtKeyUsageAppleCryptoQos
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_TIER0_QOS] = ExtKeyUsageAppleCryptoTier0Qos
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_TIER1_QOS] = ExtKeyUsageAppleCryptoTier1Qos
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_TIER2_QOS] = ExtKeyUsageAppleCryptoTier2Qos
|
||||
ekuConstants[OID_EKU_APPLE_CRYPTO_TIER3_QOS] = ExtKeyUsageAppleCryptoTier3Qos
|
||||
ekuConstants[OID_EKU_MICROSOFT_CERT_TRUST_LIST_SIGNING] = ExtKeyUsageMicrosoftCertTrustListSigning
|
||||
ekuConstants[OID_EKU_MICROSOFT_QUALIFIED_SUBORDINATE] = ExtKeyUsageMicrosoftQualifiedSubordinate
|
||||
ekuConstants[OID_EKU_MICROSOFT_KEY_RECOVERY_3] = ExtKeyUsageMicrosoftKeyRecovery3
|
||||
ekuConstants[OID_EKU_MICROSOFT_DOCUMENT_SIGNING] = ExtKeyUsageMicrosoftDocumentSigning
|
||||
ekuConstants[OID_EKU_MICROSOFT_LIFETIME_SIGNING] = ExtKeyUsageMicrosoftLifetimeSigning
|
||||
ekuConstants[OID_EKU_MICROSOFT_MOBILE_DEVICE_SOFTWARE] = ExtKeyUsageMicrosoftMobileDeviceSoftware
|
||||
ekuConstants[OID_EKU_MICROSOFT_SMART_DISPLAY] = ExtKeyUsageMicrosoftSmartDisplay
|
||||
ekuConstants[OID_EKU_MICROSOFT_CSP_SIGNATURE] = ExtKeyUsageMicrosoftCspSignature
|
||||
ekuConstants[OID_EKU_MICROSOFT_TIMESTAMP_SIGNING] = ExtKeyUsageMicrosoftTimestampSigning
|
||||
ekuConstants[OID_EKU_MICROSOFT_SERVER_GATED_CRYPTO] = ExtKeyUsageMicrosoftServerGatedCrypto
|
||||
ekuConstants[OID_EKU_MICROSOFT_SGC_SERIALIZED] = ExtKeyUsageMicrosoftSgcSerialized
|
||||
ekuConstants[OID_EKU_MICROSOFT_ENCRYPTED_FILE_SYSTEM] = ExtKeyUsageMicrosoftEncryptedFileSystem
|
||||
ekuConstants[OID_EKU_MICROSOFT_EFS_RECOVERY] = ExtKeyUsageMicrosoftEfsRecovery
|
||||
ekuConstants[OID_EKU_MICROSOFT_WHQL_CRYPTO] = ExtKeyUsageMicrosoftWhqlCrypto
|
||||
ekuConstants[OID_EKU_MICROSOFT_NT5_CRYPTO] = ExtKeyUsageMicrosoftNt5Crypto
|
||||
ekuConstants[OID_EKU_MICROSOFT_OEM_WHQL_CRYPTO] = ExtKeyUsageMicrosoftOemWhqlCrypto
|
||||
ekuConstants[OID_EKU_MICROSOFT_EMBEDDED_NT_CRYPTO] = ExtKeyUsageMicrosoftEmbeddedNtCrypto
|
||||
ekuConstants[OID_EKU_MICROSOFT_ROOT_LIST_SIGNER] = ExtKeyUsageMicrosoftRootListSigner
|
||||
ekuConstants[OID_EKU_MICROSOFT_DRM] = ExtKeyUsageMicrosoftDrm
|
||||
ekuConstants[OID_EKU_MICROSOFT_DRM_INDIVIDUALIZATION] = ExtKeyUsageMicrosoftDrmIndividualization
|
||||
ekuConstants[OID_EKU_MICROSOFT_LICENSES] = ExtKeyUsageMicrosoftLicenses
|
||||
ekuConstants[OID_EKU_MICROSOFT_LICENSE_SERVER] = ExtKeyUsageMicrosoftLicenseServer
|
||||
ekuConstants[OID_EKU_MICROSOFT_ENROLLMENT_AGENT] = ExtKeyUsageMicrosoftEnrollmentAgent
|
||||
ekuConstants[OID_EKU_MICROSOFT_SMARTCARD_LOGON] = ExtKeyUsageMicrosoftSmartcardLogon
|
||||
ekuConstants[OID_EKU_MICROSOFT_CA_EXCHANGE] = ExtKeyUsageMicrosoftCaExchange
|
||||
ekuConstants[OID_EKU_MICROSOFT_KEY_RECOVERY_21] = ExtKeyUsageMicrosoftKeyRecovery21
|
||||
ekuConstants[OID_EKU_MICROSOFT_SYSTEM_HEALTH] = ExtKeyUsageMicrosoftSystemHealth
|
||||
ekuConstants[OID_EKU_MICROSOFT_SYSTEM_HEALTH_LOOPHOLE] = ExtKeyUsageMicrosoftSystemHealthLoophole
|
||||
ekuConstants[OID_EKU_MICROSOFT_KERNEL_MODE_CODE_SIGNING] = ExtKeyUsageMicrosoftKernelModeCodeSigning
|
||||
ekuConstants[OID_EKU_SERVER_AUTH] = ExtKeyUsageServerAuth
|
||||
ekuConstants[OID_EKU_DVCS] = ExtKeyUsageDvcs
|
||||
ekuConstants[OID_EKU_SBGP_CERT_AA_SERVICE_AUTH] = ExtKeyUsageSbgpCertAaServiceAuth
|
||||
ekuConstants[OID_EKU_EAP_OVER_PPP] = ExtKeyUsageEapOverPpp
|
||||
ekuConstants[OID_EKU_EAP_OVER_LAN] = ExtKeyUsageEapOverLan
|
||||
ekuConstants[OID_EKU_CLIENT_AUTH] = ExtKeyUsageClientAuth
|
||||
ekuConstants[OID_EKU_CODE_SIGNING] = ExtKeyUsageCodeSigning
|
||||
ekuConstants[OID_EKU_EMAIL_PROTECTION] = ExtKeyUsageEmailProtection
|
||||
ekuConstants[OID_EKU_IPSEC_END_SYSTEM] = ExtKeyUsageIpsecEndSystem
|
||||
ekuConstants[OID_EKU_IPSEC_TUNNEL] = ExtKeyUsageIpsecTunnel
|
||||
ekuConstants[OID_EKU_IPSEC_USER] = ExtKeyUsageIpsecUser
|
||||
ekuConstants[OID_EKU_TIME_STAMPING] = ExtKeyUsageTimeStamping
|
||||
ekuConstants[OID_EKU_OCSP_SIGNING] = ExtKeyUsageOcspSigning
|
||||
ekuConstants[OID_EKU_IPSEC_INTERMEDIATE_SYSTEM_USAGE] = ExtKeyUsageIpsecIntermediateSystemUsage
|
||||
ekuConstants[OID_EKU_NETSCAPE_SERVER_GATED_CRYPTO] = ExtKeyUsageNetscapeServerGatedCrypto
|
||||
ekuConstants[OID_EKU_ANY] = ExtKeyUsageAny
|
||||
}
|
21
vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh
generated
vendored
Normal file
21
vendor/github.com/zmap/zcrypto/x509/extended_key_usage_schema.sh
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# TODO: This should really be generated by Go code as a subrecord, but
|
||||
# importing in Python is hard. This is quick and dirty.
|
||||
|
||||
FIELDS=$(\
|
||||
cat extended_key_usage.go |\
|
||||
grep json |\
|
||||
cut -d ':' -f 2 |\
|
||||
sed 's|,omitempty||g' |\
|
||||
tr -d '`')
|
||||
echo "extended_key_usage = SubRecord({"
|
||||
for f in $FIELDS; do
|
||||
if [ $f == "\"unknown\"" ]; then
|
||||
echo " $f: ListOf(OID())"
|
||||
else
|
||||
echo " $f: Boolean(),"
|
||||
fi
|
||||
done
|
||||
echo "})"
|
818
vendor/github.com/zmap/zcrypto/x509/extensions.go
generated
vendored
Normal file
818
vendor/github.com/zmap/zcrypto/x509/extensions.go
generated
vendored
Normal file
|
@ -0,0 +1,818 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/zmap/zcrypto/x509/ct"
|
||||
"github.com/zmap/zcrypto/x509/pkix"
|
||||
)
|
||||
|
||||
var (
|
||||
oidExtKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 15}
|
||||
oidExtBasicConstraints = asn1.ObjectIdentifier{2, 5, 29, 19}
|
||||
oidExtSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
|
||||
oidExtIssuerAltName = asn1.ObjectIdentifier{2, 5, 29, 18}
|
||||
oidExtNameConstraints = asn1.ObjectIdentifier{2, 5, 29, 30}
|
||||
oidCRLDistributionPoints = asn1.ObjectIdentifier{2, 5, 29, 31}
|
||||
oidExtAuthKeyId = asn1.ObjectIdentifier{2, 5, 29, 35}
|
||||
oidExtSubjectKeyId = asn1.ObjectIdentifier{2, 5, 29, 14}
|
||||
oidExtExtendedKeyUsage = asn1.ObjectIdentifier{2, 5, 29, 37}
|
||||
oidExtCertificatePolicy = asn1.ObjectIdentifier{2, 5, 29, 32}
|
||||
|
||||
oidExtAuthorityInfoAccess = oidExtensionAuthorityInfoAccess
|
||||
oidExtensionCTPrecertificatePoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
|
||||
oidExtSignedCertificateTimestampList = oidExtensionSignedCertificateTimestampList
|
||||
|
||||
oidExtCABFOrganizationID = asn1.ObjectIdentifier{2, 23, 140, 3, 1}
|
||||
oidExtQCStatements = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3}
|
||||
)
|
||||
|
||||
type CertificateExtensions struct {
|
||||
KeyUsage KeyUsage `json:"key_usage,omitempty"`
|
||||
BasicConstraints *BasicConstraints `json:"basic_constraints,omitempty"`
|
||||
SubjectAltName *GeneralNames `json:"subject_alt_name,omitempty"`
|
||||
IssuerAltName *GeneralNames `json:"issuer_alt_name,omitempty"`
|
||||
NameConstraints *NameConstraints `json:"name_constraints,omitempty"`
|
||||
CRLDistributionPoints CRLDistributionPoints `json:"crl_distribution_points,omitempty"`
|
||||
AuthKeyID SubjAuthKeyId `json:"authority_key_id,omitempty"`
|
||||
SubjectKeyID SubjAuthKeyId `json:"subject_key_id,omitempty"`
|
||||
ExtendedKeyUsage *ExtendedKeyUsageExtension `json:"extended_key_usage,omitempty"`
|
||||
CertificatePolicies *CertificatePoliciesData `json:"certificate_policies,omitempty"`
|
||||
AuthorityInfoAccess *AuthorityInfoAccess `json:"authority_info_access,omitempty"`
|
||||
IsPrecert IsPrecert `json:"ct_poison,omitempty"`
|
||||
SignedCertificateTimestampList []*ct.SignedCertificateTimestamp `json:"signed_certificate_timestamps,omitempty"`
|
||||
TorServiceDescriptors []*TorServiceDescriptorHash `json:"tor_service_descriptors,omitempty"`
|
||||
CABFOrganizationIdentifier *CABFOrganizationIdentifier `json:"cabf_organization_id,omitempty"`
|
||||
QCStatements *QCStatements `json:"qc_statements,omitempty"`
|
||||
}
|
||||
|
||||
type UnknownCertificateExtensions []pkix.Extension
|
||||
|
||||
type IsPrecert bool
|
||||
|
||||
type BasicConstraints struct {
|
||||
IsCA bool `json:"is_ca"`
|
||||
MaxPathLen *int `json:"max_path_len,omitempty"`
|
||||
}
|
||||
|
||||
type NoticeReference struct {
|
||||
Organization string `json:"organization,omitempty"`
|
||||
NoticeNumbers NoticeNumber `json:"notice_numbers,omitempty"`
|
||||
}
|
||||
|
||||
type UserNoticeData struct {
|
||||
ExplicitText string `json:"explicit_text,omitempty"`
|
||||
NoticeReference []NoticeReference `json:"notice_reference,omitempty"`
|
||||
}
|
||||
|
||||
type CertificatePoliciesJSON struct {
|
||||
PolicyIdentifier string `json:"id,omitempty"`
|
||||
CPSUri []string `json:"cps,omitempty"`
|
||||
UserNotice []UserNoticeData `json:"user_notice,omitempty"`
|
||||
}
|
||||
|
||||
type CertificatePolicies []CertificatePoliciesJSON
|
||||
|
||||
type CertificatePoliciesData struct {
|
||||
PolicyIdentifiers []asn1.ObjectIdentifier
|
||||
QualifierId [][]asn1.ObjectIdentifier
|
||||
CPSUri [][]string
|
||||
ExplicitTexts [][]string
|
||||
NoticeRefOrganization [][]string
|
||||
NoticeRefNumbers [][]NoticeNumber
|
||||
}
|
||||
|
||||
func (cp *CertificatePoliciesData) MarshalJSON() ([]byte, error) {
|
||||
policies := CertificatePolicies{}
|
||||
for idx, oid := range cp.PolicyIdentifiers {
|
||||
cpsJSON := CertificatePoliciesJSON{}
|
||||
cpsJSON.PolicyIdentifier = oid.String()
|
||||
for _, uri := range cp.CPSUri[idx] {
|
||||
cpsJSON.CPSUri = append(cpsJSON.CPSUri, uri)
|
||||
}
|
||||
|
||||
for idx2, explicit_text := range cp.ExplicitTexts[idx] {
|
||||
uNoticeData := UserNoticeData{}
|
||||
uNoticeData.ExplicitText = explicit_text
|
||||
noticeRef := NoticeReference{}
|
||||
if len(cp.NoticeRefOrganization[idx]) > 0 {
|
||||
organization := cp.NoticeRefOrganization[idx][idx2]
|
||||
noticeRef.Organization = organization
|
||||
noticeRef.NoticeNumbers = cp.NoticeRefNumbers[idx][idx2]
|
||||
uNoticeData.NoticeReference = append(uNoticeData.NoticeReference, noticeRef)
|
||||
}
|
||||
cpsJSON.UserNotice = append(cpsJSON.UserNotice, uNoticeData)
|
||||
}
|
||||
|
||||
policies = append(policies, cpsJSON)
|
||||
}
|
||||
return json.Marshal(policies)
|
||||
}
|
||||
|
||||
// GeneralNames corresponds an X.509 GeneralName defined in
|
||||
// Section 4.2.1.6 of RFC 5280.
|
||||
//
|
||||
// GeneralName ::= CHOICE {
|
||||
// otherName [0] AnotherName,
|
||||
// rfc822Name [1] IA5String,
|
||||
// dNSName [2] IA5String,
|
||||
// x400Address [3] ORAddress,
|
||||
// directoryName [4] Name,
|
||||
// ediPartyName [5] EDIPartyName,
|
||||
// uniformResourceIdentifier [6] IA5String,
|
||||
// iPAddress [7] OCTET STRING,
|
||||
// registeredID [8] OBJECT IDENTIFIER }
|
||||
type GeneralNames struct {
|
||||
DirectoryNames []pkix.Name
|
||||
DNSNames []string
|
||||
EDIPartyNames []pkix.EDIPartyName
|
||||
EmailAddresses []string
|
||||
IPAddresses []net.IP
|
||||
OtherNames []pkix.OtherName
|
||||
RegisteredIDs []asn1.ObjectIdentifier
|
||||
URIs []string
|
||||
}
|
||||
|
||||
type jsonGeneralNames struct {
|
||||
DirectoryNames []pkix.Name `json:"directory_names,omitempty"`
|
||||
DNSNames []string `json:"dns_names,omitempty"`
|
||||
EDIPartyNames []pkix.EDIPartyName `json:"edi_party_names,omitempty"`
|
||||
EmailAddresses []string `json:"email_addresses,omitempty"`
|
||||
IPAddresses []net.IP `json:"ip_addresses,omitempty"`
|
||||
OtherNames []pkix.OtherName `json:"other_names,omitempty"`
|
||||
RegisteredIDs []string `json:"registered_ids,omitempty"`
|
||||
URIs []string `json:"uniform_resource_identifiers,omitempty"`
|
||||
}
|
||||
|
||||
func (gn *GeneralNames) MarshalJSON() ([]byte, error) {
|
||||
jsan := jsonGeneralNames{
|
||||
DirectoryNames: gn.DirectoryNames,
|
||||
DNSNames: gn.DNSNames,
|
||||
EDIPartyNames: gn.EDIPartyNames,
|
||||
EmailAddresses: gn.EmailAddresses,
|
||||
IPAddresses: gn.IPAddresses,
|
||||
OtherNames: gn.OtherNames,
|
||||
RegisteredIDs: make([]string, 0, len(gn.RegisteredIDs)),
|
||||
URIs: gn.URIs,
|
||||
}
|
||||
for _, id := range gn.RegisteredIDs {
|
||||
jsan.RegisteredIDs = append(jsan.RegisteredIDs, id.String())
|
||||
}
|
||||
return json.Marshal(jsan)
|
||||
}
|
||||
|
||||
func (gn *GeneralNames) UnmarshalJSON(b []byte) error {
|
||||
var jsan jsonGeneralNames
|
||||
err := json.Unmarshal(b, &jsan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gn.DirectoryNames = jsan.DirectoryNames
|
||||
gn.DNSNames = jsan.DNSNames
|
||||
gn.EDIPartyNames = jsan.EDIPartyNames
|
||||
gn.EmailAddresses = jsan.EmailAddresses
|
||||
gn.IPAddresses = jsan.IPAddresses
|
||||
gn.OtherNames = jsan.OtherNames
|
||||
gn.RegisteredIDs = make([]asn1.ObjectIdentifier, len(jsan.RegisteredIDs))
|
||||
gn.URIs = jsan.URIs
|
||||
|
||||
for i, rID := range jsan.RegisteredIDs {
|
||||
arcs := strings.Split(rID, ".")
|
||||
oid := make(asn1.ObjectIdentifier, len(arcs))
|
||||
|
||||
for j, s := range arcs {
|
||||
tmp, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oid[j] = int(tmp)
|
||||
}
|
||||
gn.RegisteredIDs[i] = oid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Handle excluded names
|
||||
|
||||
type NameConstraints struct {
|
||||
Critical bool `json:"critical"`
|
||||
|
||||
PermittedDNSNames []GeneralSubtreeString
|
||||
PermittedEmailAddresses []GeneralSubtreeString
|
||||
PermittedURIs []GeneralSubtreeString
|
||||
PermittedIPAddresses []GeneralSubtreeIP
|
||||
PermittedDirectoryNames []GeneralSubtreeName
|
||||
PermittedEdiPartyNames []GeneralSubtreeEdi
|
||||
PermittedRegisteredIDs []GeneralSubtreeOid
|
||||
|
||||
ExcludedEmailAddresses []GeneralSubtreeString
|
||||
ExcludedDNSNames []GeneralSubtreeString
|
||||
ExcludedURIs []GeneralSubtreeString
|
||||
ExcludedIPAddresses []GeneralSubtreeIP
|
||||
ExcludedDirectoryNames []GeneralSubtreeName
|
||||
ExcludedEdiPartyNames []GeneralSubtreeEdi
|
||||
ExcludedRegisteredIDs []GeneralSubtreeOid
|
||||
}
|
||||
|
||||
type NameConstraintsJSON struct {
|
||||
Critical bool `json:"critical"`
|
||||
|
||||
PermittedDNSNames []string `json:"permitted_names,omitempty"`
|
||||
PermittedEmailAddresses []string `json:"permitted_email_addresses,omitempty"`
|
||||
PermittedURIs []string `json:"permitted_uris,omitempty"`
|
||||
PermittedIPAddresses []GeneralSubtreeIP `json:"permitted_ip_addresses,omitempty"`
|
||||
PermittedDirectoryNames []pkix.Name `json:"permitted_directory_names,omitempty"`
|
||||
PermittedEdiPartyNames []pkix.EDIPartyName `json:"permitted_edi_party_names,omitempty"`
|
||||
PermittedRegisteredIDs []string `json:"permitted_registred_id,omitempty"`
|
||||
|
||||
ExcludedDNSNames []string `json:"excluded_names,omitempty"`
|
||||
ExcludedEmailAddresses []string `json:"excluded_email_addresses,omitempty"`
|
||||
ExcludedURIs []string `json:"excluded_uris,omitempty"`
|
||||
ExcludedIPAddresses []GeneralSubtreeIP `json:"excluded_ip_addresses,omitempty"`
|
||||
ExcludedDirectoryNames []pkix.Name `json:"excluded_directory_names,omitempty"`
|
||||
ExcludedEdiPartyNames []pkix.EDIPartyName `json:"excluded_edi_party_names,omitempty"`
|
||||
ExcludedRegisteredIDs []string `json:"excluded_registred_id,omitempty"`
|
||||
}
|
||||
|
||||
func (nc *NameConstraints) UnmarshalJSON(b []byte) error {
|
||||
var ncJson NameConstraintsJSON
|
||||
err := json.Unmarshal(b, &ncJson)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, dns := range ncJson.PermittedDNSNames {
|
||||
nc.PermittedDNSNames = append(nc.PermittedDNSNames, GeneralSubtreeString{Data: dns})
|
||||
}
|
||||
for _, email := range ncJson.PermittedEmailAddresses {
|
||||
nc.PermittedEmailAddresses = append(nc.PermittedEmailAddresses, GeneralSubtreeString{Data: email})
|
||||
}
|
||||
for _, uri := range ncJson.PermittedURIs {
|
||||
nc.PermittedURIs = append(nc.PermittedURIs, GeneralSubtreeString{Data: uri})
|
||||
}
|
||||
for _, constraint := range ncJson.PermittedIPAddresses {
|
||||
nc.PermittedIPAddresses = append(nc.PermittedIPAddresses, constraint)
|
||||
}
|
||||
for _, directory := range ncJson.PermittedDirectoryNames {
|
||||
nc.PermittedDirectoryNames = append(nc.PermittedDirectoryNames, GeneralSubtreeName{Data: directory})
|
||||
}
|
||||
for _, edi := range ncJson.PermittedEdiPartyNames {
|
||||
nc.PermittedEdiPartyNames = append(nc.PermittedEdiPartyNames, GeneralSubtreeEdi{Data: edi})
|
||||
}
|
||||
for _, id := range ncJson.PermittedRegisteredIDs {
|
||||
arcs := strings.Split(id, ".")
|
||||
oid := make(asn1.ObjectIdentifier, len(arcs))
|
||||
|
||||
for j, s := range arcs {
|
||||
tmp, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oid[j] = int(tmp)
|
||||
}
|
||||
nc.PermittedRegisteredIDs = append(nc.PermittedRegisteredIDs, GeneralSubtreeOid{Data: oid})
|
||||
}
|
||||
|
||||
for _, dns := range ncJson.ExcludedDNSNames {
|
||||
nc.ExcludedDNSNames = append(nc.ExcludedDNSNames, GeneralSubtreeString{Data: dns})
|
||||
}
|
||||
for _, email := range ncJson.ExcludedEmailAddresses {
|
||||
nc.ExcludedEmailAddresses = append(nc.ExcludedEmailAddresses, GeneralSubtreeString{Data: email})
|
||||
}
|
||||
for _, uri := range ncJson.ExcludedURIs {
|
||||
nc.ExcludedURIs = append(nc.ExcludedURIs, GeneralSubtreeString{Data: uri})
|
||||
}
|
||||
for _, constraint := range ncJson.ExcludedIPAddresses {
|
||||
nc.ExcludedIPAddresses = append(nc.ExcludedIPAddresses, constraint)
|
||||
}
|
||||
for _, directory := range ncJson.ExcludedDirectoryNames {
|
||||
nc.ExcludedDirectoryNames = append(nc.ExcludedDirectoryNames, GeneralSubtreeName{Data: directory})
|
||||
}
|
||||
for _, edi := range ncJson.ExcludedEdiPartyNames {
|
||||
nc.ExcludedEdiPartyNames = append(nc.ExcludedEdiPartyNames, GeneralSubtreeEdi{Data: edi})
|
||||
}
|
||||
for _, id := range ncJson.ExcludedRegisteredIDs {
|
||||
arcs := strings.Split(id, ".")
|
||||
oid := make(asn1.ObjectIdentifier, len(arcs))
|
||||
|
||||
for j, s := range arcs {
|
||||
tmp, err := strconv.ParseInt(s, 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
oid[j] = int(tmp)
|
||||
}
|
||||
nc.ExcludedRegisteredIDs = append(nc.ExcludedRegisteredIDs, GeneralSubtreeOid{Data: oid})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nc NameConstraints) MarshalJSON() ([]byte, error) {
|
||||
var out NameConstraintsJSON
|
||||
for _, dns := range nc.PermittedDNSNames {
|
||||
out.PermittedDNSNames = append(out.PermittedDNSNames, dns.Data)
|
||||
}
|
||||
for _, email := range nc.PermittedEmailAddresses {
|
||||
out.PermittedEmailAddresses = append(out.PermittedEmailAddresses, email.Data)
|
||||
}
|
||||
for _, uri := range nc.PermittedURIs {
|
||||
out.PermittedURIs = append(out.PermittedURIs, uri.Data)
|
||||
}
|
||||
out.PermittedIPAddresses = nc.PermittedIPAddresses
|
||||
for _, directory := range nc.PermittedDirectoryNames {
|
||||
out.PermittedDirectoryNames = append(out.PermittedDirectoryNames, directory.Data)
|
||||
}
|
||||
for _, edi := range nc.PermittedEdiPartyNames {
|
||||
out.PermittedEdiPartyNames = append(out.PermittedEdiPartyNames, edi.Data)
|
||||
}
|
||||
for _, id := range nc.PermittedRegisteredIDs {
|
||||
out.PermittedRegisteredIDs = append(out.PermittedRegisteredIDs, id.Data.String())
|
||||
}
|
||||
|
||||
for _, dns := range nc.ExcludedDNSNames {
|
||||
out.ExcludedDNSNames = append(out.ExcludedDNSNames, dns.Data)
|
||||
}
|
||||
for _, email := range nc.ExcludedEmailAddresses {
|
||||
out.ExcludedEmailAddresses = append(out.ExcludedEmailAddresses, email.Data)
|
||||
}
|
||||
for _, uri := range nc.ExcludedURIs {
|
||||
out.ExcludedURIs = append(out.ExcludedURIs, uri.Data)
|
||||
}
|
||||
for _, ip := range nc.ExcludedIPAddresses {
|
||||
out.ExcludedIPAddresses = append(out.ExcludedIPAddresses, ip)
|
||||
}
|
||||
for _, directory := range nc.ExcludedDirectoryNames {
|
||||
out.ExcludedDirectoryNames = append(out.ExcludedDirectoryNames, directory.Data)
|
||||
}
|
||||
for _, edi := range nc.ExcludedEdiPartyNames {
|
||||
out.ExcludedEdiPartyNames = append(out.ExcludedEdiPartyNames, edi.Data)
|
||||
}
|
||||
for _, id := range nc.ExcludedRegisteredIDs {
|
||||
out.ExcludedRegisteredIDs = append(out.ExcludedRegisteredIDs, id.Data.String())
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
type CRLDistributionPoints []string
|
||||
|
||||
type SubjAuthKeyId []byte
|
||||
|
||||
func (kid SubjAuthKeyId) MarshalJSON() ([]byte, error) {
|
||||
enc := hex.EncodeToString(kid)
|
||||
return json.Marshal(enc)
|
||||
}
|
||||
|
||||
type ExtendedKeyUsage []ExtKeyUsage
|
||||
|
||||
type ExtendedKeyUsageExtension struct {
|
||||
Known ExtendedKeyUsage
|
||||
Unknown []asn1.ObjectIdentifier
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshal interface. The output is a struct of
|
||||
// bools, with an additional `Value` field containing the actual OIDs.
|
||||
func (e *ExtendedKeyUsageExtension) MarshalJSON() ([]byte, error) {
|
||||
aux := new(auxExtendedKeyUsage)
|
||||
for _, e := range e.Known {
|
||||
aux.populateFromExtKeyUsage(e)
|
||||
}
|
||||
for _, oid := range e.Unknown {
|
||||
aux.Unknown = append(aux.Unknown, oid.String())
|
||||
}
|
||||
return json.Marshal(aux)
|
||||
}
|
||||
|
||||
func (e *ExtendedKeyUsageExtension) UnmarshalJSON(b []byte) error {
|
||||
aux := new(auxExtendedKeyUsage)
|
||||
if err := json.Unmarshal(b, aux); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: Generate the reverse functions.
|
||||
return nil
|
||||
}
|
||||
|
||||
//go:generate go run extended_key_usage_gen.go
|
||||
|
||||
// The string functions for CertValidationLevel are auto-generated via
|
||||
// `go generate <full_path_to_x509_package>` or running `go generate` in the package directory
|
||||
//go:generate stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go
|
||||
type CertValidationLevel int
|
||||
|
||||
const (
|
||||
UnknownValidationLevel CertValidationLevel = 0
|
||||
DV CertValidationLevel = 1
|
||||
OV CertValidationLevel = 2
|
||||
EV CertValidationLevel = 3
|
||||
)
|
||||
|
||||
func (c *CertValidationLevel) MarshalJSON() ([]byte, error) {
|
||||
if *c == UnknownValidationLevel || *c < 0 || *c > EV {
|
||||
return json.Marshal("unknown")
|
||||
}
|
||||
return json.Marshal(c.String())
|
||||
}
|
||||
|
||||
// TODO: All of validation-level maps should be auto-generated from
|
||||
// https://github.com/zmap/constants.
|
||||
|
||||
// ExtendedValidationOIDs contains the UNION of Chromium
|
||||
// (https://chromium.googlesource.com/chromium/src/net/+/master/cert/ev_root_ca_metadata.cc)
|
||||
// and Firefox
|
||||
// (http://hg.mozilla.org/mozilla-central/file/tip/security/certverifier/ExtendedValidation.cpp)
|
||||
// EV OID lists
|
||||
var ExtendedValidationOIDs = map[string]interface{}{
|
||||
// CA/Browser Forum EV OID standard
|
||||
// https://cabforum.org/object-registry/
|
||||
"2.23.140.1.1": nil,
|
||||
// CA/Browser Forum EV Code Signing
|
||||
"2.23.140.1.3": nil,
|
||||
// CA/Browser Forum .onion EV Certs
|
||||
"2.23.140.1.31": nil,
|
||||
// AC Camerfirma S.A. Chambers of Commerce Root - 2008
|
||||
// https://www.camerfirma.com
|
||||
// AC Camerfirma uses the last two arcs to track how the private key
|
||||
// is managed - the effective verification policy is the same.
|
||||
"1.3.6.1.4.1.17326.10.14.2.1.2": nil,
|
||||
"1.3.6.1.4.1.17326.10.14.2.2.2": nil,
|
||||
// AC Camerfirma S.A. Global Chambersign Root - 2008
|
||||
// https://server2.camerfirma.com:8082
|
||||
// AC Camerfirma uses the last two arcs to track how the private key
|
||||
// is managed - the effective verification policy is the same.
|
||||
"1.3.6.1.4.1.17326.10.8.12.1.2": nil,
|
||||
"1.3.6.1.4.1.17326.10.8.12.2.2": nil,
|
||||
// Actalis Authentication Root CA
|
||||
// https://ssltest-a.actalis.it:8443
|
||||
"1.3.159.1.17.1": nil,
|
||||
// AffirmTrust Commercial
|
||||
// https://commercial.affirmtrust.com/
|
||||
"1.3.6.1.4.1.34697.2.1": nil,
|
||||
// AffirmTrust Networking
|
||||
// https://networking.affirmtrust.com:4431
|
||||
"1.3.6.1.4.1.34697.2.2": nil,
|
||||
// AffirmTrust Premium
|
||||
// https://premium.affirmtrust.com:4432/
|
||||
"1.3.6.1.4.1.34697.2.3": nil,
|
||||
// AffirmTrust Premium ECC
|
||||
// https://premiumecc.affirmtrust.com:4433/
|
||||
"1.3.6.1.4.1.34697.2.4": nil,
|
||||
// Autoridad de Certificacion Firmaprofesional CIF A62634068
|
||||
// https://publifirma.firmaprofesional.com/
|
||||
"1.3.6.1.4.1.13177.10.1.3.10": nil,
|
||||
// Buypass Class 3 CA 1
|
||||
// https://valid.evident.ca13.ssl.buypass.no/
|
||||
"2.16.578.1.26.1.3.3": nil,
|
||||
// Certification Authority of WoSign
|
||||
// CA 沃通根证书
|
||||
// https://root2evtest.wosign.com/
|
||||
"1.3.6.1.4.1.36305.2": nil,
|
||||
// CertPlus Class 2 Primary CA (KEYNECTIS)
|
||||
// https://www.keynectis.com/
|
||||
"1.3.6.1.4.1.22234.2.5.2.3.1": nil,
|
||||
// Certum Trusted Network CA
|
||||
// https://juice.certum.pl/
|
||||
"1.2.616.1.113527.2.5.1.1": nil,
|
||||
// China Internet Network Information Center EV Certificates Root
|
||||
// https://evdemo.cnnic.cn/
|
||||
"1.3.6.1.4.1.29836.1.10": nil,
|
||||
// COMODO Certification Authority & USERTrust RSA Certification Authority & UTN-USERFirst-Hardware & AddTrust External CA Root
|
||||
// https://secure.comodo.com/
|
||||
// https://usertrustrsacertificationauthority-ev.comodoca.com/
|
||||
// https://addtrustexternalcaroot-ev.comodoca.com
|
||||
"1.3.6.1.4.1.6449.1.2.1.5.1": nil,
|
||||
// Cybertrust Global Root & GTE CyberTrust Global Root & Baltimore CyberTrust Root
|
||||
// https://evup.cybertrust.ne.jp/ctj-ev-upgrader/evseal.gif
|
||||
// https://www.cybertrust.ne.jp/
|
||||
// https://secure.omniroot.com/repository/
|
||||
"1.3.6.1.4.1.6334.1.100.1": nil,
|
||||
// DigiCert High Assurance EV Root CA
|
||||
// https://www.digicert.com
|
||||
"2.16.840.1.114412.2.1": nil,
|
||||
// D-TRUST Root Class 3 CA 2 EV 2009
|
||||
// https://certdemo-ev-valid.ssl.d-trust.net/
|
||||
"1.3.6.1.4.1.4788.2.202.1": nil,
|
||||
// Entrust.net Secure Server Certification Authority
|
||||
// https://www.entrust.net/
|
||||
"2.16.840.1.114028.10.1.2": nil,
|
||||
// E-Tugra Certification Authority
|
||||
// https://sslev.e-tugra.com.tr
|
||||
"2.16.792.3.0.4.1.1.4": nil,
|
||||
// GeoTrust Primary Certification Authority
|
||||
// https://www.geotrust.com/
|
||||
"1.3.6.1.4.1.14370.1.6": nil,
|
||||
// GlobalSign Root CA - R2
|
||||
// https://www.globalsign.com/
|
||||
"1.3.6.1.4.1.4146.1.1": nil,
|
||||
// Go Daddy Class 2 Certification Authority & Go Daddy Root Certificate Authority - G2
|
||||
// https://www.godaddy.com/
|
||||
// https://valid.gdig2.catest.godaddy.com/
|
||||
"2.16.840.1.114413.1.7.23.3": nil,
|
||||
// Izenpe.com - SHA256 root
|
||||
// The first OID is for businesses and the second for government entities.
|
||||
// These are the test sites, respectively:
|
||||
// https://servicios.izenpe.com
|
||||
// https://servicios1.izenpe.com
|
||||
// Windows XP finds this, SHA1, root instead. The policy OIDs are the same
|
||||
// as for the SHA256 root, above.
|
||||
"1.3.6.1.4.1.14777.6.1.1": nil,
|
||||
"1.3.6.1.4.1.14777.6.1.2": nil,
|
||||
// Network Solutions Certificate Authority
|
||||
// https://www.networksolutions.com/website-packages/index.jsp
|
||||
"1.3.6.1.4.1.782.1.2.1.8.1": nil,
|
||||
// QuoVadis Root CA 2
|
||||
// https://www.quovadis.bm/
|
||||
"1.3.6.1.4.1.8024.0.2.100.1.2": nil,
|
||||
// SecureTrust CA, SecureTrust Corporation
|
||||
// https://www.securetrust.com
|
||||
// https://www.trustwave.com/
|
||||
"2.16.840.1.114404.1.1.2.4.1": nil,
|
||||
// Security Communication RootCA1
|
||||
// https://www.secomtrust.net/contact/form.html
|
||||
"1.2.392.200091.100.721.1": nil,
|
||||
// Staat der Nederlanden EV Root CA
|
||||
// https://pkioevssl-v.quovadisglobal.com/
|
||||
"2.16.528.1.1003.1.2.7": nil,
|
||||
// StartCom Certification Authority
|
||||
// https://www.startssl.com/
|
||||
"1.3.6.1.4.1.23223.1.1.1": nil,
|
||||
// Starfield Class 2 Certification Authority
|
||||
// https://www.starfieldtech.com/
|
||||
"2.16.840.1.114414.1.7.23.3": nil,
|
||||
// Starfield Services Root Certificate Authority - G2
|
||||
// https://valid.sfsg2.catest.starfieldtech.com/
|
||||
"2.16.840.1.114414.1.7.24.3": nil,
|
||||
// SwissSign Gold CA - G2
|
||||
// https://testevg2.swisssign.net/
|
||||
"2.16.756.1.89.1.2.1.1": nil,
|
||||
// Swisscom Root EV CA 2
|
||||
// https://test-quarz-ev-ca-2.pre.swissdigicert.ch
|
||||
"2.16.756.1.83.21.0": nil,
|
||||
// thawte Primary Root CA
|
||||
// https://www.thawte.com/
|
||||
"2.16.840.1.113733.1.7.48.1": nil,
|
||||
// TWCA Global Root CA
|
||||
// https://evssldemo3.twca.com.tw/index.html
|
||||
"1.3.6.1.4.1.40869.1.1.22.3": nil,
|
||||
// T-TeleSec GlobalRoot Class 3
|
||||
// http://www.telesec.de/ / https://root-class3.test.telesec.de/
|
||||
"1.3.6.1.4.1.7879.13.24.1": nil,
|
||||
// VeriSign Class 3 Public Primary Certification Authority - G5
|
||||
// https://www.verisign.com/
|
||||
"2.16.840.1.113733.1.7.23.6": nil,
|
||||
// Wells Fargo WellsSecure Public Root Certificate Authority
|
||||
// https://nerys.wellsfargo.com/test.html
|
||||
"2.16.840.1.114171.500.9": nil,
|
||||
// CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN
|
||||
// https://www.cfca.com.cn/
|
||||
"2.16.156.112554.3": nil,
|
||||
// CN=OISTE WISeKey Global Root GB CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH
|
||||
// https://www.wisekey.com/repository/cacertificates/
|
||||
"2.16.756.5.14.7.4.8": nil,
|
||||
// CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H6,O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A...,L=Ankara,C=TR
|
||||
// https://www.turktrust.com.tr/
|
||||
"2.16.792.3.0.3.1.1.5": nil,
|
||||
}
|
||||
|
||||
// OrganizationValidationOIDs contains CA specific OV OIDs from
|
||||
// https://cabforum.org/object-registry/
|
||||
var OrganizationValidationOIDs = map[string]interface{}{
|
||||
// CA/Browser Forum OV OID standard
|
||||
// https://cabforum.org/object-registry/
|
||||
"2.23.140.1.2.2": nil,
|
||||
// CA/Browser Forum individually validated
|
||||
"2.23.140.1.2.3": nil,
|
||||
// Digicert
|
||||
"2.16.840.1.114412.1.1": nil,
|
||||
// D-Trust
|
||||
"1.3.6.1.4.1.4788.2.200.1": nil,
|
||||
// GoDaddy
|
||||
"2.16.840.1.114413.1.7.23.2": nil,
|
||||
// Logius
|
||||
"2.16.528.1.1003.1.2.5.6": nil,
|
||||
// QuoVadis
|
||||
"1.3.6.1.4.1.8024.0.2.100.1.1": nil,
|
||||
// Starfield
|
||||
"2.16.840.1.114414.1.7.23.2": nil,
|
||||
// TurkTrust
|
||||
"2.16.792.3.0.3.1.1.2": nil,
|
||||
}
|
||||
|
||||
// DomainValidationOIDs contain OIDs that identify DV certs.
|
||||
var DomainValidationOIDs = map[string]interface{}{
|
||||
// Globalsign
|
||||
"1.3.6.1.4.1.4146.1.10.10": nil,
|
||||
// Let's Encrypt
|
||||
"1.3.6.1.4.1.44947.1.1.1": nil,
|
||||
// Comodo (eNom)
|
||||
"1.3.6.1.4.1.6449.1.2.2.10": nil,
|
||||
// Comodo (WoTrust)
|
||||
"1.3.6.1.4.1.6449.1.2.2.15": nil,
|
||||
// Comodo (RBC SOFT)
|
||||
"1.3.6.1.4.1.6449.1.2.2.16": nil,
|
||||
// Comodo (RegisterFly)
|
||||
"1.3.6.1.4.1.6449.1.2.2.17": nil,
|
||||
// Comodo (Central Security Patrols)
|
||||
"1.3.6.1.4.1.6449.1.2.2.18": nil,
|
||||
// Comodo (eBiz Networks)
|
||||
"1.3.6.1.4.1.6449.1.2.2.19": nil,
|
||||
// Comodo (OptimumSSL)
|
||||
"1.3.6.1.4.1.6449.1.2.2.21": nil,
|
||||
// Comodo (WoSign)
|
||||
"1.3.6.1.4.1.6449.1.2.2.22": nil,
|
||||
// Comodo (Register.com)
|
||||
"1.3.6.1.4.1.6449.1.2.2.24": nil,
|
||||
// Comodo (The Code Project)
|
||||
"1.3.6.1.4.1.6449.1.2.2.25": nil,
|
||||
// Comodo (Gandi)
|
||||
"1.3.6.1.4.1.6449.1.2.2.26": nil,
|
||||
// Comodo (GlobeSSL)
|
||||
"1.3.6.1.4.1.6449.1.2.2.27": nil,
|
||||
// Comodo (DreamHost)
|
||||
"1.3.6.1.4.1.6449.1.2.2.28": nil,
|
||||
// Comodo (TERENA)
|
||||
"1.3.6.1.4.1.6449.1.2.2.29": nil,
|
||||
// Comodo (GlobalSSL)
|
||||
"1.3.6.1.4.1.6449.1.2.2.31": nil,
|
||||
// Comodo (IceWarp)
|
||||
"1.3.6.1.4.1.6449.1.2.2.35": nil,
|
||||
// Comodo (Dotname Korea)
|
||||
"1.3.6.1.4.1.6449.1.2.2.37": nil,
|
||||
// Comodo (TrustSign)
|
||||
"1.3.6.1.4.1.6449.1.2.2.38": nil,
|
||||
// Comodo (Formidable)
|
||||
"1.3.6.1.4.1.6449.1.2.2.39": nil,
|
||||
// Comodo (SSL Blindado)
|
||||
"1.3.6.1.4.1.6449.1.2.2.40": nil,
|
||||
// Comodo (Dreamscape Networks)
|
||||
"1.3.6.1.4.1.6449.1.2.2.41": nil,
|
||||
// Comodo (K Software)
|
||||
"1.3.6.1.4.1.6449.1.2.2.42": nil,
|
||||
// Comodo (FBS)
|
||||
"1.3.6.1.4.1.6449.1.2.2.44": nil,
|
||||
// Comodo (ReliaSite)
|
||||
"1.3.6.1.4.1.6449.1.2.2.45": nil,
|
||||
// Comodo (CertAssure)
|
||||
"1.3.6.1.4.1.6449.1.2.2.47": nil,
|
||||
// Comodo (TrustAsia)
|
||||
"1.3.6.1.4.1.6449.1.2.2.49": nil,
|
||||
// Comodo (SecureCore)
|
||||
"1.3.6.1.4.1.6449.1.2.2.50": nil,
|
||||
// Comodo (Western Digital)
|
||||
"1.3.6.1.4.1.6449.1.2.2.51": nil,
|
||||
// Comodo (cPanel)
|
||||
"1.3.6.1.4.1.6449.1.2.2.52": nil,
|
||||
// Comodo (BlackCert)
|
||||
"1.3.6.1.4.1.6449.1.2.2.53": nil,
|
||||
// Comodo (KeyNet Systems)
|
||||
"1.3.6.1.4.1.6449.1.2.2.54": nil,
|
||||
// Comodo
|
||||
"1.3.6.1.4.1.6449.1.2.2.7": nil,
|
||||
// Comodo (CSC)
|
||||
"1.3.6.1.4.1.6449.1.2.2.8": nil,
|
||||
// Digicert
|
||||
"2.16.840.1.114412.1.2": nil,
|
||||
// GoDaddy
|
||||
"2.16.840.1.114413.1.7.23.1": nil,
|
||||
// Starfield
|
||||
"2.16.840.1.114414.1.7.23.1": nil,
|
||||
// CA/B Forum
|
||||
"2.23.140.1.2.1": nil,
|
||||
}
|
||||
|
||||
// TODO pull out other types
|
||||
type AuthorityInfoAccess struct {
|
||||
OCSPServer []string `json:"ocsp_urls,omitempty"`
|
||||
IssuingCertificateURL []string `json:"issuer_urls,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
id-CABFOrganizationIdentifier OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) international-organizations(23) ca-browser-forum(140) certificate-extensions(3) cabf-organization-identifier(1) }
|
||||
|
||||
ext-CABFOrganizationIdentifier EXTENSION ::= { SYNTAX CABFOrganizationIdentifier IDENTIFIED BY id-CABFOrganizationIdentifier }
|
||||
|
||||
CABFOrganizationIdentifier ::= SEQUENCE {
|
||||
|
||||
registrationSchemeIdentifier PrintableString (SIZE(3)),
|
||||
|
||||
registrationCountry PrintableString (SIZE(2)),
|
||||
|
||||
registrationStateOrProvince [0] IMPLICIT PrintableString OPTIONAL (SIZE(0..128)),
|
||||
|
||||
registrationReference UTF8String
|
||||
|
||||
}
|
||||
*/
|
||||
type CABFOrganizationIDASN struct {
|
||||
RegistrationSchemeIdentifier string `asn1:"printable"`
|
||||
RegistrationCountry string `asn1:"printable"`
|
||||
RegistrationStateOrProvince string `asn1:"printable,optional,tag:0"`
|
||||
RegistrationReference string `asn1:"utf8"`
|
||||
}
|
||||
|
||||
type CABFOrganizationIdentifier struct {
|
||||
Scheme string `json:"scheme,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Reference string `json:"reference,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Certificate) jsonifyExtensions() (*CertificateExtensions, UnknownCertificateExtensions) {
|
||||
exts := new(CertificateExtensions)
|
||||
unk := make([]pkix.Extension, 0, 2)
|
||||
for _, e := range c.Extensions {
|
||||
if e.Id.Equal(oidExtKeyUsage) {
|
||||
exts.KeyUsage = c.KeyUsage
|
||||
} else if e.Id.Equal(oidExtBasicConstraints) {
|
||||
exts.BasicConstraints = new(BasicConstraints)
|
||||
exts.BasicConstraints.IsCA = c.IsCA
|
||||
if c.MaxPathLen > 0 || c.MaxPathLenZero {
|
||||
exts.BasicConstraints.MaxPathLen = new(int)
|
||||
*exts.BasicConstraints.MaxPathLen = c.MaxPathLen
|
||||
}
|
||||
} else if e.Id.Equal(oidExtSubjectAltName) {
|
||||
exts.SubjectAltName = new(GeneralNames)
|
||||
exts.SubjectAltName.DirectoryNames = c.DirectoryNames
|
||||
exts.SubjectAltName.DNSNames = c.DNSNames
|
||||
exts.SubjectAltName.EDIPartyNames = c.EDIPartyNames
|
||||
exts.SubjectAltName.EmailAddresses = c.EmailAddresses
|
||||
exts.SubjectAltName.IPAddresses = c.IPAddresses
|
||||
exts.SubjectAltName.OtherNames = c.OtherNames
|
||||
exts.SubjectAltName.RegisteredIDs = c.RegisteredIDs
|
||||
exts.SubjectAltName.URIs = c.URIs
|
||||
} else if e.Id.Equal(oidExtIssuerAltName) {
|
||||
exts.IssuerAltName = new(GeneralNames)
|
||||
exts.IssuerAltName.DirectoryNames = c.IANDirectoryNames
|
||||
exts.IssuerAltName.DNSNames = c.IANDNSNames
|
||||
exts.IssuerAltName.EDIPartyNames = c.IANEDIPartyNames
|
||||
exts.IssuerAltName.EmailAddresses = c.IANEmailAddresses
|
||||
exts.IssuerAltName.IPAddresses = c.IANIPAddresses
|
||||
exts.IssuerAltName.OtherNames = c.IANOtherNames
|
||||
exts.IssuerAltName.RegisteredIDs = c.IANRegisteredIDs
|
||||
exts.IssuerAltName.URIs = c.IANURIs
|
||||
} else if e.Id.Equal(oidExtNameConstraints) {
|
||||
exts.NameConstraints = new(NameConstraints)
|
||||
exts.NameConstraints.Critical = c.NameConstraintsCritical
|
||||
|
||||
exts.NameConstraints.PermittedDNSNames = c.PermittedDNSNames
|
||||
exts.NameConstraints.PermittedEmailAddresses = c.PermittedEmailAddresses
|
||||
exts.NameConstraints.PermittedURIs = c.PermittedURIs
|
||||
exts.NameConstraints.PermittedIPAddresses = c.PermittedIPAddresses
|
||||
exts.NameConstraints.PermittedDirectoryNames = c.PermittedDirectoryNames
|
||||
exts.NameConstraints.PermittedEdiPartyNames = c.PermittedEdiPartyNames
|
||||
exts.NameConstraints.PermittedRegisteredIDs = c.PermittedRegisteredIDs
|
||||
|
||||
exts.NameConstraints.ExcludedEmailAddresses = c.ExcludedEmailAddresses
|
||||
exts.NameConstraints.ExcludedDNSNames = c.ExcludedDNSNames
|
||||
exts.NameConstraints.ExcludedURIs = c.ExcludedURIs
|
||||
exts.NameConstraints.ExcludedIPAddresses = c.ExcludedIPAddresses
|
||||
exts.NameConstraints.ExcludedDirectoryNames = c.ExcludedDirectoryNames
|
||||
exts.NameConstraints.ExcludedEdiPartyNames = c.ExcludedEdiPartyNames
|
||||
exts.NameConstraints.ExcludedRegisteredIDs = c.ExcludedRegisteredIDs
|
||||
} else if e.Id.Equal(oidCRLDistributionPoints) {
|
||||
exts.CRLDistributionPoints = c.CRLDistributionPoints
|
||||
} else if e.Id.Equal(oidExtAuthKeyId) {
|
||||
exts.AuthKeyID = c.AuthorityKeyId
|
||||
} else if e.Id.Equal(oidExtExtendedKeyUsage) {
|
||||
exts.ExtendedKeyUsage = new(ExtendedKeyUsageExtension)
|
||||
exts.ExtendedKeyUsage.Known = c.ExtKeyUsage
|
||||
exts.ExtendedKeyUsage.Unknown = c.UnknownExtKeyUsage
|
||||
} else if e.Id.Equal(oidExtCertificatePolicy) {
|
||||
exts.CertificatePolicies = new(CertificatePoliciesData)
|
||||
exts.CertificatePolicies.PolicyIdentifiers = c.PolicyIdentifiers
|
||||
exts.CertificatePolicies.NoticeRefNumbers = c.NoticeRefNumbers
|
||||
exts.CertificatePolicies.NoticeRefOrganization = c.ParsedNoticeRefOrganization
|
||||
exts.CertificatePolicies.ExplicitTexts = c.ParsedExplicitTexts
|
||||
exts.CertificatePolicies.QualifierId = c.QualifierId
|
||||
exts.CertificatePolicies.CPSUri = c.CPSuri
|
||||
|
||||
} else if e.Id.Equal(oidExtAuthorityInfoAccess) {
|
||||
exts.AuthorityInfoAccess = new(AuthorityInfoAccess)
|
||||
exts.AuthorityInfoAccess.OCSPServer = c.OCSPServer
|
||||
exts.AuthorityInfoAccess.IssuingCertificateURL = c.IssuingCertificateURL
|
||||
} else if e.Id.Equal(oidExtSubjectKeyId) {
|
||||
exts.SubjectKeyID = c.SubjectKeyId
|
||||
} else if e.Id.Equal(oidExtSignedCertificateTimestampList) {
|
||||
exts.SignedCertificateTimestampList = c.SignedCertificateTimestampList
|
||||
} else if e.Id.Equal(oidExtensionCTPrecertificatePoison) {
|
||||
exts.IsPrecert = true
|
||||
} else if e.Id.Equal(oidBRTorServiceDescriptor) {
|
||||
exts.TorServiceDescriptors = c.TorServiceDescriptors
|
||||
} else if e.Id.Equal(oidExtCABFOrganizationID) {
|
||||
exts.CABFOrganizationIdentifier = c.CABFOrganizationIdentifier
|
||||
} else if e.Id.Equal(oidExtQCStatements) {
|
||||
exts.QCStatements = c.QCStatements
|
||||
} else {
|
||||
// Unknown extension
|
||||
unk = append(unk, e)
|
||||
}
|
||||
}
|
||||
return exts, unk
|
||||
}
|
61
vendor/github.com/zmap/zcrypto/x509/fingerprint.go
generated
vendored
Normal file
61
vendor/github.com/zmap/zcrypto/x509/fingerprint.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// CertificateFingerprint represents a digest/fingerprint of some data. It can
|
||||
// easily be encoded to hex and JSON (as a hex string).
|
||||
type CertificateFingerprint []byte
|
||||
|
||||
// MD5Fingerprint creates a fingerprint of data using the MD5 hash algorithm.
|
||||
func MD5Fingerprint(data []byte) CertificateFingerprint {
|
||||
sum := md5.Sum(data)
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
// SHA1Fingerprint creates a fingerprint of data using the SHA1 hash algorithm.
|
||||
func SHA1Fingerprint(data []byte) CertificateFingerprint {
|
||||
sum := sha1.Sum(data)
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
// SHA256Fingerprint creates a fingerprint of data using the SHA256 hash
|
||||
// algorithm.
|
||||
func SHA256Fingerprint(data []byte) CertificateFingerprint {
|
||||
sum := sha256.Sum256(data)
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
// SHA512Fingerprint creates a fingerprint of data using the SHA256 hash
|
||||
// algorithm.
|
||||
func SHA512Fingerprint(data []byte) CertificateFingerprint {
|
||||
sum := sha512.Sum512(data)
|
||||
return sum[:]
|
||||
}
|
||||
|
||||
// Equal returns true if the fingerprints are bytewise-equal.
|
||||
func (f CertificateFingerprint) Equal(other CertificateFingerprint) bool {
|
||||
return bytes.Equal(f, other)
|
||||
}
|
||||
|
||||
// Hex returns the given fingerprint encoded as a hex string.
|
||||
func (f CertificateFingerprint) Hex() string {
|
||||
return hex.EncodeToString(f)
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface, and marshals the
|
||||
// fingerprint as a hex string.
|
||||
func (f *CertificateFingerprint) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(f.Hex())
|
||||
}
|
16
vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go
generated
vendored
Normal file
16
vendor/github.com/zmap/zcrypto/x509/generated_certvalidationlevel_string.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Code generated by "stringer -type=CertValidationLevel -output=generated_certvalidationlevel_string.go"; DO NOT EDIT.
|
||||
|
||||
package x509
|
||||
|
||||
import "strconv"
|
||||
|
||||
const _CertValidationLevel_name = "UnknownValidationLevelDVOVEV"
|
||||
|
||||
var _CertValidationLevel_index = [...]uint8{0, 22, 24, 26, 28}
|
||||
|
||||
func (i CertValidationLevel) String() string {
|
||||
if i < 0 || i >= CertValidationLevel(len(_CertValidationLevel_index)-1) {
|
||||
return "CertValidationLevel(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||
}
|
||||
return _CertValidationLevel_name[_CertValidationLevel_index[i]:_CertValidationLevel_index[i+1]]
|
||||
}
|
652
vendor/github.com/zmap/zcrypto/x509/json.go
generated
vendored
Normal file
652
vendor/github.com/zmap/zcrypto/x509/json.go
generated
vendored
Normal file
|
@ -0,0 +1,652 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"encoding/asn1"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
"github.com/zmap/zcrypto/dsa"
|
||||
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
jsonKeys "github.com/zmap/zcrypto/json"
|
||||
"github.com/zmap/zcrypto/util"
|
||||
"github.com/zmap/zcrypto/x509/pkix"
|
||||
)
|
||||
|
||||
var kMinTime, kMaxTime time.Time
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
kMinTime, err = time.Parse(time.RFC3339, "1970-01-01T00:00:00Z")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
kMaxTime, err = time.Parse(time.RFC3339, "9999-12-31T23:59:59Z")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type auxKeyUsage struct {
|
||||
DigitalSignature bool `json:"digital_signature,omitempty"`
|
||||
ContentCommitment bool `json:"content_commitment,omitempty"`
|
||||
KeyEncipherment bool `json:"key_encipherment,omitempty"`
|
||||
DataEncipherment bool `json:"data_encipherment,omitempty"`
|
||||
KeyAgreement bool `json:"key_agreement,omitempty"`
|
||||
CertificateSign bool `json:"certificate_sign,omitempty"`
|
||||
CRLSign bool `json:"crl_sign,omitempty"`
|
||||
EncipherOnly bool `json:"encipher_only,omitempty"`
|
||||
DecipherOnly bool `json:"decipher_only,omitempty"`
|
||||
Value uint32 `json:"value"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (k KeyUsage) MarshalJSON() ([]byte, error) {
|
||||
var enc auxKeyUsage
|
||||
enc.Value = uint32(k)
|
||||
if k&KeyUsageDigitalSignature > 0 {
|
||||
enc.DigitalSignature = true
|
||||
}
|
||||
if k&KeyUsageContentCommitment > 0 {
|
||||
enc.ContentCommitment = true
|
||||
}
|
||||
if k&KeyUsageKeyEncipherment > 0 {
|
||||
enc.KeyEncipherment = true
|
||||
}
|
||||
if k&KeyUsageDataEncipherment > 0 {
|
||||
enc.DataEncipherment = true
|
||||
}
|
||||
if k&KeyUsageKeyAgreement > 0 {
|
||||
enc.KeyAgreement = true
|
||||
}
|
||||
if k&KeyUsageCertSign > 0 {
|
||||
enc.CertificateSign = true
|
||||
}
|
||||
if k&KeyUsageCRLSign > 0 {
|
||||
enc.CRLSign = true
|
||||
}
|
||||
if k&KeyUsageEncipherOnly > 0 {
|
||||
enc.EncipherOnly = true
|
||||
}
|
||||
if k&KeyUsageDecipherOnly > 0 {
|
||||
enc.DecipherOnly = true
|
||||
}
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshler interface
|
||||
func (k *KeyUsage) UnmarshalJSON(b []byte) error {
|
||||
var aux auxKeyUsage
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: validate the flags match
|
||||
v := int(aux.Value)
|
||||
*k = KeyUsage(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// JSONSignatureAlgorithm is the intermediate type
|
||||
// used when marshaling a PublicKeyAlgorithm out to JSON.
|
||||
type JSONSignatureAlgorithm struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
OID pkix.AuxOID `json:"oid"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
// MAY NOT PRESERVE ORIGINAL OID FROM CERTIFICATE -
|
||||
// CONSIDER USING jsonifySignatureAlgorithm INSTEAD!
|
||||
func (s *SignatureAlgorithm) MarshalJSON() ([]byte, error) {
|
||||
aux := JSONSignatureAlgorithm{
|
||||
Name: s.String(),
|
||||
}
|
||||
for _, val := range signatureAlgorithmDetails {
|
||||
if val.algo == *s {
|
||||
aux.OID = make([]int, len(val.oid))
|
||||
for idx := range val.oid {
|
||||
aux.OID[idx] = val.oid[idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshler interface
|
||||
func (s *SignatureAlgorithm) UnmarshalJSON(b []byte) error {
|
||||
var aux JSONSignatureAlgorithm
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
*s = UnknownSignatureAlgorithm
|
||||
oid := asn1.ObjectIdentifier(aux.OID.AsSlice())
|
||||
if oid.Equal(oidSignatureRSAPSS) {
|
||||
pssAlgs := []SignatureAlgorithm{SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS}
|
||||
for _, alg := range pssAlgs {
|
||||
if strings.Compare(alg.String(), aux.Name) == 0 {
|
||||
*s = alg
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, val := range signatureAlgorithmDetails {
|
||||
if val.oid.Equal(oid) {
|
||||
*s = val.algo
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// jsonifySignatureAlgorithm gathers the necessary fields in a Certificate
|
||||
// into a JSONSignatureAlgorithm, which can then use the default
|
||||
// JSON marhsalers and unmarshalers. THIS FUNCTION IS PREFERED OVER
|
||||
// THE CUSTOM JSON MARSHALER PRESENTED ABOVE FOR SIGNATUREALGORITHM
|
||||
// BECAUSE THIS METHOD PRESERVES THE OID ORIGINALLY IN THE CERTIFICATE!
|
||||
// This reason also explains why we need this function -
|
||||
// the OID is unfortunately stored outside the scope of a
|
||||
// SignatureAlgorithm struct and cannot be recovered without access to the
|
||||
// entire Certificate if we do not know the signature algorithm.
|
||||
func (c *Certificate) jsonifySignatureAlgorithm() JSONSignatureAlgorithm {
|
||||
aux := JSONSignatureAlgorithm{}
|
||||
if c.SignatureAlgorithm == 0 {
|
||||
aux.Name = "unknown_algorithm"
|
||||
} else {
|
||||
aux.Name = c.SignatureAlgorithm.String()
|
||||
}
|
||||
aux.OID = make([]int, len(c.SignatureAlgorithmOID))
|
||||
for idx := range c.SignatureAlgorithmOID {
|
||||
aux.OID[idx] = c.SignatureAlgorithmOID[idx]
|
||||
}
|
||||
return aux
|
||||
}
|
||||
|
||||
type auxPublicKeyAlgorithm struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
OID *pkix.AuxOID `json:"oid,omitempty"`
|
||||
}
|
||||
|
||||
var publicKeyNameToAlgorithm = map[string]PublicKeyAlgorithm{
|
||||
"RSA": RSA,
|
||||
"DSA": DSA,
|
||||
"ECDSA": ECDSA,
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (p *PublicKeyAlgorithm) MarshalJSON() ([]byte, error) {
|
||||
aux := auxPublicKeyAlgorithm{
|
||||
Name: p.String(),
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (p *PublicKeyAlgorithm) UnmarshalJSON(b []byte) error {
|
||||
var aux auxPublicKeyAlgorithm
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
*p = publicKeyNameToAlgorithm[aux.Name]
|
||||
return nil
|
||||
}
|
||||
|
||||
func clampTime(t time.Time) time.Time {
|
||||
if t.Before(kMinTime) {
|
||||
return kMinTime
|
||||
}
|
||||
if t.After(kMaxTime) {
|
||||
return kMaxTime
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
type auxValidity struct {
|
||||
Start string `json:"start"`
|
||||
End string `json:"end"`
|
||||
ValidityPeriod int `json:"length"`
|
||||
}
|
||||
|
||||
func (v *validity) MarshalJSON() ([]byte, error) {
|
||||
aux := auxValidity{
|
||||
Start: clampTime(v.NotBefore.UTC()).Format(time.RFC3339),
|
||||
End: clampTime(v.NotAfter.UTC()).Format(time.RFC3339),
|
||||
ValidityPeriod: int(v.NotAfter.Sub(v.NotBefore).Seconds()),
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
func (v *validity) UnmarshalJSON(b []byte) error {
|
||||
var aux auxValidity
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
var err error
|
||||
if v.NotBefore, err = time.Parse(time.RFC3339, aux.Start); err != nil {
|
||||
return err
|
||||
}
|
||||
if v.NotAfter, err = time.Parse(time.RFC3339, aux.End); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ECDSAPublicKeyJSON - used to condense several fields from a
|
||||
// ECDSA public key into one field for use in JSONCertificate.
|
||||
// Uses default JSON marshal and unmarshal methods
|
||||
type ECDSAPublicKeyJSON struct {
|
||||
B []byte `json:"b"`
|
||||
Curve string `json:"curve"`
|
||||
Gx []byte `json:"gx"`
|
||||
Gy []byte `json:"gy"`
|
||||
Length int `json:"length"`
|
||||
N []byte `json:"n"`
|
||||
P []byte `json:"p"`
|
||||
Pub []byte `json:"pub,omitempty"`
|
||||
X []byte `json:"x"`
|
||||
Y []byte `json:"y"`
|
||||
}
|
||||
|
||||
// DSAPublicKeyJSON - used to condense several fields from a
|
||||
// DSA public key into one field for use in JSONCertificate.
|
||||
// Uses default JSON marshal and unmarshal methods
|
||||
type DSAPublicKeyJSON struct {
|
||||
G []byte `json:"g"`
|
||||
P []byte `json:"p"`
|
||||
Q []byte `json:"q"`
|
||||
Y []byte `json:"y"`
|
||||
}
|
||||
|
||||
// GetDSAPublicKeyJSON - get the DSAPublicKeyJSON for the given standard DSA PublicKey.
|
||||
func GetDSAPublicKeyJSON(key *dsa.PublicKey) *DSAPublicKeyJSON {
|
||||
return &DSAPublicKeyJSON{
|
||||
P: key.P.Bytes(),
|
||||
Q: key.Q.Bytes(),
|
||||
G: key.G.Bytes(),
|
||||
Y: key.Y.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
// GetRSAPublicKeyJSON - get the jsonKeys.RSAPublicKey for the given standard RSA PublicKey.
|
||||
func GetRSAPublicKeyJSON(key *rsa.PublicKey) *jsonKeys.RSAPublicKey {
|
||||
rsaKey := new(jsonKeys.RSAPublicKey)
|
||||
rsaKey.PublicKey = key
|
||||
return rsaKey
|
||||
}
|
||||
|
||||
// GetECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given standard ECDSA PublicKey.
|
||||
func GetECDSAPublicKeyJSON(key *ecdsa.PublicKey) *ECDSAPublicKeyJSON {
|
||||
params := key.Params()
|
||||
return &ECDSAPublicKeyJSON{
|
||||
P: params.P.Bytes(),
|
||||
N: params.N.Bytes(),
|
||||
B: params.B.Bytes(),
|
||||
Gx: params.Gx.Bytes(),
|
||||
Gy: params.Gy.Bytes(),
|
||||
X: key.X.Bytes(),
|
||||
Y: key.Y.Bytes(),
|
||||
Curve: key.Curve.Params().Name,
|
||||
Length: key.Curve.Params().BitSize,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAugmentedECDSAPublicKeyJSON - get the GetECDSAPublicKeyJSON for the given "augmented"
|
||||
// ECDSA PublicKey.
|
||||
func GetAugmentedECDSAPublicKeyJSON(key *AugmentedECDSA) *ECDSAPublicKeyJSON {
|
||||
params := key.Pub.Params()
|
||||
return &ECDSAPublicKeyJSON{
|
||||
P: params.P.Bytes(),
|
||||
N: params.N.Bytes(),
|
||||
B: params.B.Bytes(),
|
||||
Gx: params.Gx.Bytes(),
|
||||
Gy: params.Gy.Bytes(),
|
||||
X: key.Pub.X.Bytes(),
|
||||
Y: key.Pub.Y.Bytes(),
|
||||
Curve: key.Pub.Curve.Params().Name,
|
||||
Length: key.Pub.Curve.Params().BitSize,
|
||||
Pub: key.Raw.Bytes,
|
||||
}
|
||||
}
|
||||
|
||||
// jsonifySubjectKey - Convert public key data in a Certificate
|
||||
// into json output format for JSONCertificate
|
||||
func (c *Certificate) jsonifySubjectKey() JSONSubjectKeyInfo {
|
||||
j := JSONSubjectKeyInfo{
|
||||
KeyAlgorithm: c.PublicKeyAlgorithm,
|
||||
SPKIFingerprint: c.SPKIFingerprint,
|
||||
}
|
||||
|
||||
switch key := c.PublicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
rsaKey := new(jsonKeys.RSAPublicKey)
|
||||
rsaKey.PublicKey = key
|
||||
j.RSAPublicKey = rsaKey
|
||||
case *dsa.PublicKey:
|
||||
j.DSAPublicKey = &DSAPublicKeyJSON{
|
||||
P: key.P.Bytes(),
|
||||
Q: key.Q.Bytes(),
|
||||
G: key.G.Bytes(),
|
||||
Y: key.Y.Bytes(),
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
params := key.Params()
|
||||
j.ECDSAPublicKey = &ECDSAPublicKeyJSON{
|
||||
P: params.P.Bytes(),
|
||||
N: params.N.Bytes(),
|
||||
B: params.B.Bytes(),
|
||||
Gx: params.Gx.Bytes(),
|
||||
Gy: params.Gy.Bytes(),
|
||||
X: key.X.Bytes(),
|
||||
Y: key.Y.Bytes(),
|
||||
Curve: key.Curve.Params().Name,
|
||||
Length: key.Curve.Params().BitSize,
|
||||
}
|
||||
case *AugmentedECDSA:
|
||||
params := key.Pub.Params()
|
||||
j.ECDSAPublicKey = &ECDSAPublicKeyJSON{
|
||||
P: params.P.Bytes(),
|
||||
N: params.N.Bytes(),
|
||||
B: params.B.Bytes(),
|
||||
Gx: params.Gx.Bytes(),
|
||||
Gy: params.Gy.Bytes(),
|
||||
X: key.Pub.X.Bytes(),
|
||||
Y: key.Pub.Y.Bytes(),
|
||||
Curve: key.Pub.Curve.Params().Name,
|
||||
Length: key.Pub.Curve.Params().BitSize,
|
||||
Pub: key.Raw.Bytes,
|
||||
}
|
||||
}
|
||||
return j
|
||||
}
|
||||
|
||||
// JSONSubjectKeyInfo - used to condense several fields from x509.Certificate
|
||||
// related to the subject public key into one field within JSONCertificate
|
||||
// Unfortunately, this struct cannot have its own Marshal method since it
|
||||
// needs information from multiple fields in x509.Certificate
|
||||
type JSONSubjectKeyInfo struct {
|
||||
KeyAlgorithm PublicKeyAlgorithm `json:"key_algorithm"`
|
||||
RSAPublicKey *jsonKeys.RSAPublicKey `json:"rsa_public_key,omitempty"`
|
||||
DSAPublicKey *DSAPublicKeyJSON `json:"dsa_public_key,omitempty"`
|
||||
ECDSAPublicKey *ECDSAPublicKeyJSON `json:"ecdsa_public_key,omitempty"`
|
||||
SPKIFingerprint CertificateFingerprint `json:"fingerprint_sha256"`
|
||||
}
|
||||
|
||||
// JSONSignature - used to condense several fields from x509.Certificate
|
||||
// related to the signature into one field within JSONCertificate
|
||||
// Unfortunately, this struct cannot have its own Marshal method since it
|
||||
// needs information from multiple fields in x509.Certificate
|
||||
type JSONSignature struct {
|
||||
SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"`
|
||||
Value []byte `json:"value"`
|
||||
Valid bool `json:"valid"`
|
||||
SelfSigned bool `json:"self_signed"`
|
||||
}
|
||||
|
||||
// JSONValidity - used to condense several fields related
|
||||
// to validity in x509.Certificate into one field within JSONCertificate
|
||||
// Unfortunately, this struct cannot have its own Marshal method since it
|
||||
// needs information from multiple fields in x509.Certificate
|
||||
type JSONValidity struct {
|
||||
validity
|
||||
ValidityPeriod int
|
||||
}
|
||||
|
||||
// JSONCertificate - used to condense data from x509.Certificate when marhsaling
|
||||
// into JSON. This struct has a distinct and independent layout from
|
||||
// x509.Certificate, mostly for condensing data across repetitive
|
||||
// fields and making it more presentable.
|
||||
type JSONCertificate struct {
|
||||
Version int `json:"version"`
|
||||
SerialNumber string `json:"serial_number"`
|
||||
SignatureAlgorithm JSONSignatureAlgorithm `json:"signature_algorithm"`
|
||||
Issuer pkix.Name `json:"issuer"`
|
||||
IssuerDN string `json:"issuer_dn,omitempty"`
|
||||
Validity JSONValidity `json:"validity"`
|
||||
Subject pkix.Name `json:"subject"`
|
||||
SubjectDN string `json:"subject_dn,omitempty"`
|
||||
SubjectKeyInfo JSONSubjectKeyInfo `json:"subject_key_info"`
|
||||
Extensions *CertificateExtensions `json:"extensions,omitempty"`
|
||||
UnknownExtensions UnknownCertificateExtensions `json:"unknown_extensions,omitempty"`
|
||||
Signature JSONSignature `json:"signature"`
|
||||
FingerprintMD5 CertificateFingerprint `json:"fingerprint_md5"`
|
||||
FingerprintSHA1 CertificateFingerprint `json:"fingerprint_sha1"`
|
||||
FingerprintSHA256 CertificateFingerprint `json:"fingerprint_sha256"`
|
||||
FingerprintNoCT CertificateFingerprint `json:"tbs_noct_fingerprint"`
|
||||
SPKISubjectFingerprint CertificateFingerprint `json:"spki_subject_fingerprint"`
|
||||
TBSCertificateFingerprint CertificateFingerprint `json:"tbs_fingerprint"`
|
||||
ValidationLevel CertValidationLevel `json:"validation_level"`
|
||||
Names []string `json:"names,omitempty"`
|
||||
Redacted bool `json:"redacted"`
|
||||
}
|
||||
|
||||
// CollectAllNames - Collect and validate all DNS / URI / IP Address names for a given certificate
|
||||
func (c *Certificate) CollectAllNames() []string {
|
||||
var names []string
|
||||
|
||||
if isValidName(c.Subject.CommonName) {
|
||||
names = append(names, c.Subject.CommonName)
|
||||
}
|
||||
|
||||
for _, name := range c.DNSNames {
|
||||
if isValidName(name) {
|
||||
names = append(names, name)
|
||||
} else if !strings.Contains(name, ".") { //just a TLD
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for _, name := range c.URIs {
|
||||
if util.IsURL(name) {
|
||||
names = append(names, name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range c.IPAddresses {
|
||||
str := name.String()
|
||||
if util.IsURL(str) {
|
||||
names = append(names, str)
|
||||
}
|
||||
}
|
||||
|
||||
return purgeNameDuplicates(names)
|
||||
}
|
||||
|
||||
func (c *Certificate) MarshalJSON() ([]byte, error) {
|
||||
// Fill out the certificate
|
||||
jc := new(JSONCertificate)
|
||||
jc.Version = c.Version
|
||||
jc.SerialNumber = c.SerialNumber.String()
|
||||
jc.Issuer = c.Issuer
|
||||
jc.IssuerDN = c.Issuer.String()
|
||||
|
||||
jc.Validity.NotBefore = c.NotBefore
|
||||
jc.Validity.NotAfter = c.NotAfter
|
||||
jc.Validity.ValidityPeriod = c.ValidityPeriod
|
||||
jc.Subject = c.Subject
|
||||
jc.SubjectDN = c.Subject.String()
|
||||
jc.Names = c.CollectAllNames()
|
||||
jc.Redacted = false
|
||||
for _, name := range jc.Names {
|
||||
if strings.HasPrefix(name, "?") {
|
||||
jc.Redacted = true
|
||||
}
|
||||
}
|
||||
|
||||
jc.SubjectKeyInfo = c.jsonifySubjectKey()
|
||||
jc.Extensions, jc.UnknownExtensions = c.jsonifyExtensions()
|
||||
|
||||
// TODO: Handle the fact this might not match
|
||||
jc.SignatureAlgorithm = c.jsonifySignatureAlgorithm()
|
||||
jc.Signature.SignatureAlgorithm = jc.SignatureAlgorithm
|
||||
jc.Signature.Value = c.Signature
|
||||
jc.Signature.Valid = c.validSignature
|
||||
jc.Signature.SelfSigned = c.SelfSigned
|
||||
if c.SelfSigned {
|
||||
jc.Signature.Valid = true
|
||||
}
|
||||
jc.FingerprintMD5 = c.FingerprintMD5
|
||||
jc.FingerprintSHA1 = c.FingerprintSHA1
|
||||
jc.FingerprintSHA256 = c.FingerprintSHA256
|
||||
jc.FingerprintNoCT = c.FingerprintNoCT
|
||||
jc.SPKISubjectFingerprint = c.SPKISubjectFingerprint
|
||||
jc.TBSCertificateFingerprint = c.TBSCertificateFingerprint
|
||||
jc.ValidationLevel = c.ValidationLevel
|
||||
|
||||
return json.Marshal(jc)
|
||||
}
|
||||
|
||||
// UnmarshalJSON - intentionally implimented to always error,
|
||||
// as this method should not be used. The MarshalJSON method
|
||||
// on Certificate condenses data in a way that is not recoverable.
|
||||
// Use the x509.ParseCertificate function instead or
|
||||
// JSONCertificateWithRaw Marshal method
|
||||
func (jc *JSONCertificate) UnmarshalJSON(b []byte) error {
|
||||
return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function")
|
||||
}
|
||||
|
||||
// UnmarshalJSON - intentionally implimented to always error,
|
||||
// as this method should not be used. The MarshalJSON method
|
||||
// on Certificate condenses data in a way that is not recoverable.
|
||||
// Use the x509.ParseCertificate function instead or
|
||||
// JSONCertificateWithRaw Marshal method
|
||||
func (c *Certificate) UnmarshalJSON(b []byte) error {
|
||||
return errors.New("Do not unmarshal cert JSON directly, use JSONCertificateWithRaw or x509.ParseCertificate function")
|
||||
}
|
||||
|
||||
// JSONCertificateWithRaw - intermediate struct for unmarshaling json
|
||||
// of a certificate - the raw is require since the
|
||||
// MarshalJSON method on Certificate condenses data in a way that
|
||||
// makes extraction to the original in Unmarshal impossible.
|
||||
// The JSON output of Marshal is not even used to construct
|
||||
// a certificate, all we need is raw
|
||||
type JSONCertificateWithRaw struct {
|
||||
Raw []byte `json:"raw,omitempty"`
|
||||
}
|
||||
|
||||
// ParseRaw - for converting the intermediate object
|
||||
// JSONCertificateWithRaw into a parsed Certificate
|
||||
// see description of JSONCertificateWithRaw for
|
||||
// why this is used instead of UnmarshalJSON methods
|
||||
func (c *JSONCertificateWithRaw) ParseRaw() (*Certificate, error) {
|
||||
return ParseCertificate(c.Raw)
|
||||
}
|
||||
|
||||
func purgeNameDuplicates(names []string) (out []string) {
|
||||
hashset := make(map[string]bool, len(names))
|
||||
for _, name := range names {
|
||||
if _, inc := hashset[name]; !inc {
|
||||
hashset[name] = true
|
||||
}
|
||||
}
|
||||
|
||||
out = make([]string, 0, len(hashset))
|
||||
for key := range hashset {
|
||||
out = append(out, key)
|
||||
}
|
||||
|
||||
sort.Strings(out) // must sort to ensure output is deterministic!
|
||||
return
|
||||
}
|
||||
|
||||
func isValidName(name string) (ret bool) {
|
||||
|
||||
// Check for wildcards and redacts, ignore malformed urls
|
||||
if strings.HasPrefix(name, "?.") || strings.HasPrefix(name, "*.") {
|
||||
ret = isValidName(name[2:])
|
||||
} else {
|
||||
ret = util.IsURL(name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func orMask(ip net.IP, mask net.IPMask) net.IP {
|
||||
if len(ip) == 0 || len(mask) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(ip) != net.IPv4len && len(ip) != net.IPv6len {
|
||||
return nil
|
||||
}
|
||||
if len(ip) != len(mask) {
|
||||
return nil
|
||||
}
|
||||
out := make([]byte, len(ip))
|
||||
for idx := range ip {
|
||||
out[idx] = ip[idx] | mask[idx]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func invertMask(mask net.IPMask) net.IPMask {
|
||||
if mask == nil {
|
||||
return nil
|
||||
}
|
||||
out := make([]byte, len(mask))
|
||||
for idx := range mask {
|
||||
out[idx] = ^mask[idx]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type auxGeneralSubtreeIP struct {
|
||||
CIDR string `json:"cidr,omitempty"`
|
||||
Begin string `json:"begin,omitempty"`
|
||||
End string `json:"end,omitempty"`
|
||||
Mask string `json:"mask,omitempty"`
|
||||
}
|
||||
|
||||
func (g *GeneralSubtreeIP) MarshalJSON() ([]byte, error) {
|
||||
aux := auxGeneralSubtreeIP{}
|
||||
aux.CIDR = g.Data.String()
|
||||
// Check to see if the subnet is valid. An invalid subnet will return 0,0
|
||||
// from Size(). If the subnet is invalid, only output the CIDR.
|
||||
ones, bits := g.Data.Mask.Size()
|
||||
if ones == 0 && bits == 0 {
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
// The first IP in the range should be `ip & mask`.
|
||||
begin := g.Data.IP.Mask(g.Data.Mask)
|
||||
if begin != nil {
|
||||
aux.Begin = begin.String()
|
||||
}
|
||||
// The last IP (inclusive) is `ip & (^mask)`.
|
||||
inverseMask := invertMask(g.Data.Mask)
|
||||
end := orMask(g.Data.IP, inverseMask)
|
||||
if end != nil {
|
||||
aux.End = end.String()
|
||||
}
|
||||
// Output the mask as an IP, but enforce it can be formatted correctly.
|
||||
// net.IP.String() only works on byte arrays of the correct length.
|
||||
maskLen := len(g.Data.Mask)
|
||||
if maskLen == net.IPv4len || maskLen == net.IPv6len {
|
||||
maskAsIP := net.IP(g.Data.Mask)
|
||||
aux.Mask = maskAsIP.String()
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
func (g *GeneralSubtreeIP) UnmarshalJSON(b []byte) error {
|
||||
aux := auxGeneralSubtreeIP{}
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
ip, ipNet, err := net.ParseCIDR(aux.CIDR)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
g.Data.IP = ip
|
||||
g.Data.Mask = ipNet.Mask
|
||||
g.Min = 0
|
||||
g.Max = 0
|
||||
return nil
|
||||
}
|
30
vendor/github.com/zmap/zcrypto/x509/names.go
generated
vendored
Normal file
30
vendor/github.com/zmap/zcrypto/x509/names.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
func (p PublicKeyAlgorithm) String() string {
|
||||
if p >= total_key_algorithms || p < 0 {
|
||||
p = UnknownPublicKeyAlgorithm
|
||||
}
|
||||
return keyAlgorithmNames[p]
|
||||
}
|
||||
|
||||
func (c *Certificate) SignatureAlgorithmName() string {
|
||||
switch c.SignatureAlgorithm {
|
||||
case UnknownSignatureAlgorithm:
|
||||
return c.SignatureAlgorithmOID.String()
|
||||
default:
|
||||
return c.SignatureAlgorithm.String()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Certificate) PublicKeyAlgorithmName() string {
|
||||
switch c.PublicKeyAlgorithm {
|
||||
case UnknownPublicKeyAlgorithm:
|
||||
return c.PublicKeyAlgorithmOID.String()
|
||||
default:
|
||||
return c.PublicKeyAlgorithm.String()
|
||||
}
|
||||
}
|
240
vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go
generated
vendored
Normal file
240
vendor/github.com/zmap/zcrypto/x509/pem_decrypt.go
generated
vendored
Normal file
|
@ -0,0 +1,240 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
// RFC 1423 describes the encryption of PEM blocks. The algorithm used to
|
||||
// generate a key from the password was derived by looking at the OpenSSL
|
||||
// implementation.
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PEMCipher int
|
||||
|
||||
// Possible values for the EncryptPEMBlock encryption algorithm.
|
||||
const (
|
||||
_ PEMCipher = iota
|
||||
PEMCipherDES
|
||||
PEMCipher3DES
|
||||
PEMCipherAES128
|
||||
PEMCipherAES192
|
||||
PEMCipherAES256
|
||||
)
|
||||
|
||||
// rfc1423Algo holds a method for enciphering a PEM block.
|
||||
type rfc1423Algo struct {
|
||||
cipher PEMCipher
|
||||
name string
|
||||
cipherFunc func(key []byte) (cipher.Block, error)
|
||||
keySize int
|
||||
blockSize int
|
||||
}
|
||||
|
||||
// rfc1423Algos holds a slice of the possible ways to encrypt a PEM
|
||||
// block. The ivSize numbers were taken from the OpenSSL source.
|
||||
var rfc1423Algos = []rfc1423Algo{{
|
||||
cipher: PEMCipherDES,
|
||||
name: "DES-CBC",
|
||||
cipherFunc: des.NewCipher,
|
||||
keySize: 8,
|
||||
blockSize: des.BlockSize,
|
||||
}, {
|
||||
cipher: PEMCipher3DES,
|
||||
name: "DES-EDE3-CBC",
|
||||
cipherFunc: des.NewTripleDESCipher,
|
||||
keySize: 24,
|
||||
blockSize: des.BlockSize,
|
||||
}, {
|
||||
cipher: PEMCipherAES128,
|
||||
name: "AES-128-CBC",
|
||||
cipherFunc: aes.NewCipher,
|
||||
keySize: 16,
|
||||
blockSize: aes.BlockSize,
|
||||
}, {
|
||||
cipher: PEMCipherAES192,
|
||||
name: "AES-192-CBC",
|
||||
cipherFunc: aes.NewCipher,
|
||||
keySize: 24,
|
||||
blockSize: aes.BlockSize,
|
||||
}, {
|
||||
cipher: PEMCipherAES256,
|
||||
name: "AES-256-CBC",
|
||||
cipherFunc: aes.NewCipher,
|
||||
keySize: 32,
|
||||
blockSize: aes.BlockSize,
|
||||
},
|
||||
}
|
||||
|
||||
// deriveKey uses a key derivation function to stretch the password into a key
|
||||
// with the number of bits our cipher requires. This algorithm was derived from
|
||||
// the OpenSSL source.
|
||||
func (c rfc1423Algo) deriveKey(password, salt []byte) []byte {
|
||||
hash := md5.New()
|
||||
out := make([]byte, c.keySize)
|
||||
var digest []byte
|
||||
|
||||
for i := 0; i < len(out); i += len(digest) {
|
||||
hash.Reset()
|
||||
hash.Write(digest)
|
||||
hash.Write(password)
|
||||
hash.Write(salt)
|
||||
digest = hash.Sum(digest[:0])
|
||||
copy(out[i:], digest)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// IsEncryptedPEMBlock returns if the PEM block is password encrypted.
|
||||
func IsEncryptedPEMBlock(b *pem.Block) bool {
|
||||
_, ok := b.Headers["DEK-Info"]
|
||||
return ok
|
||||
}
|
||||
|
||||
// IncorrectPasswordError is returned when an incorrect password is detected.
|
||||
var IncorrectPasswordError = errors.New("x509: decryption password incorrect")
|
||||
|
||||
// DecryptPEMBlock takes a password encrypted PEM block and the password used to
|
||||
// encrypt it and returns a slice of decrypted DER encoded bytes. It inspects
|
||||
// the DEK-Info header to determine the algorithm used for decryption. If no
|
||||
// DEK-Info header is present, an error is returned. If an incorrect password
|
||||
// is detected an IncorrectPasswordError is returned. Because of deficiencies
|
||||
// in the encrypted-PEM format, it's not always possible to detect an incorrect
|
||||
// password. In these cases no error will be returned but the decrypted DER
|
||||
// bytes will be random noise.
|
||||
func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
|
||||
dek, ok := b.Headers["DEK-Info"]
|
||||
if !ok {
|
||||
return nil, errors.New("x509: no DEK-Info header in block")
|
||||
}
|
||||
|
||||
idx := strings.Index(dek, ",")
|
||||
if idx == -1 {
|
||||
return nil, errors.New("x509: malformed DEK-Info header")
|
||||
}
|
||||
|
||||
mode, hexIV := dek[:idx], dek[idx+1:]
|
||||
ciph := cipherByName(mode)
|
||||
if ciph == nil {
|
||||
return nil, errors.New("x509: unknown encryption mode")
|
||||
}
|
||||
iv, err := hex.DecodeString(hexIV)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(iv) != ciph.blockSize {
|
||||
return nil, errors.New("x509: incorrect IV size")
|
||||
}
|
||||
|
||||
// Based on the OpenSSL implementation. The salt is the first 8 bytes
|
||||
// of the initialization vector.
|
||||
key := ciph.deriveKey(password, iv[:8])
|
||||
block, err := ciph.cipherFunc(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b.Bytes)%block.BlockSize() != 0 {
|
||||
return nil, errors.New("x509: encrypted PEM data is not a multiple of the block size")
|
||||
}
|
||||
|
||||
data := make([]byte, len(b.Bytes))
|
||||
dec := cipher.NewCBCDecrypter(block, iv)
|
||||
dec.CryptBlocks(data, b.Bytes)
|
||||
|
||||
// Blocks are padded using a scheme where the last n bytes of padding are all
|
||||
// equal to n. It can pad from 1 to blocksize bytes inclusive. See RFC 1423.
|
||||
// For example:
|
||||
// [x y z 2 2]
|
||||
// [x y 7 7 7 7 7 7 7]
|
||||
// If we detect a bad padding, we assume it is an invalid password.
|
||||
dlen := len(data)
|
||||
if dlen == 0 || dlen%ciph.blockSize != 0 {
|
||||
return nil, errors.New("x509: invalid padding")
|
||||
}
|
||||
last := int(data[dlen-1])
|
||||
if dlen < last {
|
||||
return nil, IncorrectPasswordError
|
||||
}
|
||||
if last == 0 || last > ciph.blockSize {
|
||||
return nil, IncorrectPasswordError
|
||||
}
|
||||
for _, val := range data[dlen-last:] {
|
||||
if int(val) != last {
|
||||
return nil, IncorrectPasswordError
|
||||
}
|
||||
}
|
||||
return data[:dlen-last], nil
|
||||
}
|
||||
|
||||
// EncryptPEMBlock returns a PEM block of the specified type holding the
|
||||
// given DER-encoded data encrypted with the specified algorithm and
|
||||
// password.
|
||||
func EncryptPEMBlock(rand io.Reader, blockType string, data, password []byte, alg PEMCipher) (*pem.Block, error) {
|
||||
ciph := cipherByKey(alg)
|
||||
if ciph == nil {
|
||||
return nil, errors.New("x509: unknown encryption mode")
|
||||
}
|
||||
iv := make([]byte, ciph.blockSize)
|
||||
if _, err := io.ReadFull(rand, iv); err != nil {
|
||||
return nil, errors.New("x509: cannot generate IV: " + err.Error())
|
||||
}
|
||||
// The salt is the first 8 bytes of the initialization vector,
|
||||
// matching the key derivation in DecryptPEMBlock.
|
||||
key := ciph.deriveKey(password, iv[:8])
|
||||
block, err := ciph.cipherFunc(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
enc := cipher.NewCBCEncrypter(block, iv)
|
||||
pad := ciph.blockSize - len(data)%ciph.blockSize
|
||||
encrypted := make([]byte, len(data), len(data)+pad)
|
||||
// We could save this copy by encrypting all the whole blocks in
|
||||
// the data separately, but it doesn't seem worth the additional
|
||||
// code.
|
||||
copy(encrypted, data)
|
||||
// See RFC 1423, section 1.1
|
||||
for i := 0; i < pad; i++ {
|
||||
encrypted = append(encrypted, byte(pad))
|
||||
}
|
||||
enc.CryptBlocks(encrypted, encrypted)
|
||||
|
||||
return &pem.Block{
|
||||
Type: blockType,
|
||||
Headers: map[string]string{
|
||||
"Proc-Type": "4,ENCRYPTED",
|
||||
"DEK-Info": ciph.name + "," + hex.EncodeToString(iv),
|
||||
},
|
||||
Bytes: encrypted,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func cipherByName(name string) *rfc1423Algo {
|
||||
for i := range rfc1423Algos {
|
||||
alg := &rfc1423Algos[i]
|
||||
if alg.name == name {
|
||||
return alg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cipherByKey(key PEMCipher) *rfc1423Algo {
|
||||
for i := range rfc1423Algos {
|
||||
alg := &rfc1423Algos[i]
|
||||
if alg.cipher == key {
|
||||
return alg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
121
vendor/github.com/zmap/zcrypto/x509/pkcs1.go
generated
vendored
Normal file
121
vendor/github.com/zmap/zcrypto/x509/pkcs1.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key.
|
||||
type pkcs1PrivateKey struct {
|
||||
Version int
|
||||
N *big.Int
|
||||
E int
|
||||
D *big.Int
|
||||
P *big.Int
|
||||
Q *big.Int
|
||||
// We ignore these values, if present, because rsa will calculate them.
|
||||
Dp *big.Int `asn1:"optional"`
|
||||
Dq *big.Int `asn1:"optional"`
|
||||
Qinv *big.Int `asn1:"optional"`
|
||||
|
||||
AdditionalPrimes []pkcs1AdditionalRSAPrime `asn1:"optional,omitempty"`
|
||||
}
|
||||
|
||||
type pkcs1AdditionalRSAPrime struct {
|
||||
Prime *big.Int
|
||||
|
||||
// We ignore these values because rsa will calculate them.
|
||||
Exp *big.Int
|
||||
Coeff *big.Int
|
||||
}
|
||||
|
||||
// pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key.
|
||||
type pkcs1PublicKey struct {
|
||||
N *big.Int
|
||||
E int
|
||||
}
|
||||
|
||||
// ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
|
||||
func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
|
||||
var priv pkcs1PrivateKey
|
||||
rest, err := asn1.Unmarshal(der, &priv)
|
||||
if len(rest) > 0 {
|
||||
return nil, asn1.SyntaxError{Msg: "trailing data"}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if priv.Version > 1 {
|
||||
return nil, errors.New("x509: unsupported private key version")
|
||||
}
|
||||
|
||||
if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
|
||||
return nil, errors.New("x509: private key contains zero or negative value")
|
||||
}
|
||||
|
||||
key := new(rsa.PrivateKey)
|
||||
key.PublicKey = rsa.PublicKey{
|
||||
E: priv.E,
|
||||
N: priv.N,
|
||||
}
|
||||
|
||||
key.D = priv.D
|
||||
key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
|
||||
key.Primes[0] = priv.P
|
||||
key.Primes[1] = priv.Q
|
||||
for i, a := range priv.AdditionalPrimes {
|
||||
if a.Prime.Sign() <= 0 {
|
||||
return nil, errors.New("x509: private key contains zero or negative prime")
|
||||
}
|
||||
key.Primes[i+2] = a.Prime
|
||||
// We ignore the other two values because rsa will calculate
|
||||
// them as needed.
|
||||
}
|
||||
|
||||
err = key.Validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key.Precompute()
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
|
||||
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
|
||||
key.Precompute()
|
||||
|
||||
version := 0
|
||||
if len(key.Primes) > 2 {
|
||||
version = 1
|
||||
}
|
||||
|
||||
priv := pkcs1PrivateKey{
|
||||
Version: version,
|
||||
N: key.N,
|
||||
E: key.PublicKey.E,
|
||||
D: key.D,
|
||||
P: key.Primes[0],
|
||||
Q: key.Primes[1],
|
||||
Dp: key.Precomputed.Dp,
|
||||
Dq: key.Precomputed.Dq,
|
||||
Qinv: key.Precomputed.Qinv,
|
||||
}
|
||||
|
||||
priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
|
||||
for i, values := range key.Precomputed.CRTValues {
|
||||
priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
|
||||
priv.AdditionalPrimes[i].Exp = values.Exp
|
||||
priv.AdditionalPrimes[i].Coeff = values.Coeff
|
||||
}
|
||||
|
||||
b, _ := asn1.Marshal(priv)
|
||||
return b
|
||||
}
|
54
vendor/github.com/zmap/zcrypto/x509/pkcs8.go
generated
vendored
Normal file
54
vendor/github.com/zmap/zcrypto/x509/pkcs8.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zmap/zcrypto/x509/pkix"
|
||||
)
|
||||
|
||||
// pkcs8 reflects an ASN.1, PKCS#8 PrivateKey. See
|
||||
// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
|
||||
// and RFC 5208.
|
||||
type pkcs8 struct {
|
||||
Version int
|
||||
Algo pkix.AlgorithmIdentifier
|
||||
PrivateKey []byte
|
||||
// optional attributes omitted.
|
||||
}
|
||||
|
||||
// ParsePKCS8PrivateKey parses an unencrypted, PKCS#8 private key.
|
||||
// See RFC 5208.
|
||||
func ParsePKCS8PrivateKey(der []byte) (key interface{}, err error) {
|
||||
var privKey pkcs8
|
||||
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch {
|
||||
case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA):
|
||||
key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
|
||||
}
|
||||
return key, nil
|
||||
|
||||
case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
|
||||
bytes := privKey.Algo.Parameters.FullBytes
|
||||
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||
if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
|
||||
namedCurveOID = nil
|
||||
}
|
||||
key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
|
||||
}
|
||||
return key, nil
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
|
||||
}
|
||||
}
|
279
vendor/github.com/zmap/zcrypto/x509/pkix/json.go
generated
vendored
Normal file
279
vendor/github.com/zmap/zcrypto/x509/pkix/json.go
generated
vendored
Normal file
|
@ -0,0 +1,279 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pkix
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type auxAttributeTypeAndValue struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (a *AttributeTypeAndValue) MarshalJSON() ([]byte, error) {
|
||||
aux := auxAttributeTypeAndValue{}
|
||||
aux.Type = a.Type.String()
|
||||
if s, ok := a.Value.(string); ok {
|
||||
aux.Value = s
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (a *AttributeTypeAndValue) UnmarshalJSON(b []byte) error {
|
||||
aux := auxAttributeTypeAndValue{}
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
a.Type = nil
|
||||
if len(aux.Type) > 0 {
|
||||
parts := strings.Split(aux.Type, ".")
|
||||
for _, part := range parts {
|
||||
i, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Type = append(a.Type, i)
|
||||
}
|
||||
}
|
||||
a.Value = aux.Value
|
||||
return nil
|
||||
}
|
||||
|
||||
type auxOtherName struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Value []byte `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (o *OtherName) MarshalJSON() ([]byte, error) {
|
||||
aux := auxOtherName{
|
||||
ID: o.TypeID.String(),
|
||||
Value: o.Value.Bytes,
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (o *OtherName) UnmarshalJSON(b []byte) (err error) {
|
||||
aux := auxOtherName{}
|
||||
if err = json.Unmarshal(b, &aux); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Turn dot-notation back into an OID
|
||||
if len(aux.ID) == 0 {
|
||||
return errors.New("empty type ID")
|
||||
}
|
||||
parts := strings.Split(aux.ID, ".")
|
||||
o.TypeID = nil
|
||||
for _, part := range parts {
|
||||
i, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.TypeID = append(o.TypeID, i)
|
||||
}
|
||||
|
||||
// Build the ASN.1 value
|
||||
o.Value = asn1.RawValue{
|
||||
Tag: 0,
|
||||
Class: asn1.ClassContextSpecific,
|
||||
IsCompound: true,
|
||||
Bytes: aux.Value,
|
||||
}
|
||||
o.Value.FullBytes, err = asn1.Marshal(o.Value)
|
||||
return
|
||||
}
|
||||
|
||||
type auxExtension struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Critical bool `json:"critical"`
|
||||
Value []byte `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (ext *Extension) MarshalJSON() ([]byte, error) {
|
||||
aux := auxExtension{
|
||||
ID: ext.Id.String(),
|
||||
Critical: ext.Critical,
|
||||
Value: ext.Value,
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (ext *Extension) UnmarshalJSON(b []byte) (err error) {
|
||||
aux := auxExtension{}
|
||||
if err = json.Unmarshal(b, &aux); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
parts := strings.Split(aux.ID, ".")
|
||||
for _, part := range parts {
|
||||
i, err := strconv.Atoi(part)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ext.Id = append(ext.Id, i)
|
||||
}
|
||||
ext.Critical = aux.Critical
|
||||
ext.Value = aux.Value
|
||||
return
|
||||
}
|
||||
|
||||
type auxName struct {
|
||||
CommonName []string `json:"common_name,omitempty"`
|
||||
SerialNumber []string `json:"serial_number,omitempty"`
|
||||
Country []string `json:"country,omitempty"`
|
||||
Locality []string `json:"locality,omitempty"`
|
||||
Province []string `json:"province,omitempty"`
|
||||
StreetAddress []string `json:"street_address,omitempty"`
|
||||
Organization []string `json:"organization,omitempty"`
|
||||
OrganizationalUnit []string `json:"organizational_unit,omitempty"`
|
||||
PostalCode []string `json:"postal_code,omitempty"`
|
||||
DomainComponent []string `json:"domain_component,omitempty"`
|
||||
EmailAddress []string `json:"email_address,omitempty"`
|
||||
GivenName []string `json:"given_name,omitempty"`
|
||||
Surname []string `json:"surname,omitempty"`
|
||||
// EV
|
||||
JurisdictionCountry []string `json:"jurisdiction_country,omitempty"`
|
||||
JurisdictionLocality []string `json:"jurisdiction_locality,omitempty"`
|
||||
JurisdictionProvince []string `json:"jurisdiction_province,omitempty"`
|
||||
|
||||
// QWACS
|
||||
OrganizationID []string `json:"organization_id,omitempty"`
|
||||
|
||||
UnknownAttributes []AttributeTypeAndValue `json:"-"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (n *Name) MarshalJSON() ([]byte, error) {
|
||||
aux := auxName{}
|
||||
attrs := n.ToRDNSequence()
|
||||
for _, attrSet := range attrs {
|
||||
for _, a := range attrSet {
|
||||
s, ok := a.Value.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if a.Type.Equal(oidCommonName) {
|
||||
aux.CommonName = append(aux.CommonName, s)
|
||||
} else if a.Type.Equal(oidSurname) {
|
||||
aux.Surname = append(aux.Surname, s)
|
||||
} else if a.Type.Equal(oidSerialNumber) {
|
||||
aux.SerialNumber = append(aux.SerialNumber, s)
|
||||
} else if a.Type.Equal(oidCountry) {
|
||||
aux.Country = append(aux.Country, s)
|
||||
} else if a.Type.Equal(oidLocality) {
|
||||
aux.Locality = append(aux.Locality, s)
|
||||
} else if a.Type.Equal(oidProvince) {
|
||||
aux.Province = append(aux.Province, s)
|
||||
} else if a.Type.Equal(oidStreetAddress) {
|
||||
aux.StreetAddress = append(aux.StreetAddress, s)
|
||||
} else if a.Type.Equal(oidOrganization) {
|
||||
aux.Organization = append(aux.Organization, s)
|
||||
} else if a.Type.Equal(oidGivenName) {
|
||||
aux.GivenName = append(aux.GivenName, s)
|
||||
} else if a.Type.Equal(oidOrganizationalUnit) {
|
||||
aux.OrganizationalUnit = append(aux.OrganizationalUnit, s)
|
||||
} else if a.Type.Equal(oidPostalCode) {
|
||||
aux.PostalCode = append(aux.PostalCode, s)
|
||||
} else if a.Type.Equal(oidDomainComponent) {
|
||||
aux.DomainComponent = append(aux.DomainComponent, s)
|
||||
} else if a.Type.Equal(oidDNEmailAddress) {
|
||||
aux.EmailAddress = append(aux.EmailAddress, s)
|
||||
// EV
|
||||
} else if a.Type.Equal(oidJurisdictionCountry) {
|
||||
aux.JurisdictionCountry = append(aux.JurisdictionCountry, s)
|
||||
} else if a.Type.Equal(oidJurisdictionLocality) {
|
||||
aux.JurisdictionLocality = append(aux.JurisdictionLocality, s)
|
||||
} else if a.Type.Equal(oidJurisdictionProvince) {
|
||||
aux.JurisdictionProvince = append(aux.JurisdictionProvince, s)
|
||||
} else if a.Type.Equal(oidOrganizationID) {
|
||||
aux.OrganizationID = append(aux.OrganizationID, s)
|
||||
} else {
|
||||
aux.UnknownAttributes = append(aux.UnknownAttributes, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
func appendATV(names []AttributeTypeAndValue, fieldVals []string, asn1Id asn1.ObjectIdentifier) []AttributeTypeAndValue {
|
||||
if len(fieldVals) == 0 {
|
||||
return names
|
||||
}
|
||||
|
||||
for _, val := range fieldVals {
|
||||
names = append(names, AttributeTypeAndValue{Type: asn1Id, Value: val})
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (n *Name) UnmarshalJSON(b []byte) error {
|
||||
aux := auxName{}
|
||||
if err := json.Unmarshal(b, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Populate Names as []AttributeTypeAndValue
|
||||
n.Names = appendATV(n.Names, aux.Country, oidCountry)
|
||||
n.Names = appendATV(n.Names, aux.Organization, oidOrganization)
|
||||
n.Names = appendATV(n.Names, aux.OrganizationalUnit, oidOrganizationalUnit)
|
||||
n.Names = appendATV(n.Names, aux.Locality, oidLocality)
|
||||
n.Names = appendATV(n.Names, aux.Province, oidProvince)
|
||||
n.Names = appendATV(n.Names, aux.StreetAddress, oidStreetAddress)
|
||||
n.Names = appendATV(n.Names, aux.PostalCode, oidPostalCode)
|
||||
n.Names = appendATV(n.Names, aux.DomainComponent, oidDomainComponent)
|
||||
n.Names = appendATV(n.Names, aux.EmailAddress, oidDNEmailAddress)
|
||||
// EV
|
||||
n.Names = appendATV(n.Names, aux.JurisdictionCountry, oidJurisdictionCountry)
|
||||
n.Names = appendATV(n.Names, aux.JurisdictionLocality, oidJurisdictionLocality)
|
||||
n.Names = appendATV(n.Names, aux.JurisdictionProvince, oidJurisdictionProvince)
|
||||
|
||||
n.Names = appendATV(n.Names, aux.CommonName, oidCommonName)
|
||||
n.Names = appendATV(n.Names, aux.SerialNumber, oidSerialNumber)
|
||||
|
||||
// Populate specific fields as []string
|
||||
n.Country = aux.Country
|
||||
n.Organization = aux.Organization
|
||||
n.OrganizationalUnit = aux.OrganizationalUnit
|
||||
n.Locality = aux.Locality
|
||||
n.Province = aux.Province
|
||||
n.StreetAddress = aux.StreetAddress
|
||||
n.PostalCode = aux.PostalCode
|
||||
n.DomainComponent = aux.DomainComponent
|
||||
// EV
|
||||
n.JurisdictionCountry = aux.JurisdictionCountry
|
||||
n.JurisdictionLocality = aux.JurisdictionLocality
|
||||
n.JurisdictionProvince = aux.JurisdictionProvince
|
||||
|
||||
// CommonName and SerialNumber are not arrays.
|
||||
if len(aux.CommonName) > 0 {
|
||||
n.CommonName = aux.CommonName[0]
|
||||
}
|
||||
if len(aux.SerialNumber) > 0 {
|
||||
n.SerialNumber = aux.SerialNumber[0]
|
||||
}
|
||||
|
||||
// Add "extra" commonNames and serialNumbers to ExtraNames.
|
||||
if len(aux.CommonName) > 1 {
|
||||
n.ExtraNames = appendATV(n.ExtraNames, aux.CommonName[1:], oidCommonName)
|
||||
}
|
||||
if len(aux.SerialNumber) > 1 {
|
||||
n.ExtraNames = appendATV(n.ExtraNames, aux.SerialNumber[1:], oidSerialNumber)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
74
vendor/github.com/zmap/zcrypto/x509/pkix/oid.go
generated
vendored
Normal file
74
vendor/github.com/zmap/zcrypto/x509/pkix/oid.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package pkix
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AuxOID behaves similar to asn1.ObjectIdentifier, except encodes to JSON as a
|
||||
// string in dot notation. It is a type synonym for []int, and can be converted
|
||||
// to an asn1.ObjectIdentifier by going through []int and back.
|
||||
type AuxOID []int
|
||||
|
||||
// AsSlice returns a slice over the inner-representation
|
||||
func (aux *AuxOID) AsSlice() []int {
|
||||
return *aux
|
||||
}
|
||||
|
||||
// CopyAsSlice returns a copy of the inter-representation as a slice
|
||||
func (aux *AuxOID) CopyAsSlice() []int {
|
||||
out := make([]int, len(*aux))
|
||||
copy(out, *aux)
|
||||
return out
|
||||
}
|
||||
|
||||
// Equal tests (deep) equality of two AuxOIDs
|
||||
func (aux *AuxOID) Equal(other *AuxOID) bool {
|
||||
var a []int = *aux
|
||||
var b []int = *other
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for idx := range a {
|
||||
if a[idx] != b[idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface
|
||||
func (aux *AuxOID) MarshalJSON() ([]byte, error) {
|
||||
var oid asn1.ObjectIdentifier
|
||||
oid = []int(*aux)
|
||||
return json.Marshal(oid.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface
|
||||
func (aux *AuxOID) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
return err
|
||||
}
|
||||
parts := strings.Split(s, ".")
|
||||
if len(parts) < 1 {
|
||||
return fmt.Errorf("Invalid OID string %s", s)
|
||||
}
|
||||
slice := make([]int, len(parts))
|
||||
for idx := range parts {
|
||||
n, err := strconv.Atoi(parts[idx])
|
||||
if err != nil || n < 0 {
|
||||
return fmt.Errorf("Invalid OID integer %s", parts[idx])
|
||||
}
|
||||
slice[idx] = n
|
||||
}
|
||||
*aux = slice
|
||||
return nil
|
||||
}
|
1014
vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go
generated
vendored
Normal file
1014
vendor/github.com/zmap/zcrypto/x509/pkix/oid_names.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
299
vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go
generated
vendored
Normal file
299
vendor/github.com/zmap/zcrypto/x509/pkix/pkix.go
generated
vendored
Normal file
|
@ -0,0 +1,299 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package pkix contains shared, low level structures used for ASN.1 parsing
|
||||
// and serialization of X.509 certificates, CRL and OCSP.
|
||||
package pkix
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"math/big"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 4.1.1.2.
|
||||
type AlgorithmIdentifier struct {
|
||||
Algorithm asn1.ObjectIdentifier
|
||||
Parameters asn1.RawValue `asn1:"optional"`
|
||||
}
|
||||
|
||||
type RDNSequence []RelativeDistinguishedNameSET
|
||||
|
||||
type RelativeDistinguishedNameSET []AttributeTypeAndValue
|
||||
|
||||
// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
|
||||
// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
|
||||
type AttributeTypeAndValue struct {
|
||||
Type asn1.ObjectIdentifier `json:"type"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// AttributeTypeAndValueSET represents a set of ASN.1 sequences of
|
||||
// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10).
|
||||
type AttributeTypeAndValueSET struct {
|
||||
Type asn1.ObjectIdentifier
|
||||
Value [][]AttributeTypeAndValue `asn1:"set"`
|
||||
}
|
||||
|
||||
// Extension represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 4.2.
|
||||
type Extension struct {
|
||||
Id asn1.ObjectIdentifier
|
||||
Critical bool `asn1:"optional"`
|
||||
Value []byte
|
||||
}
|
||||
|
||||
// Name represents an X.509 distinguished name. This only includes the common
|
||||
// elements of a DN. Additional elements in the name are ignored.
|
||||
type Name struct {
|
||||
Country, Organization, OrganizationalUnit []string
|
||||
Locality, Province []string
|
||||
StreetAddress, PostalCode, DomainComponent []string
|
||||
EmailAddress []string
|
||||
SerialNumber, CommonName string
|
||||
SerialNumbers, CommonNames []string
|
||||
GivenName, Surname []string
|
||||
OrganizationIDs []string
|
||||
// EV Components
|
||||
JurisdictionLocality, JurisdictionProvince, JurisdictionCountry []string
|
||||
|
||||
Names []AttributeTypeAndValue
|
||||
ExtraNames []AttributeTypeAndValue
|
||||
|
||||
// OriginalRDNS is saved if the name is populated using FillFromRDNSequence.
|
||||
// Additionally, if OriginalRDNS is non-nil, the String and ToRDNSequence
|
||||
// methods will simply use this.
|
||||
OriginalRDNS RDNSequence
|
||||
}
|
||||
|
||||
// FillFromRDNSequence populates n based on the AttributeTypeAndValueSETs in the
|
||||
// RDNSequence. It save the sequence as OriginalRDNS.
|
||||
func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
|
||||
n.OriginalRDNS = *rdns
|
||||
for _, rdn := range *rdns {
|
||||
if len(rdn) == 0 {
|
||||
continue
|
||||
}
|
||||
atv := rdn[0]
|
||||
n.Names = append(n.Names, atv)
|
||||
value, ok := atv.Value.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
t := atv.Type
|
||||
if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
|
||||
switch t[3] {
|
||||
case 3:
|
||||
n.CommonName = value
|
||||
n.CommonNames = append(n.CommonNames, value)
|
||||
case 4:
|
||||
n.Surname = append(n.Surname, value)
|
||||
case 5:
|
||||
n.SerialNumber = value
|
||||
n.SerialNumbers = append(n.SerialNumbers, value)
|
||||
case 6:
|
||||
n.Country = append(n.Country, value)
|
||||
case 7:
|
||||
n.Locality = append(n.Locality, value)
|
||||
case 8:
|
||||
n.Province = append(n.Province, value)
|
||||
case 9:
|
||||
n.StreetAddress = append(n.StreetAddress, value)
|
||||
case 10:
|
||||
n.Organization = append(n.Organization, value)
|
||||
case 11:
|
||||
n.OrganizationalUnit = append(n.OrganizationalUnit, value)
|
||||
case 17:
|
||||
n.PostalCode = append(n.PostalCode, value)
|
||||
case 42:
|
||||
n.GivenName = append(n.GivenName, value)
|
||||
case 97:
|
||||
n.OrganizationIDs = append(n.OrganizationIDs, value)
|
||||
}
|
||||
} else if t.Equal(oidDomainComponent) {
|
||||
n.DomainComponent = append(n.DomainComponent, value)
|
||||
} else if t.Equal(oidDNEmailAddress) {
|
||||
// Deprecated, see RFC 5280 Section 4.1.2.6
|
||||
n.EmailAddress = append(n.EmailAddress, value)
|
||||
} else if t.Equal(oidJurisdictionLocality) {
|
||||
n.JurisdictionLocality = append(n.JurisdictionLocality, value)
|
||||
} else if t.Equal(oidJurisdictionProvince) {
|
||||
n.JurisdictionProvince = append(n.JurisdictionProvince, value)
|
||||
} else if t.Equal(oidJurisdictionCountry) {
|
||||
n.JurisdictionCountry = append(n.JurisdictionCountry, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
oidCountry = []int{2, 5, 4, 6}
|
||||
oidOrganization = []int{2, 5, 4, 10}
|
||||
oidOrganizationalUnit = []int{2, 5, 4, 11}
|
||||
oidCommonName = []int{2, 5, 4, 3}
|
||||
oidSurname = []int{2, 5, 4, 4}
|
||||
oidSerialNumber = []int{2, 5, 4, 5}
|
||||
oidLocality = []int{2, 5, 4, 7}
|
||||
oidProvince = []int{2, 5, 4, 8}
|
||||
oidStreetAddress = []int{2, 5, 4, 9}
|
||||
oidPostalCode = []int{2, 5, 4, 17}
|
||||
oidGivenName = []int{2, 5, 4, 42}
|
||||
oidDomainComponent = []int{0, 9, 2342, 19200300, 100, 1, 25}
|
||||
oidDNEmailAddress = []int{1, 2, 840, 113549, 1, 9, 1}
|
||||
// EV
|
||||
oidJurisdictionLocality = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 1}
|
||||
oidJurisdictionProvince = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 2}
|
||||
oidJurisdictionCountry = []int{1, 3, 6, 1, 4, 1, 311, 60, 2, 1, 3}
|
||||
// QWACS
|
||||
oidOrganizationID = []int{2, 5, 4, 97}
|
||||
)
|
||||
|
||||
// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
|
||||
// and returns the new value. The relativeDistinguishedNameSET contains an
|
||||
// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
|
||||
// search for AttributeTypeAndValue.
|
||||
func (n Name) appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
|
||||
// NOTE: stdlib prevents adding if the oid is already present in n.ExtraNames
|
||||
//if len(values) == 0 || oidInAttributeTypeAndValue(oid, n.ExtraNames) {
|
||||
if len(values) == 0 {
|
||||
return in
|
||||
}
|
||||
|
||||
s := make([]AttributeTypeAndValue, len(values))
|
||||
for i, value := range values {
|
||||
s[i].Type = oid
|
||||
s[i].Value = value
|
||||
}
|
||||
|
||||
return append(in, s)
|
||||
}
|
||||
|
||||
// String returns an RDNSequence as comma seperated list of
|
||||
// AttributeTypeAndValues in canonical form.
|
||||
func (seq RDNSequence) String() string {
|
||||
out := make([]string, 0, len(seq))
|
||||
// An RDNSequence is effectively an [][]AttributeTypeAndValue
|
||||
for _, atvSet := range seq {
|
||||
for _, atv := range atvSet {
|
||||
// Convert each individual AttributeTypeAndValue to X=Y
|
||||
attrParts := make([]string, 0, 2)
|
||||
oidString := atv.Type.String()
|
||||
oidName, ok := oidDotNotationToNames[oidString]
|
||||
if ok {
|
||||
attrParts = append(attrParts, oidName.ShortName)
|
||||
} else {
|
||||
attrParts = append(attrParts, oidString)
|
||||
}
|
||||
switch value := atv.Value.(type) {
|
||||
case string:
|
||||
attrParts = append(attrParts, value)
|
||||
case []byte:
|
||||
attrParts = append(attrParts, string(value))
|
||||
default:
|
||||
continue
|
||||
}
|
||||
attrString := strings.Join(attrParts, "=")
|
||||
out = append(out, attrString)
|
||||
}
|
||||
}
|
||||
return strings.Join(out, ", ")
|
||||
}
|
||||
|
||||
// ToRDNSequence returns OriginalRDNS is populated. Otherwise, it builds an
|
||||
// RDNSequence in canonical order.
|
||||
func (n Name) ToRDNSequence() (ret RDNSequence) {
|
||||
if n.OriginalRDNS != nil {
|
||||
return n.OriginalRDNS
|
||||
}
|
||||
if len(n.CommonName) > 0 {
|
||||
ret = n.appendRDNs(ret, []string{n.CommonName}, oidCommonName)
|
||||
}
|
||||
ret = n.appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
|
||||
ret = n.appendRDNs(ret, n.Organization, oidOrganization)
|
||||
ret = n.appendRDNs(ret, n.StreetAddress, oidStreetAddress)
|
||||
ret = n.appendRDNs(ret, n.Locality, oidLocality)
|
||||
ret = n.appendRDNs(ret, n.Province, oidProvince)
|
||||
ret = n.appendRDNs(ret, n.PostalCode, oidPostalCode)
|
||||
ret = n.appendRDNs(ret, n.Country, oidCountry)
|
||||
ret = n.appendRDNs(ret, n.DomainComponent, oidDomainComponent)
|
||||
// EV Components
|
||||
ret = n.appendRDNs(ret, n.JurisdictionLocality, oidJurisdictionLocality)
|
||||
ret = n.appendRDNs(ret, n.JurisdictionProvince, oidJurisdictionProvince)
|
||||
ret = n.appendRDNs(ret, n.JurisdictionCountry, oidJurisdictionCountry)
|
||||
// QWACS
|
||||
ret = n.appendRDNs(ret, n.OrganizationIDs, oidOrganizationID)
|
||||
if len(n.SerialNumber) > 0 {
|
||||
ret = n.appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
|
||||
}
|
||||
ret = append(ret, n.ExtraNames)
|
||||
return ret
|
||||
}
|
||||
|
||||
// oidInAttributeTypeAndValue returns whether a type with the given OID exists
|
||||
// in atv.
|
||||
func oidInAttributeTypeAndValue(oid asn1.ObjectIdentifier, atv []AttributeTypeAndValue) bool {
|
||||
for _, a := range atv {
|
||||
if a.Type.Equal(oid) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CertificateList represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
|
||||
// signature.
|
||||
type CertificateList struct {
|
||||
TBSCertList TBSCertificateList
|
||||
SignatureAlgorithm AlgorithmIdentifier
|
||||
SignatureValue asn1.BitString
|
||||
}
|
||||
|
||||
// HasExpired reports whether now is past the expiry time of certList.
|
||||
func (certList *CertificateList) HasExpired(now time.Time) bool {
|
||||
return now.After(certList.TBSCertList.NextUpdate)
|
||||
}
|
||||
|
||||
// String returns a canonical representation of a DistinguishedName
|
||||
func (n *Name) String() string {
|
||||
seq := n.ToRDNSequence()
|
||||
return seq.String()
|
||||
}
|
||||
|
||||
// OtherName represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 4.2.1.6.
|
||||
type OtherName struct {
|
||||
TypeID asn1.ObjectIdentifier
|
||||
Value asn1.RawValue `asn1:"explicit"`
|
||||
}
|
||||
|
||||
// EDIPartyName represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 4.2.1.6.
|
||||
type EDIPartyName struct {
|
||||
NameAssigner string `asn1:"tag:0,optional,explicit" json:"name_assigner,omitempty"`
|
||||
PartyName string `asn1:"tag:1,explicit" json:"party_name"`
|
||||
}
|
||||
|
||||
// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 5.1.
|
||||
type TBSCertificateList struct {
|
||||
Raw asn1.RawContent
|
||||
Version int `asn1:"optional,default:0"`
|
||||
Signature AlgorithmIdentifier
|
||||
Issuer RDNSequence
|
||||
ThisUpdate time.Time
|
||||
NextUpdate time.Time `asn1:"optional"`
|
||||
RevokedCertificates []RevokedCertificate `asn1:"optional"`
|
||||
Extensions []Extension `asn1:"tag:0,optional,explicit"`
|
||||
}
|
||||
|
||||
// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
|
||||
// 5280, section 5.1.
|
||||
type RevokedCertificate struct {
|
||||
SerialNumber *big.Int
|
||||
RevocationTime time.Time
|
||||
Extensions []Extension `asn1:"optional"`
|
||||
}
|
173
vendor/github.com/zmap/zcrypto/x509/qc_statements.go
generated
vendored
Normal file
173
vendor/github.com/zmap/zcrypto/x509/qc_statements.go
generated
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
package x509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type QCStatementASN struct {
|
||||
StatementID asn1.ObjectIdentifier
|
||||
StatementInfo asn1.RawValue `asn1:"optional"`
|
||||
}
|
||||
|
||||
func (s *QCStatementASN) MarshalJSON() ([]byte, error) {
|
||||
aux := struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Value []byte `json:"value,omitempty"`
|
||||
}{
|
||||
ID: s.StatementID.String(),
|
||||
Value: s.StatementInfo.Bytes,
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
type QCStatementsASN struct {
|
||||
QCStatements []QCStatementASN
|
||||
}
|
||||
|
||||
// ETSI OIDS from https://www.etsi.org/deliver/etsi_en/319400_319499/31941205/02.02.03_20/en_31941205v020203a.pdf
|
||||
var (
|
||||
oidEtsiQcsQcCompliance = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 1}
|
||||
oidEtsiQcsQcLimitValue = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 2}
|
||||
oidEtsiQcsQcRetentionPeriod = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 3}
|
||||
oidEtsiQcsQcSSCD = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 4}
|
||||
oidEtsiQcsQcEuPDS = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 5}
|
||||
oidEtsiQcsQcType = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6}
|
||||
oidEtsiQcsQcCCLegislation = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 7}
|
||||
oidEtsiQcsQctEsign = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 1}
|
||||
oidEtsiQcsQctEseal = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 2}
|
||||
oidEtsiQcsQctWeb = asn1.ObjectIdentifier{0, 4, 0, 1862, 1, 6, 3}
|
||||
)
|
||||
|
||||
type QCStatements struct {
|
||||
StatementIDs []string `json:"ids,omitempty"`
|
||||
ParsedStatements *ParsedQCStatements `json:"parsed,omitempty"`
|
||||
}
|
||||
|
||||
type ParsedQCStatements struct {
|
||||
ETSICompliance []bool `json:"etsi_compliance,omitempty"`
|
||||
SSCD []bool `json:"sscd,omitempty"`
|
||||
Types []QCType `json:"types,omitempty"`
|
||||
Limit []MonetaryValue `json:"limit,omitempty"`
|
||||
PDSLocations []PDSLocations `json:"pds_locations,omitempty"`
|
||||
RetentionPeriod []int `json:"retention_period,omitempty"`
|
||||
Legislation []QCLegistation `json:"legislation,omitempty"`
|
||||
}
|
||||
|
||||
type MonetaryValue struct {
|
||||
Currency string `json:"currency,omitempty"`
|
||||
CurrencyNumber int `json:"currency_number,omitempty"`
|
||||
Amount int `json:"amount,omitempty"`
|
||||
Exponent int `json:"exponent,omitempty"`
|
||||
}
|
||||
|
||||
type monetaryValueASNString struct {
|
||||
Currency string `asn1:"printable"`
|
||||
Amount int
|
||||
Exponent int
|
||||
}
|
||||
|
||||
type monetaryValueASNNumber struct {
|
||||
Currency int
|
||||
Amount int
|
||||
Exponent int
|
||||
}
|
||||
|
||||
type PDSLocations struct {
|
||||
Locations []PDSLocation `json:"locations,omitempty"`
|
||||
}
|
||||
|
||||
type PDSLocation struct {
|
||||
URL string `json:"url,omitempty" asn1:"ia5"`
|
||||
Language string `json:"language,omitempty" asn1:"printable"`
|
||||
}
|
||||
|
||||
type QCType struct {
|
||||
TypeIdentifiers []asn1.ObjectIdentifier
|
||||
}
|
||||
|
||||
type QCLegistation struct {
|
||||
CountryCodes []string `json:"country_codes,omitempty"`
|
||||
}
|
||||
|
||||
func (qt *QCType) MarshalJSON() ([]byte, error) {
|
||||
aux := struct {
|
||||
Types []string `json:"ids,omitempty"`
|
||||
}{
|
||||
Types: make([]string, len(qt.TypeIdentifiers)),
|
||||
}
|
||||
for idx := range qt.TypeIdentifiers {
|
||||
aux.Types[idx] = qt.TypeIdentifiers[idx].String()
|
||||
}
|
||||
return json.Marshal(&aux)
|
||||
}
|
||||
|
||||
func (q *QCStatements) Parse(in *QCStatementsASN) error {
|
||||
q.StatementIDs = make([]string, len(in.QCStatements))
|
||||
known := ParsedQCStatements{}
|
||||
for i, s := range in.QCStatements {
|
||||
val := in.QCStatements[i].StatementInfo.FullBytes
|
||||
q.StatementIDs[i] = s.StatementID.String()
|
||||
if s.StatementID.Equal(oidEtsiQcsQcCompliance) {
|
||||
known.ETSICompliance = append(known.ETSICompliance, true)
|
||||
if val != nil {
|
||||
return errors.New("EtsiQcsQcCompliance QCStatement must not contain a statementInfo")
|
||||
}
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcLimitValue) {
|
||||
// TODO
|
||||
mvs := monetaryValueASNString{}
|
||||
mvn := monetaryValueASNNumber{}
|
||||
out := MonetaryValue{}
|
||||
if _, err := asn1.Unmarshal(val, &mvs); err == nil {
|
||||
out.Currency = mvs.Currency
|
||||
out.Amount = mvs.Amount
|
||||
out.Exponent = mvs.Exponent
|
||||
} else if _, err := asn1.Unmarshal(val, &mvn); err == nil {
|
||||
out.CurrencyNumber = mvn.Currency
|
||||
out.Amount = mvn.Amount
|
||||
out.Exponent = mvn.Exponent
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
known.Limit = append(known.Limit, out)
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcRetentionPeriod) {
|
||||
var retentionPeriod int
|
||||
if _, err := asn1.Unmarshal(val, &retentionPeriod); err != nil {
|
||||
return err
|
||||
}
|
||||
known.RetentionPeriod = append(known.RetentionPeriod, retentionPeriod)
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcSSCD) {
|
||||
known.SSCD = append(known.SSCD, true)
|
||||
if val != nil {
|
||||
return errors.New("EtsiQcsQcSSCD QCStatement must not contain a statementInfo")
|
||||
}
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcEuPDS) {
|
||||
locations := make([]PDSLocation, 0)
|
||||
if _, err := asn1.Unmarshal(val, &locations); err != nil {
|
||||
return err
|
||||
}
|
||||
known.PDSLocations = append(known.PDSLocations, PDSLocations{
|
||||
Locations: locations,
|
||||
})
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcType) {
|
||||
typeIds := make([]asn1.ObjectIdentifier, 0)
|
||||
if _, err := asn1.Unmarshal(val, &typeIds); err != nil {
|
||||
return err
|
||||
}
|
||||
known.Types = append(known.Types, QCType{
|
||||
TypeIdentifiers: typeIds,
|
||||
})
|
||||
} else if s.StatementID.Equal(oidEtsiQcsQcCCLegislation) {
|
||||
countryCodes := make([]string, 0)
|
||||
if _, err := asn1.Unmarshal(val, &countryCodes); err != nil {
|
||||
return err
|
||||
}
|
||||
known.Legislation = append(known.Legislation, QCLegistation{
|
||||
CountryCodes: countryCodes,
|
||||
})
|
||||
}
|
||||
}
|
||||
q.ParsedStatements = &known
|
||||
return nil
|
||||
}
|
105
vendor/github.com/zmap/zcrypto/x509/sec1.go
generated
vendored
Normal file
105
vendor/github.com/zmap/zcrypto/x509/sec1.go
generated
vendored
Normal file
|
@ -0,0 +1,105 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
const ecPrivKeyVersion = 1
|
||||
|
||||
// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
|
||||
// References:
|
||||
// RFC 5915
|
||||
// SEC1 - http://www.secg.org/sec1-v2.pdf
|
||||
// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
|
||||
// most cases it is not.
|
||||
type ecPrivateKey struct {
|
||||
Version int
|
||||
PrivateKey []byte
|
||||
NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
|
||||
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
|
||||
}
|
||||
|
||||
// ParseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
|
||||
func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
|
||||
return parseECPrivateKey(nil, der)
|
||||
}
|
||||
|
||||
// MarshalECPrivateKey marshals an EC private key into ASN.1, DER format.
|
||||
func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
|
||||
oid, ok := oidFromNamedCurve(key.Curve)
|
||||
if !ok {
|
||||
return nil, errors.New("x509: unknown elliptic curve")
|
||||
}
|
||||
|
||||
privateKeyBytes := key.D.Bytes()
|
||||
paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
|
||||
copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
|
||||
|
||||
return asn1.Marshal(ecPrivateKey{
|
||||
Version: 1,
|
||||
PrivateKey: paddedPrivateKey,
|
||||
NamedCurveOID: oid,
|
||||
PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
|
||||
})
|
||||
}
|
||||
|
||||
// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
|
||||
// The OID for the named curve may be provided from another source (such as
|
||||
// the PKCS8 container) - if it is provided then use this instead of the OID
|
||||
// that may exist in the EC private key structure.
|
||||
func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
|
||||
var privKey ecPrivateKey
|
||||
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
|
||||
return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
|
||||
}
|
||||
if privKey.Version != ecPrivKeyVersion {
|
||||
return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
|
||||
}
|
||||
|
||||
var curve elliptic.Curve
|
||||
if namedCurveOID != nil {
|
||||
curve = namedCurveFromOID(*namedCurveOID)
|
||||
} else {
|
||||
curve = namedCurveFromOID(privKey.NamedCurveOID)
|
||||
}
|
||||
if curve == nil {
|
||||
return nil, errors.New("x509: unknown elliptic curve")
|
||||
}
|
||||
|
||||
k := new(big.Int).SetBytes(privKey.PrivateKey)
|
||||
curveOrder := curve.Params().N
|
||||
if k.Cmp(curveOrder) >= 0 {
|
||||
return nil, errors.New("x509: invalid elliptic curve private key value")
|
||||
}
|
||||
priv := new(ecdsa.PrivateKey)
|
||||
priv.Curve = curve
|
||||
priv.D = k
|
||||
|
||||
privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
|
||||
|
||||
// Some private keys have leading zero padding. This is invalid
|
||||
// according to [SEC1], but this code will ignore it.
|
||||
for len(privKey.PrivateKey) > len(privateKey) {
|
||||
if privKey.PrivateKey[0] != 0 {
|
||||
return nil, errors.New("x509: invalid private key length")
|
||||
}
|
||||
privKey.PrivateKey = privKey.PrivateKey[1:]
|
||||
}
|
||||
|
||||
// Some private keys remove all leading zeros, this is also invalid
|
||||
// according to [SEC1] but since OpenSSL used to do this, we ignore
|
||||
// this too.
|
||||
copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
|
||||
priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
|
||||
|
||||
return priv, nil
|
||||
}
|
158
vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go
generated
vendored
Normal file
158
vendor/github.com/zmap/zcrypto/x509/tor_service_descriptor.go
generated
vendored
Normal file
|
@ -0,0 +1,158 @@
|
|||
package x509
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"github.com/zmap/zcrypto/x509/pkix"
|
||||
)
|
||||
|
||||
var (
|
||||
// oidBRTorServiceDescriptor is the assigned OID for the CAB Forum Tor Service
|
||||
// Descriptor Hash extension (see EV Guidelines Appendix F)
|
||||
oidBRTorServiceDescriptor = asn1.ObjectIdentifier{2, 23, 140, 1, 31}
|
||||
)
|
||||
|
||||
// TorServiceDescriptorHash is a structure corrsponding to the
|
||||
// TorServiceDescriptorHash SEQUENCE described in Appendix F ("Issuance of
|
||||
// Certificates for .onion Domain Names").
|
||||
//
|
||||
// Each TorServiceDescriptorHash holds an onion URI (a utf8 string with the
|
||||
// .onion address that was validated), a hash algorithm name (computed based on
|
||||
// the pkix.AlgorithmIdentifier in the TorServiceDescriptorHash), the hash bytes
|
||||
// (computed over the DER encoding of the ASN.1 SubjectPublicKey of the .onion
|
||||
// service), and the number of bits in the hash bytes.
|
||||
type TorServiceDescriptorHash struct {
|
||||
Onion string `json:"onion"`
|
||||
Algorithm pkix.AlgorithmIdentifier `json:"-"`
|
||||
AlgorithmName string `json:"algorithm_name"`
|
||||
Hash CertificateFingerprint `json:"hash"`
|
||||
HashBits int `json:"hash_bits"`
|
||||
}
|
||||
|
||||
// parseTorServiceDescriptorSyntax parses the given pkix.Extension (assumed to
|
||||
// have OID == oidBRTorServiceDescriptor) and returns a slice of parsed
|
||||
// TorServiceDescriptorHash objects, or an error. An error will be returned if
|
||||
// there are any structural errors related to the ASN.1 content (wrong tags,
|
||||
// trailing data, missing fields, etc).
|
||||
func parseTorServiceDescriptorSyntax(ext pkix.Extension) ([]*TorServiceDescriptorHash, error) {
|
||||
// TorServiceDescriptorSyntax ::=
|
||||
// SEQUENCE ( 1..MAX ) of TorServiceDescriptorHash
|
||||
var seq asn1.RawValue
|
||||
rest, err := asn1.Unmarshal(ext.Value, &seq)
|
||||
if err != nil {
|
||||
return nil, asn1.SyntaxError{
|
||||
Msg: "unable to unmarshal outer TorServiceDescriptor SEQUENCE",
|
||||
}
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
return nil, asn1.SyntaxError{
|
||||
Msg: "trailing data after outer TorServiceDescriptor SEQUENCE",
|
||||
}
|
||||
}
|
||||
if seq.Tag != asn1.TagSequence || seq.Class != asn1.ClassUniversal || !seq.IsCompound {
|
||||
return nil, asn1.SyntaxError{
|
||||
Msg: "invalid outer TorServiceDescriptor SEQUENCE",
|
||||
}
|
||||
}
|
||||
|
||||
var descriptors []*TorServiceDescriptorHash
|
||||
rest = seq.Bytes
|
||||
for len(rest) > 0 {
|
||||
var descriptor *TorServiceDescriptorHash
|
||||
descriptor, rest, err = parseTorServiceDescriptorHash(rest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
descriptors = append(descriptors, descriptor)
|
||||
}
|
||||
return descriptors, nil
|
||||
}
|
||||
|
||||
// parseTorServiceDescriptorHash unmarshals a SEQUENCE from the provided data
|
||||
// and parses a TorServiceDescriptorHash using the data contained in the
|
||||
// sequence. The TorServiceDescriptorHash object and the remaining data are
|
||||
// returned if no error occurs.
|
||||
func parseTorServiceDescriptorHash(data []byte) (*TorServiceDescriptorHash, []byte, error) {
|
||||
// TorServiceDescriptorHash:: = SEQUENCE {
|
||||
// onionURI UTF8String
|
||||
// algorithm AlgorithmIdentifier
|
||||
// subjectPublicKeyHash BIT STRING
|
||||
// }
|
||||
var outerSeq asn1.RawValue
|
||||
var err error
|
||||
data, err = asn1.Unmarshal(data, &outerSeq)
|
||||
if err != nil {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "error unmarshaling TorServiceDescriptorHash SEQUENCE",
|
||||
}
|
||||
}
|
||||
if outerSeq.Tag != asn1.TagSequence ||
|
||||
outerSeq.Class != asn1.ClassUniversal ||
|
||||
!outerSeq.IsCompound {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "TorServiceDescriptorHash missing compound SEQUENCE tag",
|
||||
}
|
||||
}
|
||||
fieldData := outerSeq.Bytes
|
||||
|
||||
// Unmarshal and verify the structure of the onionURI UTF8String field.
|
||||
var rawOnionURI asn1.RawValue
|
||||
fieldData, err = asn1.Unmarshal(fieldData, &rawOnionURI)
|
||||
if err != nil {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "error unmarshaling TorServiceDescriptorHash onionURI",
|
||||
}
|
||||
}
|
||||
if rawOnionURI.Tag != asn1.TagUTF8String ||
|
||||
rawOnionURI.Class != asn1.ClassUniversal ||
|
||||
rawOnionURI.IsCompound {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "TorServiceDescriptorHash missing non-compound UTF8String tag",
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarshal and verify the structure of the algorithm UTF8String field.
|
||||
var algorithm pkix.AlgorithmIdentifier
|
||||
fieldData, err = asn1.Unmarshal(fieldData, &algorithm)
|
||||
if err != nil {
|
||||
return nil, nil, asn1.SyntaxError{
|
||||
Msg: "error unmarshaling TorServiceDescriptorHash algorithm",
|
||||
}
|
||||
}
|
||||
|
||||
var algorithmName string
|
||||
if algorithm.Algorithm.Equal(oidSHA256) {
|
||||
algorithmName = "SHA256"
|
||||
} else if algorithm.Algorithm.Equal(oidSHA384) {
|
||||
algorithmName = "SHA384"
|
||||
} else if algorithm.Algorithm.Equal(oidSHA512) {
|
||||
algorithmName = "SHA512"
|
||||
} else {
|
||||
algorithmName = "Unknown"
|
||||
}
|
||||
|
||||
// Unmarshal and verify the structure of the Subject Public Key Hash BitString
|
||||
// field.
|
||||
var spkh asn1.BitString
|
||||
fieldData, err = asn1.Unmarshal(fieldData, &spkh)
|
||||
if err != nil {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "error unmarshaling TorServiceDescriptorHash Hash",
|
||||
}
|
||||
}
|
||||
|
||||
// There should be no trailing data after the TorServiceDescriptorHash
|
||||
// SEQUENCE.
|
||||
if len(fieldData) > 0 {
|
||||
return nil, data, asn1.SyntaxError{
|
||||
Msg: "trailing data after TorServiceDescriptorHash",
|
||||
}
|
||||
}
|
||||
|
||||
return &TorServiceDescriptorHash{
|
||||
Onion: string(rawOnionURI.Bytes),
|
||||
Algorithm: algorithm,
|
||||
AlgorithmName: algorithmName,
|
||||
HashBits: spkh.BitLength,
|
||||
Hash: CertificateFingerprint(spkh.Bytes),
|
||||
}, data, nil
|
||||
}
|
60
vendor/github.com/zmap/zcrypto/x509/validation.go
generated
vendored
Normal file
60
vendor/github.com/zmap/zcrypto/x509/validation.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import "time"
|
||||
|
||||
// Validation stores different validation levels for a given certificate
|
||||
type Validation struct {
|
||||
BrowserTrusted bool `json:"browser_trusted"`
|
||||
BrowserError string `json:"browser_error,omitempty"`
|
||||
MatchesDomain bool `json:"matches_domain,omitempty"`
|
||||
Domain string `json:"-"`
|
||||
}
|
||||
|
||||
// ValidateWithStupidDetail fills out a Validation struct given a leaf
|
||||
// certificate and intermediates / roots. If opts.DNSName is set, then it will
|
||||
// also check if the domain matches.
|
||||
//
|
||||
// Deprecated: Use verifier.Verify() instead.
|
||||
func (c *Certificate) ValidateWithStupidDetail(opts VerifyOptions) (chains []CertificateChain, validation *Validation, err error) {
|
||||
|
||||
// Manually set the time, so that all verifies we do get the same time
|
||||
if opts.CurrentTime.IsZero() {
|
||||
opts.CurrentTime = time.Now()
|
||||
}
|
||||
|
||||
// XXX: Don't pass a KeyUsage to the Verify API
|
||||
opts.KeyUsages = nil
|
||||
domain := opts.DNSName
|
||||
opts.DNSName = ""
|
||||
|
||||
out := new(Validation)
|
||||
out.Domain = domain
|
||||
|
||||
if chains, _, _, err = c.Verify(opts); err != nil {
|
||||
out.BrowserError = err.Error()
|
||||
} else {
|
||||
out.BrowserTrusted = true
|
||||
}
|
||||
|
||||
if domain != "" {
|
||||
nameErr := c.VerifyHostname(domain)
|
||||
if nameErr != nil {
|
||||
out.MatchesDomain = false
|
||||
} else {
|
||||
out.MatchesDomain = true
|
||||
}
|
||||
|
||||
// Make sure we return an error if either chain building or hostname
|
||||
// verification fails.
|
||||
if err == nil && nameErr != nil {
|
||||
err = nameErr
|
||||
}
|
||||
}
|
||||
validation = out
|
||||
|
||||
return
|
||||
}
|
635
vendor/github.com/zmap/zcrypto/x509/verify.go
generated
vendored
Normal file
635
vendor/github.com/zmap/zcrypto/x509/verify.go
generated
vendored
Normal file
|
@ -0,0 +1,635 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type InvalidReason int
|
||||
|
||||
const (
|
||||
// NotAuthorizedToSign results when a certificate is signed by another
|
||||
// which isn't marked as a CA certificate.
|
||||
NotAuthorizedToSign InvalidReason = iota
|
||||
|
||||
// Expired results when a certificate has expired, based on the time
|
||||
// given in the VerifyOptions.
|
||||
Expired
|
||||
|
||||
// CANotAuthorizedForThisName results when an intermediate or root
|
||||
// certificate has a name constraint which doesn't include the name
|
||||
// being checked.
|
||||
CANotAuthorizedForThisName
|
||||
|
||||
// CANotAuthorizedForThisEmail results when an intermediate or root
|
||||
// certificate has a name constraint which doesn't include the email
|
||||
// being checked.
|
||||
CANotAuthorizedForThisEmail
|
||||
|
||||
// CANotAuthorizedForThisIP results when an intermediate or root
|
||||
// certificate has a name constraint which doesn't include the IP
|
||||
// being checked.
|
||||
CANotAuthorizedForThisIP
|
||||
|
||||
// CANotAuthorizedForThisDirectory results when an intermediate or root
|
||||
// certificate has a name constraint which doesn't include the directory
|
||||
// being checked.
|
||||
CANotAuthorizedForThisDirectory
|
||||
|
||||
// TooManyIntermediates results when a path length constraint is
|
||||
// violated.
|
||||
TooManyIntermediates
|
||||
|
||||
// IncompatibleUsage results when the certificate's key usage indicates
|
||||
// that it may only be used for a different purpose.
|
||||
IncompatibleUsage
|
||||
|
||||
// NameMismatch results when the subject name of a parent certificate
|
||||
// does not match the issuer name in the child.
|
||||
NameMismatch
|
||||
|
||||
// NeverValid results when the certificate could never have been valid due to
|
||||
// some date-related issue, e.g. NotBefore > NotAfter.
|
||||
NeverValid
|
||||
|
||||
// IsSelfSigned results when the certificate is self-signed and not a trusted
|
||||
// root.
|
||||
IsSelfSigned
|
||||
)
|
||||
|
||||
// CertificateInvalidError results when an odd error occurs. Users of this
|
||||
// library probably want to handle all these errors uniformly.
|
||||
type CertificateInvalidError struct {
|
||||
Cert *Certificate
|
||||
Reason InvalidReason
|
||||
}
|
||||
|
||||
func (e CertificateInvalidError) Error() string {
|
||||
switch e.Reason {
|
||||
case NotAuthorizedToSign:
|
||||
return "x509: certificate is not authorized to sign other certificates"
|
||||
case Expired:
|
||||
return "x509: certificate has expired or is not yet valid"
|
||||
case CANotAuthorizedForThisName:
|
||||
return "x509: a root or intermediate certificate is not authorized to sign in this domain"
|
||||
case CANotAuthorizedForThisEmail:
|
||||
return "x509: a root or intermediate certificate is not authorized to sign this email address"
|
||||
case CANotAuthorizedForThisIP:
|
||||
return "x509: a root or intermediate certificate is not authorized to sign this IP address"
|
||||
case CANotAuthorizedForThisDirectory:
|
||||
return "x509: a root or intermediate certificate is not authorized to sign in this directory"
|
||||
case TooManyIntermediates:
|
||||
return "x509: too many intermediates for path length constraint"
|
||||
case IncompatibleUsage:
|
||||
return "x509: certificate specifies an incompatible key usage"
|
||||
case NameMismatch:
|
||||
return "x509: issuer name does not match subject from issuing certificate"
|
||||
case NeverValid:
|
||||
return "x509: certificate will never be valid"
|
||||
}
|
||||
return "x509: unknown error"
|
||||
}
|
||||
|
||||
// HostnameError results when the set of authorized names doesn't match the
|
||||
// requested name.
|
||||
type HostnameError struct {
|
||||
Certificate *Certificate
|
||||
Host string
|
||||
}
|
||||
|
||||
func (h HostnameError) Error() string {
|
||||
c := h.Certificate
|
||||
|
||||
var valid string
|
||||
if ip := net.ParseIP(h.Host); ip != nil {
|
||||
// Trying to validate an IP
|
||||
if len(c.IPAddresses) == 0 {
|
||||
return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
|
||||
}
|
||||
for _, san := range c.IPAddresses {
|
||||
if len(valid) > 0 {
|
||||
valid += ", "
|
||||
}
|
||||
valid += san.String()
|
||||
}
|
||||
} else {
|
||||
if c.hasSANExtension() {
|
||||
valid = strings.Join(c.DNSNames, ", ")
|
||||
} else {
|
||||
valid = c.Subject.CommonName
|
||||
}
|
||||
}
|
||||
|
||||
if len(valid) == 0 {
|
||||
return "x509: certificate is not valid for any names, but wanted to match " + h.Host
|
||||
}
|
||||
return "x509: certificate is valid for " + valid + ", not " + h.Host
|
||||
}
|
||||
|
||||
// UnknownAuthorityError results when the certificate issuer is unknown
|
||||
type UnknownAuthorityError struct {
|
||||
Cert *Certificate
|
||||
// hintErr contains an error that may be helpful in determining why an
|
||||
// authority wasn't found.
|
||||
hintErr error
|
||||
// hintCert contains a possible authority certificate that was rejected
|
||||
// because of the error in hintErr.
|
||||
hintCert *Certificate
|
||||
}
|
||||
|
||||
func (e UnknownAuthorityError) Error() string {
|
||||
s := "x509: certificate signed by unknown authority"
|
||||
if e.hintErr != nil {
|
||||
certName := e.hintCert.Subject.CommonName
|
||||
if len(certName) == 0 {
|
||||
if len(e.hintCert.Subject.Organization) > 0 {
|
||||
certName = e.hintCert.Subject.Organization[0]
|
||||
} else {
|
||||
certName = "serial:" + e.hintCert.SerialNumber.String()
|
||||
}
|
||||
}
|
||||
s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// SystemRootsError results when we fail to load the system root certificates.
|
||||
type SystemRootsError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (se SystemRootsError) Error() string {
|
||||
msg := "x509: failed to load system roots and no roots provided"
|
||||
if se.Err != nil {
|
||||
return msg + "; " + se.Err.Error()
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
// errNotParsed is returned when a certificate without ASN.1 contents is
|
||||
// verified. Platform-specific verification needs the ASN.1 contents.
|
||||
var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
|
||||
|
||||
const maxIntermediateCount = 10
|
||||
|
||||
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
|
||||
// because other PKIX verification APIs have ended up needing many options.
|
||||
type VerifyOptions struct {
|
||||
DNSName string
|
||||
EmailAddress string
|
||||
IPAddress net.IP
|
||||
|
||||
Intermediates *CertPool
|
||||
Roots *CertPool // if nil, the system roots are used
|
||||
CurrentTime time.Time // if zero, the current time is used
|
||||
// KeyUsage specifies which Extended Key Usage values are acceptable.
|
||||
// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
|
||||
// constraint down the chain which mirrors Windows CryptoAPI behaviour,
|
||||
// but not the spec. To accept any key usage, include ExtKeyUsageAny.
|
||||
KeyUsages []ExtKeyUsage
|
||||
}
|
||||
|
||||
const (
|
||||
leafCertificate = iota
|
||||
intermediateCertificate
|
||||
rootCertificate
|
||||
)
|
||||
|
||||
func matchNameConstraint(domain, constraint string) bool {
|
||||
// The meaning of zero length constraints is not specified, but this
|
||||
// code follows NSS and accepts them as matching everything.
|
||||
if len(constraint) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(domain) < len(constraint) {
|
||||
return false
|
||||
}
|
||||
|
||||
prefixLen := len(domain) - len(constraint)
|
||||
if !strings.EqualFold(domain[prefixLen:], constraint) {
|
||||
return false
|
||||
}
|
||||
|
||||
if prefixLen == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
isSubdomain := domain[prefixLen-1] == '.'
|
||||
constraintHasLeadingDot := constraint[0] == '.'
|
||||
return isSubdomain != constraintHasLeadingDot
|
||||
}
|
||||
|
||||
// NOTE: the stdlib function does many more checks and is preferable. For backwards compatibility using this version
|
||||
|
||||
// isValid performs validity checks on the c. It will never return a
|
||||
// date-related error.
|
||||
func (c *Certificate) isValid(certType CertificateType, currentChain CertificateChain) error {
|
||||
|
||||
// KeyUsage status flags are ignored. From Engineering Security, Peter
|
||||
// Gutmann: A European government CA marked its signing certificates as
|
||||
// being valid for encryption only, but no-one noticed. Another
|
||||
// European CA marked its signature keys as not being valid for
|
||||
// signatures. A different CA marked its own trusted root certificate
|
||||
// as being invalid for certificate signing. Another national CA
|
||||
// distributed a certificate to be used to encrypt data for the
|
||||
// country’s tax authority that was marked as only being usable for
|
||||
// digital signatures but not for encryption. Yet another CA reversed
|
||||
// the order of the bit flags in the keyUsage due to confusion over
|
||||
// encoding endianness, essentially setting a random keyUsage in
|
||||
// certificates that it issued. Another CA created a self-invalidating
|
||||
// certificate by adding a certificate policy statement stipulating
|
||||
// that the certificate had to be used strictly as specified in the
|
||||
// keyUsage, and a keyUsage containing a flag indicating that the RSA
|
||||
// encryption key could only be used for Diffie-Hellman key agreement.
|
||||
|
||||
if certType == CertificateTypeIntermediate && (!c.BasicConstraintsValid || !c.IsCA) {
|
||||
return CertificateInvalidError{c, NotAuthorizedToSign}
|
||||
}
|
||||
|
||||
if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
|
||||
numIntermediates := len(currentChain) - 1
|
||||
if numIntermediates > c.MaxPathLen {
|
||||
return CertificateInvalidError{c, TooManyIntermediates}
|
||||
}
|
||||
}
|
||||
|
||||
if len(currentChain) > maxIntermediateCount {
|
||||
return CertificateInvalidError{c, TooManyIntermediates}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify attempts to verify c by building one or more chains from c to a
|
||||
// certificate in opts.Roots, using certificates in opts.Intermediates if
|
||||
// needed. If successful, it returns one or more chains where the first
|
||||
// element of the chain is c and the last element is from opts.Roots.
|
||||
//
|
||||
// If opts.Roots is nil and system roots are unavailable the returned error
|
||||
// will be of type SystemRootsError.
|
||||
//
|
||||
// WARNING: this doesn't do any revocation checking.
|
||||
func (c *Certificate) Verify(opts VerifyOptions) (current, expired, never []CertificateChain, err error) {
|
||||
|
||||
if opts.Roots == nil {
|
||||
err = SystemRootsError{}
|
||||
return
|
||||
}
|
||||
|
||||
err = c.isValid(CertificateTypeLeaf, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
candidateChains, err := c.buildChains(make(map[int][]CertificateChain), []*Certificate{c}, &opts)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
keyUsages := opts.KeyUsages
|
||||
if len(keyUsages) == 0 {
|
||||
keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
|
||||
}
|
||||
|
||||
// If any key usage is acceptable then we're done.
|
||||
hasKeyUsageAny := false
|
||||
for _, usage := range keyUsages {
|
||||
if usage == ExtKeyUsageAny {
|
||||
hasKeyUsageAny = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var chains []CertificateChain
|
||||
if hasKeyUsageAny {
|
||||
chains = candidateChains
|
||||
} else {
|
||||
for _, candidate := range candidateChains {
|
||||
if checkChainForKeyUsage(candidate, keyUsages) {
|
||||
chains = append(chains, candidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(chains) == 0 {
|
||||
err = CertificateInvalidError{c, IncompatibleUsage}
|
||||
return
|
||||
}
|
||||
|
||||
current, expired, never = FilterByDate(chains, opts.CurrentTime)
|
||||
if len(current) == 0 {
|
||||
if len(expired) > 0 {
|
||||
err = CertificateInvalidError{c, Expired}
|
||||
} else if len(never) > 0 {
|
||||
err = CertificateInvalidError{c, NeverValid}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(opts.DNSName) > 0 {
|
||||
err = c.VerifyHostname(opts.DNSName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
|
||||
n := make([]*Certificate, len(chain)+1)
|
||||
copy(n, chain)
|
||||
n[len(chain)] = cert
|
||||
return n
|
||||
}
|
||||
|
||||
// buildChains returns all chains of length < maxIntermediateCount. Chains begin
|
||||
// the certificate being validated (chain[0] = c), and end at a root. It
|
||||
// enforces that all intermediates can sign certificates, and checks signatures.
|
||||
// It does not enforce expiration.
|
||||
func (c *Certificate) buildChains(cache map[int][]CertificateChain, currentChain CertificateChain, opts *VerifyOptions) (chains []CertificateChain, err error) {
|
||||
|
||||
// If the certificate being validated is a root, add the chain of length one
|
||||
// containing just the root. Only do this on the first call to buildChains,
|
||||
// when the len(currentChain) = 1.
|
||||
if len(currentChain) == 1 && opts.Roots.Contains(c) {
|
||||
chains = append(chains, CertificateChain{c})
|
||||
}
|
||||
|
||||
if len(chains) == 0 && c.SelfSigned {
|
||||
err = CertificateInvalidError{c, IsSelfSigned}
|
||||
}
|
||||
|
||||
// Find roots that signed c and have matching SKID/AKID and Subject/Issuer.
|
||||
possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c)
|
||||
|
||||
// If any roots are parents of c, create new chain for each one of them.
|
||||
for _, rootNum := range possibleRoots {
|
||||
root := opts.Roots.certs[rootNum]
|
||||
err = root.isValid(CertificateTypeRoot, currentChain)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if !currentChain.CertificateInChain(root) {
|
||||
chains = append(chains, currentChain.AppendToFreshChain(root))
|
||||
}
|
||||
}
|
||||
|
||||
// The root chains of length N+1 are now "done". Now we'll look for any
|
||||
// intermediates that issue this certificate, meaning that any chain to a root
|
||||
// through these intermediates is at least length N+2.
|
||||
possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c)
|
||||
|
||||
for _, intermediateNum := range possibleIntermediates {
|
||||
intermediate := opts.Intermediates.certs[intermediateNum]
|
||||
if opts.Roots.Contains(intermediate) {
|
||||
continue
|
||||
}
|
||||
if currentChain.CertificateSubjectAndKeyInChain(intermediate) {
|
||||
continue
|
||||
}
|
||||
err = intermediate.isValid(CertificateTypeIntermediate, currentChain)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// We don't want to add any certificate to chains that doesn't somehow get
|
||||
// to a root. We don't know if all chains through the intermediates will end
|
||||
// at a root, so we slice off the back half of the chain and try to build
|
||||
// that part separately.
|
||||
childChains, ok := cache[intermediateNum]
|
||||
if !ok {
|
||||
childChains, err = intermediate.buildChains(cache, currentChain.AppendToFreshChain(intermediate), opts)
|
||||
cache[intermediateNum] = childChains
|
||||
}
|
||||
chains = append(chains, childChains...)
|
||||
}
|
||||
|
||||
if len(chains) > 0 {
|
||||
err = nil
|
||||
}
|
||||
|
||||
if len(chains) == 0 && err == nil {
|
||||
hintErr := rootErr
|
||||
hintCert := failedRoot
|
||||
if hintErr == nil {
|
||||
hintErr = intermediateErr
|
||||
hintCert = failedIntermediate
|
||||
}
|
||||
err = UnknownAuthorityError{c, hintErr, hintCert}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func matchHostnames(pattern, host string) bool {
|
||||
host = strings.TrimSuffix(host, ".")
|
||||
pattern = strings.TrimSuffix(pattern, ".")
|
||||
|
||||
if len(pattern) == 0 || len(host) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
patternParts := strings.Split(pattern, ".")
|
||||
hostParts := strings.Split(host, ".")
|
||||
|
||||
if len(patternParts) != len(hostParts) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, patternPart := range patternParts {
|
||||
if /*i == 0 &&*/ patternPart == "*" {
|
||||
continue
|
||||
}
|
||||
if patternPart != hostParts[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
|
||||
// an explicitly ASCII function to avoid any sharp corners resulting from
|
||||
// performing Unicode operations on DNS labels.
|
||||
func toLowerCaseASCII(in string) string {
|
||||
// If the string is already lower-case then there's nothing to do.
|
||||
isAlreadyLowerCase := true
|
||||
for _, c := range in {
|
||||
if c == utf8.RuneError {
|
||||
// If we get a UTF-8 error then there might be
|
||||
// upper-case ASCII bytes in the invalid sequence.
|
||||
isAlreadyLowerCase = false
|
||||
break
|
||||
}
|
||||
if 'A' <= c && c <= 'Z' {
|
||||
isAlreadyLowerCase = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if isAlreadyLowerCase {
|
||||
return in
|
||||
}
|
||||
|
||||
out := []byte(in)
|
||||
for i, c := range out {
|
||||
if 'A' <= c && c <= 'Z' {
|
||||
out[i] += 'a' - 'A'
|
||||
}
|
||||
}
|
||||
return string(out)
|
||||
}
|
||||
|
||||
// VerifyHostname returns nil if c is a valid certificate for the named host.
|
||||
// Otherwise it returns an error describing the mismatch.
|
||||
func (c *Certificate) VerifyHostname(h string) error {
|
||||
// IP addresses may be written in [ ].
|
||||
candidateIP := h
|
||||
if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
|
||||
candidateIP = h[1 : len(h)-1]
|
||||
}
|
||||
if ip := net.ParseIP(candidateIP); ip != nil {
|
||||
// We only match IP addresses against IP SANs.
|
||||
// https://tools.ietf.org/html/rfc6125#appendix-B.2
|
||||
for _, candidate := range c.IPAddresses {
|
||||
if ip.Equal(candidate) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return HostnameError{c, candidateIP}
|
||||
}
|
||||
|
||||
lowered := toLowerCaseASCII(h)
|
||||
|
||||
if c.hasSANExtension() {
|
||||
for _, match := range c.DNSNames {
|
||||
if matchHostnames(toLowerCaseASCII(match), lowered) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// If Subject Alt Name is given, we ignore the common name.
|
||||
} else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return HostnameError{c, h}
|
||||
}
|
||||
|
||||
func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
|
||||
usages := make([]ExtKeyUsage, len(keyUsages))
|
||||
copy(usages, keyUsages)
|
||||
|
||||
if len(chain) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
usagesRemaining := len(usages)
|
||||
|
||||
// We walk down the list and cross out any usages that aren't supported
|
||||
// by each certificate. If we cross out all the usages, then the chain
|
||||
// is unacceptable.
|
||||
|
||||
NextCert:
|
||||
for i := len(chain) - 1; i >= 0; i-- {
|
||||
cert := chain[i]
|
||||
if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
|
||||
// The certificate doesn't have any extended key usage specified.
|
||||
continue
|
||||
}
|
||||
|
||||
for _, usage := range cert.ExtKeyUsage {
|
||||
if usage == ExtKeyUsageAny {
|
||||
// The certificate is explicitly good for any usage.
|
||||
continue NextCert
|
||||
}
|
||||
}
|
||||
|
||||
const invalidUsage ExtKeyUsage = -1
|
||||
|
||||
NextRequestedUsage:
|
||||
for i, requestedUsage := range usages {
|
||||
if requestedUsage == invalidUsage {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, usage := range cert.ExtKeyUsage {
|
||||
if requestedUsage == usage {
|
||||
continue NextRequestedUsage
|
||||
} else if requestedUsage == ExtKeyUsageServerAuth &&
|
||||
(usage == ExtKeyUsageNetscapeServerGatedCrypto ||
|
||||
usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
|
||||
// In order to support COMODO
|
||||
// certificate chains, we have to
|
||||
// accept Netscape or Microsoft SGC
|
||||
// usages as equal to ServerAuth.
|
||||
continue NextRequestedUsage
|
||||
}
|
||||
}
|
||||
|
||||
usages[i] = invalidUsage
|
||||
usagesRemaining--
|
||||
if usagesRemaining == 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// earlier returns the earlier of a and b
|
||||
func earlier(a, b time.Time) time.Time {
|
||||
if a.Before(b) {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// later returns the later of a and b
|
||||
func later(a, b time.Time) time.Time {
|
||||
if a.After(b) {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// check expirations divides chains into a set of disjoint chains, containing
|
||||
// current chains valid now, expired chains that were valid at some point, and
|
||||
// the set of chains that were never valid.
|
||||
func FilterByDate(chains []CertificateChain, now time.Time) (current, expired, never []CertificateChain) {
|
||||
for _, chain := range chains {
|
||||
if len(chain) == 0 {
|
||||
continue
|
||||
}
|
||||
leaf := chain[0]
|
||||
lowerBound := leaf.NotBefore
|
||||
upperBound := leaf.NotAfter
|
||||
for _, c := range chain[1:] {
|
||||
lowerBound = later(lowerBound, c.NotBefore)
|
||||
upperBound = earlier(upperBound, c.NotAfter)
|
||||
}
|
||||
valid := lowerBound.Before(now) && upperBound.After(now)
|
||||
wasValid := lowerBound.Before(upperBound)
|
||||
if valid && !wasValid {
|
||||
// Math/logic tells us this is impossible.
|
||||
panic("valid && !wasValid should not be possible")
|
||||
}
|
||||
if valid {
|
||||
current = append(current, chain)
|
||||
} else if wasValid {
|
||||
expired = append(expired, chain)
|
||||
} else {
|
||||
never = append(never, chain)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
3042
vendor/github.com/zmap/zcrypto/x509/x509.go
generated
vendored
Normal file
3042
vendor/github.com/zmap/zcrypto/x509/x509.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
30
vendor/github.com/zmap/zlint/v3/.goreleaser.yml
generated
vendored
Normal file
30
vendor/github.com/zmap/zlint/v3/.goreleaser.yml
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
project_name: zlint
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
builds:
|
||||
-
|
||||
main: ./cmd/zlint/main.go
|
||||
binary: zlint
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- freebsd
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
archives:
|
||||
-
|
||||
wrap_in_directory: true
|
||||
replacements:
|
||||
darwin: Darwin
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
amd64: x86_64
|
||||
snapshot:
|
||||
name_template: "{{ .Tag }}-next"
|
||||
release:
|
||||
draft: true
|
||||
prerelease: auto
|
202
vendor/github.com/zmap/zlint/v3/LICENSE
generated
vendored
Normal file
202
vendor/github.com/zmap/zlint/v3/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Regents of the University of Michigan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
96
vendor/github.com/zmap/zlint/v3/lint/base.go
generated
vendored
Normal file
96
vendor/github.com/zmap/zlint/v3/lint/base.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
package lint
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
// LintInterface is implemented by each Lint.
|
||||
type LintInterface interface {
|
||||
// Initialize runs once per-lint. It is called during RegisterLint().
|
||||
Initialize() error
|
||||
|
||||
// CheckApplies runs once per certificate. It returns true if the Lint should
|
||||
// run on the given certificate. If CheckApplies returns false, the Lint
|
||||
// result is automatically set to NA without calling CheckEffective() or
|
||||
// Run().
|
||||
CheckApplies(c *x509.Certificate) bool
|
||||
|
||||
// Execute() is the body of the lint. It is called for every certificate for
|
||||
// which CheckApplies() returns true.
|
||||
Execute(c *x509.Certificate) *LintResult
|
||||
}
|
||||
|
||||
// A Lint struct represents a single lint, e.g.
|
||||
// "e_basic_constraints_not_critical". It contains an implementation of LintInterface.
|
||||
type Lint struct {
|
||||
|
||||
// Name is a lowercase underscore-separated string describing what a given
|
||||
// Lint checks. If Name beings with "w", the lint MUST NOT return Error, only
|
||||
// Warn. If Name beings with "e", the Lint MUST NOT return Warn, only Error.
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// A human-readable description of what the Lint checks. Usually copied
|
||||
// directly from the CA/B Baseline Requirements or RFC 5280.
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
// The source of the check, e.g. "BRs: 6.1.6" or "RFC 5280: 4.1.2.6".
|
||||
Citation string `json:"citation,omitempty"`
|
||||
|
||||
// Programmatic source of the check, BRs, RFC5280, or ZLint
|
||||
Source LintSource `json:"source"`
|
||||
|
||||
// Lints automatically returns NE for all certificates where CheckApplies() is
|
||||
// true but with NotBefore < EffectiveDate. This check is bypassed if
|
||||
// EffectiveDate is zero.
|
||||
EffectiveDate time.Time `json:"-"`
|
||||
|
||||
// The implementation of the lint logic.
|
||||
Lint LintInterface `json:"-"`
|
||||
}
|
||||
|
||||
// CheckEffective returns true if c was issued on or after the EffectiveDate. If
|
||||
// EffectiveDate is zero, CheckEffective always returns true.
|
||||
func (l *Lint) CheckEffective(c *x509.Certificate) bool {
|
||||
if l.EffectiveDate.IsZero() || !l.EffectiveDate.After(c.NotBefore) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Execute runs the lint against a certificate. For lints that are
|
||||
// sourced from the CA/B Forum Baseline Requirements, we first determine
|
||||
// if they are within the purview of the BRs. See LintInterface for details
|
||||
// about the other methods called. The ordering is as follows:
|
||||
//
|
||||
// CheckApplies()
|
||||
// CheckEffective()
|
||||
// Execute()
|
||||
func (l *Lint) Execute(cert *x509.Certificate) *LintResult {
|
||||
if l.Source == CABFBaselineRequirements && !util.IsServerAuthCert(cert) {
|
||||
return &LintResult{Status: NA}
|
||||
}
|
||||
if !l.Lint.CheckApplies(cert) {
|
||||
return &LintResult{Status: NA}
|
||||
} else if !l.CheckEffective(cert) {
|
||||
return &LintResult{Status: NE}
|
||||
}
|
||||
res := l.Lint.Execute(cert)
|
||||
return res
|
||||
}
|
351
vendor/github.com/zmap/zlint/v3/lint/registration.go
generated
vendored
Normal file
351
vendor/github.com/zmap/zlint/v3/lint/registration.go
generated
vendored
Normal file
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package lint
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// FilterOptions is a struct used by Registry.Filter to create a sub registry
|
||||
// containing only lints that meet the filter options specified.
|
||||
//
|
||||
// Source based exclusion/inclusion is evaluated before Lint name based
|
||||
// exclusion/inclusion. In both cases exclusion is processed before inclusion.
|
||||
//
|
||||
// Only one of NameFilter or IncludeNames/ExcludeNames can be provided at
|
||||
// a time.
|
||||
type FilterOptions struct {
|
||||
// NameFilter is a regexp used to filter lints by their name. It is mutually
|
||||
// exclusive with IncludeNames and ExcludeNames.
|
||||
NameFilter *regexp.Regexp
|
||||
// IncludeNames is a case sensitive list of lint names to include in the
|
||||
// registry being filtered.
|
||||
IncludeNames []string
|
||||
// ExcludeNames is a case sensitive list of lint names to exclude from the
|
||||
// registry being filtered.
|
||||
ExcludeNames []string
|
||||
// IncludeSource is a SourceList of LintSource's to be included in the
|
||||
// registry being filtered.
|
||||
IncludeSources SourceList
|
||||
// ExcludeSources is a SourceList of LintSources's to be excluded in the
|
||||
// registry being filtered.
|
||||
ExcludeSources SourceList
|
||||
}
|
||||
|
||||
// Empty returns true if the FilterOptions is empty and does not specify any
|
||||
// elements to filter by.
|
||||
func (opts FilterOptions) Empty() bool {
|
||||
return opts.NameFilter == nil &&
|
||||
len(opts.IncludeNames) == 0 &&
|
||||
len(opts.ExcludeNames) == 0 &&
|
||||
len(opts.IncludeSources) == 0 &&
|
||||
len(opts.ExcludeSources) == 0
|
||||
}
|
||||
|
||||
// Registry is an interface describing a collection of registered lints.
|
||||
// A Registry instance can be given to zlint.LintCertificateEx() to control what
|
||||
// lints are run for a given certificate.
|
||||
//
|
||||
// Typically users will interact with the global Registry returned by
|
||||
// GlobalRegistry(), or a filtered Registry created by applying FilterOptions to
|
||||
// the GlobalRegistry()'s Filter function.
|
||||
type Registry interface {
|
||||
// Names returns a list of all of the lint names that have been registered
|
||||
// in string sorted order.
|
||||
Names() []string
|
||||
// Sources returns a SourceList of registered LintSources. The list is not
|
||||
// sorted but can be sorted by the caller with sort.Sort() if required.
|
||||
Sources() SourceList
|
||||
// ByName returns a pointer to the registered lint with the given name, or nil
|
||||
// if there is no such lint registered in the registry.
|
||||
ByName(name string) *Lint
|
||||
// BySource returns a list of registered lints that have the same LintSource as
|
||||
// provided (or nil if there were no such lints in the registry).
|
||||
BySource(s LintSource) []*Lint
|
||||
// Filter returns a new Registry containing only lints that match the
|
||||
// FilterOptions criteria.
|
||||
Filter(opts FilterOptions) (Registry, error)
|
||||
// WriteJSON writes a description of each registered lint as
|
||||
// a JSON object, one object per line, to the provided writer.
|
||||
WriteJSON(w io.Writer)
|
||||
}
|
||||
|
||||
// registryImpl implements the Registry interface to provide a global collection
|
||||
// of Lints that have been registered.
|
||||
type registryImpl struct {
|
||||
sync.RWMutex
|
||||
// lintsByName is a map of all registered lints by name.
|
||||
lintsByName map[string]*Lint
|
||||
// lintNames is a sorted list of all of the registered lint names. It is
|
||||
// equivalent to collecting the keys from lintsByName into a slice and sorting
|
||||
// them lexicographically.
|
||||
lintNames []string
|
||||
// lintsBySource is a map of all registered lints by source category. Lints
|
||||
// are added to the lintsBySource map by RegisterLint.
|
||||
lintsBySource map[LintSource][]*Lint
|
||||
}
|
||||
|
||||
var (
|
||||
// errNilLint is returned from registry.Register if the provided lint was nil.
|
||||
errNilLint = errors.New("can not register a nil lint")
|
||||
// errNilLintPtr is returned from registry.Register if the provided lint had
|
||||
// a nil Lint field.
|
||||
errNilLintPtr = errors.New("can not register a lint with a nil Lint pointer")
|
||||
// errEmptyName is returned from registry.Register if the provided lint had an
|
||||
// empty Name field.
|
||||
errEmptyName = errors.New("can not register a lint with an empty Name")
|
||||
)
|
||||
|
||||
// errDuplicateName is returned from registry.Register if the provided lint had
|
||||
// a Name field matching a lint that was previously registered.
|
||||
type errDuplicateName struct {
|
||||
lintName string
|
||||
}
|
||||
|
||||
func (e errDuplicateName) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"can not register lint with name %q - it has already been registered",
|
||||
e.lintName)
|
||||
}
|
||||
|
||||
// errBadInit is returned from registry.Register if the provided lint's
|
||||
// Initialize function returned an error.
|
||||
type errBadInit struct {
|
||||
lintName string
|
||||
err error
|
||||
}
|
||||
|
||||
func (e errBadInit) Error() string {
|
||||
return fmt.Sprintf(
|
||||
"failed to register lint with name %q - failed to Initialize: %q",
|
||||
e.lintName, e.err)
|
||||
}
|
||||
|
||||
// register adds the provided lint to the Registry. If initialize is true then
|
||||
// the lint's Initialize() function will be called before registering the lint.
|
||||
//
|
||||
// An error is returned if the lint or lint's Lint pointer is nil, if the Lint
|
||||
// has an empty Name or if the Name was previously registered.
|
||||
func (r *registryImpl) register(l *Lint, initialize bool) error {
|
||||
if l == nil {
|
||||
return errNilLint
|
||||
}
|
||||
if l.Lint == nil {
|
||||
return errNilLintPtr
|
||||
}
|
||||
if l.Name == "" {
|
||||
return errEmptyName
|
||||
}
|
||||
if existing := r.ByName(l.Name); existing != nil {
|
||||
return &errDuplicateName{l.Name}
|
||||
}
|
||||
if initialize {
|
||||
if err := l.Lint.Initialize(); err != nil {
|
||||
return &errBadInit{l.Name, err}
|
||||
}
|
||||
}
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.lintNames = append(r.lintNames, l.Name)
|
||||
r.lintsByName[l.Name] = l
|
||||
r.lintsBySource[l.Source] = append(r.lintsBySource[l.Source], l)
|
||||
sort.Strings(r.lintNames)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ByName returns the Lint previously registered under the given name with
|
||||
// Register, or nil if no matching lint name has been registered.
|
||||
func (r *registryImpl) ByName(name string) *Lint {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.lintsByName[name]
|
||||
}
|
||||
|
||||
// Names returns a list of all of the lint names that have been registered
|
||||
// in string sorted order.
|
||||
func (r *registryImpl) Names() []string {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.lintNames
|
||||
}
|
||||
|
||||
// BySource returns a list of registered lints that have the same LintSource as
|
||||
// provided (or nil if there were no such lints).
|
||||
func (r *registryImpl) BySource(s LintSource) []*Lint {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
return r.lintsBySource[s]
|
||||
}
|
||||
|
||||
// Sources returns a SourceList of registered LintSources. The list is not
|
||||
// sorted but can be sorted by the caller with sort.Sort() if required.
|
||||
func (r *registryImpl) Sources() SourceList {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
var results SourceList
|
||||
for k := range r.lintsBySource {
|
||||
results = append(results, k)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// lintNamesToMap converts a list of lit names into a bool hashmap useful for
|
||||
// filtering. If any of the lint names are not known by the registry an error is
|
||||
// returned.
|
||||
func (r *registryImpl) lintNamesToMap(names []string) (map[string]bool, error) {
|
||||
if len(names) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
namesMap := make(map[string]bool, len(names))
|
||||
for _, n := range names {
|
||||
n = strings.TrimSpace(n)
|
||||
if l := r.ByName(n); l == nil {
|
||||
return nil, fmt.Errorf("unknown lint name %q", n)
|
||||
}
|
||||
namesMap[n] = true
|
||||
}
|
||||
return namesMap, nil
|
||||
}
|
||||
|
||||
func sourceListToMap(sources SourceList) map[LintSource]bool {
|
||||
if len(sources) == 0 {
|
||||
return nil
|
||||
}
|
||||
sourceMap := make(map[LintSource]bool, len(sources))
|
||||
for _, s := range sources {
|
||||
sourceMap[s] = true
|
||||
}
|
||||
return sourceMap
|
||||
}
|
||||
|
||||
// Filter creates a new Registry with only the lints that meet the FilterOptions
|
||||
// criteria included.
|
||||
//
|
||||
// FilterOptions are applied in the following order of precedence:
|
||||
// ExcludeSources > IncludeSources > NameFilter > ExcludeNames > IncludeNames
|
||||
func (r *registryImpl) Filter(opts FilterOptions) (Registry, error) {
|
||||
// If there's no filtering to be done, return the existing Registry.
|
||||
if opts.Empty() {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
filteredRegistry := NewRegistry()
|
||||
|
||||
sourceExcludes := sourceListToMap(opts.ExcludeSources)
|
||||
sourceIncludes := sourceListToMap(opts.IncludeSources)
|
||||
|
||||
nameExcludes, err := r.lintNamesToMap(opts.ExcludeNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nameIncludes, err := r.lintNamesToMap(opts.IncludeNames)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.NameFilter != nil && (len(nameExcludes) != 0 || len(nameIncludes) != 0) {
|
||||
return nil, errors.New(
|
||||
"FilterOptions.NameFilter cannot be used at the same time as " +
|
||||
"FilterOptions.ExcludeNames or FilterOptions.IncludeNames")
|
||||
}
|
||||
|
||||
for _, name := range r.Names() {
|
||||
l := r.ByName(name)
|
||||
|
||||
if sourceExcludes != nil && sourceExcludes[l.Source] {
|
||||
continue
|
||||
}
|
||||
if sourceIncludes != nil && !sourceIncludes[l.Source] {
|
||||
continue
|
||||
}
|
||||
if opts.NameFilter != nil && !opts.NameFilter.MatchString(name) {
|
||||
continue
|
||||
}
|
||||
if nameExcludes != nil && nameExcludes[name] {
|
||||
continue
|
||||
}
|
||||
if nameIncludes != nil && !nameIncludes[name] {
|
||||
continue
|
||||
}
|
||||
|
||||
// when adding lints to a filtered registry we do not want Initialize() to
|
||||
// be called a second time, so provide false as the initialize argument.
|
||||
if err := filteredRegistry.register(l, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return filteredRegistry, nil
|
||||
}
|
||||
|
||||
// WriteJSON writes a description of each registered lint as
|
||||
// a JSON object, one object per line, to the provided writer.
|
||||
func (r *registryImpl) WriteJSON(w io.Writer) {
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetEscapeHTML(false)
|
||||
for _, name := range r.Names() {
|
||||
_ = enc.Encode(r.ByName(name))
|
||||
}
|
||||
}
|
||||
|
||||
// NewRegistry constructs a Registry implementation that can be used to register
|
||||
// lints.
|
||||
func NewRegistry() *registryImpl {
|
||||
return ®istryImpl{
|
||||
lintsByName: make(map[string]*Lint),
|
||||
lintsBySource: make(map[LintSource][]*Lint),
|
||||
}
|
||||
}
|
||||
|
||||
// globalRegistry is the Registry used by all loaded lints that call
|
||||
// RegisterLint().
|
||||
var globalRegistry *registryImpl = NewRegistry()
|
||||
|
||||
// RegisterLint must be called once for each lint to be executed. Normally,
|
||||
// RegisterLint is called from the Go init() function of a lint implementation.
|
||||
//
|
||||
// RegsterLint will call l.Lint's Initialize() function as part of the
|
||||
// registration process.
|
||||
//
|
||||
// IMPORTANT: RegisterLint will panic if given a nil lint, or a lint with a nil
|
||||
// Lint pointer, or if the lint's Initialize function errors, or if the lint
|
||||
// name matches a previously registered lint's name. These conditions all
|
||||
// indicate a bug that should be addressed by a developer.
|
||||
func RegisterLint(l *Lint) {
|
||||
// RegisterLint always sets initialize to true. It's assumed this is called by
|
||||
// the package init() functions and therefore must be doing the first
|
||||
// initialization of a lint.
|
||||
if err := globalRegistry.register(l, true); err != nil {
|
||||
panic(fmt.Sprintf("RegisterLint error: %v\n", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
// GlobalRegistry is the Registry used by RegisterLint and contains all of the
|
||||
// lints that are loaded.
|
||||
//
|
||||
// If you want to run only a subset of the globally registered lints use
|
||||
// GloablRegistry().Filter with FilterOptions to create a filtered
|
||||
// Registry.
|
||||
func GlobalRegistry() Registry {
|
||||
return globalRegistry
|
||||
}
|
106
vendor/github.com/zmap/zlint/v3/lint/result.go
generated
vendored
Normal file
106
vendor/github.com/zmap/zlint/v3/lint/result.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
package lint
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LintStatus is an enum returned by lints inside of a LintResult.
|
||||
type LintStatus int
|
||||
|
||||
// Known LintStatus values
|
||||
const (
|
||||
// Unused / unset LintStatus
|
||||
Reserved LintStatus = 0
|
||||
|
||||
// Not Applicable
|
||||
NA LintStatus = 1
|
||||
|
||||
// Not Effective
|
||||
NE LintStatus = 2
|
||||
|
||||
Pass LintStatus = 3
|
||||
Notice LintStatus = 4
|
||||
Warn LintStatus = 5
|
||||
Error LintStatus = 6
|
||||
Fatal LintStatus = 7
|
||||
)
|
||||
|
||||
var (
|
||||
// StatusLabelToLintStatus is used to work backwards from
|
||||
// a LintStatus.String() to the LintStatus. This is used by
|
||||
// LintStatus.Unmarshal.
|
||||
StatusLabelToLintStatus = map[string]LintStatus{
|
||||
Reserved.String(): Reserved,
|
||||
NA.String(): NA,
|
||||
NE.String(): NE,
|
||||
Pass.String(): Pass,
|
||||
Notice.String(): Notice,
|
||||
Warn.String(): Warn,
|
||||
Error.String(): Error,
|
||||
Fatal.String(): Fatal,
|
||||
}
|
||||
)
|
||||
|
||||
// LintResult contains a LintStatus, and an optional human-readable description.
|
||||
// The output of a lint is a LintResult.
|
||||
type LintResult struct {
|
||||
Status LintStatus `json:"result"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (e LintStatus) MarshalJSON() ([]byte, error) {
|
||||
s := e.String()
|
||||
return json.Marshal(s)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (e *LintStatus) UnmarshalJSON(data []byte) error {
|
||||
key := strings.ReplaceAll(string(data), `"`, "")
|
||||
if status, ok := StatusLabelToLintStatus[key]; ok {
|
||||
*e = status
|
||||
} else {
|
||||
return fmt.Errorf("bad LintStatus JSON value: %s", string(data))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns the canonical representation of a LintStatus as a string.
|
||||
func (e LintStatus) String() string {
|
||||
switch e {
|
||||
case Reserved:
|
||||
return "reserved"
|
||||
case NA:
|
||||
return "NA"
|
||||
case NE:
|
||||
return "NE"
|
||||
case Pass:
|
||||
return "pass"
|
||||
case Notice:
|
||||
return "info"
|
||||
case Warn:
|
||||
return "warn"
|
||||
case Error:
|
||||
return "error"
|
||||
case Fatal:
|
||||
return "fatal"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
129
vendor/github.com/zmap/zlint/v3/lint/source.go
generated
vendored
Normal file
129
vendor/github.com/zmap/zlint/v3/lint/source.go
generated
vendored
Normal file
|
@ -0,0 +1,129 @@
|
|||
package lint
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
// LintSource is a type representing a known lint source that lints cite
|
||||
// requirements from.
|
||||
type LintSource string
|
||||
|
||||
const (
|
||||
UnknownLintSource LintSource = "Unknown"
|
||||
RFC5280 LintSource = "RFC5280"
|
||||
RFC5480 LintSource = "RFC5480"
|
||||
RFC5891 LintSource = "RFC5891"
|
||||
CABFBaselineRequirements LintSource = "CABF_BR"
|
||||
CABFEVGuidelines LintSource = "CABF_EV"
|
||||
MozillaRootStorePolicy LintSource = "Mozilla"
|
||||
AppleRootStorePolicy LintSource = "Apple"
|
||||
Community LintSource = "Community"
|
||||
EtsiEsi LintSource = "ETSI_ESI"
|
||||
)
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface. It ensures that the
|
||||
// unmarshaled value is a known LintSource.
|
||||
func (s *LintSource) UnmarshalJSON(data []byte) error {
|
||||
var throwAway string
|
||||
if err := json.Unmarshal(data, &throwAway); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch LintSource(throwAway) {
|
||||
case RFC5280, RFC5480, RFC5891, CABFBaselineRequirements, CABFEVGuidelines, MozillaRootStorePolicy, AppleRootStorePolicy, Community, EtsiEsi:
|
||||
*s = LintSource(throwAway)
|
||||
return nil
|
||||
default:
|
||||
*s = UnknownLintSource
|
||||
return fmt.Errorf("unknown LintSource value %q", throwAway)
|
||||
}
|
||||
}
|
||||
|
||||
// FromString sets the LintSource value based on the source string provided
|
||||
// (case sensitive). If the src string does not match any of the known
|
||||
// LintSource's then s is set to the UnknownLintSource.
|
||||
func (s *LintSource) FromString(src string) {
|
||||
// Start with the unknown lint source
|
||||
*s = UnknownLintSource
|
||||
// Trim space and try to match a known value
|
||||
src = strings.TrimSpace(src)
|
||||
switch LintSource(src) {
|
||||
case RFC5280:
|
||||
*s = RFC5280
|
||||
case RFC5480:
|
||||
*s = RFC5480
|
||||
case RFC5891:
|
||||
*s = RFC5891
|
||||
case CABFBaselineRequirements:
|
||||
*s = CABFBaselineRequirements
|
||||
case CABFEVGuidelines:
|
||||
*s = CABFEVGuidelines
|
||||
case MozillaRootStorePolicy:
|
||||
*s = MozillaRootStorePolicy
|
||||
case AppleRootStorePolicy:
|
||||
*s = AppleRootStorePolicy
|
||||
case Community:
|
||||
*s = Community
|
||||
case EtsiEsi:
|
||||
*s = EtsiEsi
|
||||
}
|
||||
}
|
||||
|
||||
// SourceList is a slice of LintSources that can be sorted.
|
||||
type SourceList []LintSource
|
||||
|
||||
// Len returns the length of the list.
|
||||
func (l SourceList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
// Swap swaps the LintSource at index i and j in the list.
|
||||
func (l SourceList) Swap(i, j int) {
|
||||
l[i], l[j] = l[j], l[i]
|
||||
}
|
||||
|
||||
// Less compares the LintSources at index i and j lexicographically.
|
||||
func (l SourceList) Less(i, j int) bool {
|
||||
return l[i] < l[j]
|
||||
}
|
||||
|
||||
// FromString populates a SourceList (replacing any existing content) with the
|
||||
// comma separated list of sources provided in raw. If any of the comma
|
||||
// separated values are not known LintSource's an error is returned.
|
||||
func (l *SourceList) FromString(raw string) error {
|
||||
// Start with an empty list
|
||||
*l = SourceList{}
|
||||
|
||||
values := strings.Split(raw, ",")
|
||||
for _, val := range values {
|
||||
val = strings.TrimSpace(val)
|
||||
if val == "" {
|
||||
continue
|
||||
}
|
||||
// Populate the LintSource with the trimmed value.
|
||||
var src LintSource
|
||||
src.FromString(val)
|
||||
// If the LintSource is UnknownLintSource then return an error.
|
||||
if src == UnknownLintSource {
|
||||
return fmt.Errorf("unknown lint source in list: %q", val)
|
||||
}
|
||||
*l = append(*l, src)
|
||||
}
|
||||
return nil
|
||||
}
|
157
vendor/github.com/zmap/zlint/v3/lints/apple/lint_ct_sct_policy_count_unsatisfied.go
generated
vendored
Normal file
157
vendor/github.com/zmap/zlint/v3/lints/apple/lint_ct_sct_policy_count_unsatisfied.go
generated
vendored
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package apple
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zcrypto/x509/ct"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type sctPolicyCount struct{}
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "w_ct_sct_policy_count_unsatisfied",
|
||||
Description: "Check if certificate has enough embedded SCTs to meet Apple CT Policy",
|
||||
Citation: "https://support.apple.com/en-us/HT205280",
|
||||
Source: lint.AppleRootStorePolicy,
|
||||
EffectiveDate: util.AppleCTPolicyDate,
|
||||
Lint: &sctPolicyCount{},
|
||||
})
|
||||
}
|
||||
|
||||
// Initialize for a sctPolicyCount instance does nothing.
|
||||
func (l *sctPolicyCount) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckApplies returns true for any subscriber certificates that are not
|
||||
// precertificates (e.g. that do not have the CT poison extension defined in RFC
|
||||
// 6962.
|
||||
func (l *sctPolicyCount) CheckApplies(c *x509.Certificate) bool {
|
||||
return util.IsSubscriberCert(c) && !util.IsExtInCert(c, util.CtPoisonOID)
|
||||
}
|
||||
|
||||
// Execute checks if the provided certificate has embedded SCTs from
|
||||
// a sufficient number of unique CT logs to meet Apple's CT log policy[0],
|
||||
// effective Oct 15th, 2018.
|
||||
//
|
||||
// The number of required SCTs from different logs is calculated based on the
|
||||
// Certificate's lifetime. If the number of required SCTs are not embedded in
|
||||
// the certificate a Notice level lint.LintResult is returned.
|
||||
//
|
||||
// | Certificate lifetime | # of SCTs from separate logs |
|
||||
// -------------------------------------------------------
|
||||
// | Less than 15 months | 2 |
|
||||
// | 15 to 27 months | 3 |
|
||||
// | 27 to 39 months | 4 |
|
||||
// | More than 39 months | 5 |
|
||||
// -------------------------------------------------------
|
||||
//
|
||||
// Important note 1: We can't know whether additional SCTs were presented
|
||||
// alongside the certificate via OCSP stapling. This linter assumes only
|
||||
// embedded SCTs are used and ignores the portion of the Apple policy related to
|
||||
// SCTs delivered via OCSP. This is one limitation that restricts the linter's
|
||||
// findings to Notice level. See more background discussion in Issue 226[1].
|
||||
//
|
||||
// Important note 2: The linter doesn't maintain a list of Apple's trusted
|
||||
// logs. The SCTs embedded in the certificate may not be from log's Apple
|
||||
// actually trusts. Similarly the embedded SCT signatures are not validated
|
||||
// in any way.
|
||||
//
|
||||
// [0]: https://support.apple.com/en-us/HT205280
|
||||
// [1]: https://github.com/zmap/zlint/issues/226
|
||||
func (l *sctPolicyCount) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
// Determine the required number of SCTs from separate logs
|
||||
expected := appleCTPolicyExpectedSCTs(c)
|
||||
|
||||
// If there are no SCTs then the job is easy. We can return a Notice
|
||||
// lint.LintResult immediately.
|
||||
if len(c.SignedCertificateTimestampList) == 0 && expected > 0 {
|
||||
return &lint.LintResult{
|
||||
Status: lint.Notice,
|
||||
Details: fmt.Sprintf(
|
||||
"Certificate had 0 embedded SCTs. Browser policy may require %d for this certificate.",
|
||||
expected),
|
||||
}
|
||||
}
|
||||
|
||||
// Build a map from LogID to SCT so that we can count embedded SCTs by unique
|
||||
// log.
|
||||
sctsByLogID := make(map[ct.SHA256Hash]*ct.SignedCertificateTimestamp)
|
||||
for _, sct := range c.SignedCertificateTimestampList {
|
||||
sctsByLogID[sct.LogID] = sct
|
||||
}
|
||||
|
||||
// If the number of embedded SCTs from separate logs meets expected return
|
||||
// a lint.Pass result.
|
||||
if len(sctsByLogID) >= expected {
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
}
|
||||
|
||||
// Otherwise return a Notice result - there weren't enough SCTs embedded in
|
||||
// the certificate. More must be provided by OCSP stapling if the certificate
|
||||
// is to meet Apple's CT policy.
|
||||
return &lint.LintResult{
|
||||
Status: lint.Notice,
|
||||
Details: fmt.Sprintf(
|
||||
"Certificate had %d embedded SCTs from distinct log IDs. "+
|
||||
"Browser policy may require %d for this certificate.",
|
||||
len(sctsByLogID), expected),
|
||||
}
|
||||
}
|
||||
|
||||
// appleCTPolicyExpectedSCTs returns a count of the number of SCTs expected to
|
||||
// be embedded in the given certificate based on its lifetime.
|
||||
//
|
||||
// For this function the relevant portion of Apple's policy is the table
|
||||
// "Number of embedded SCTs based on certificate lifetime" (Also reproduced in
|
||||
// the `Execute` godoc comment).
|
||||
func appleCTPolicyExpectedSCTs(cert *x509.Certificate) int {
|
||||
// Lifetime is relative to the certificate's NotBefore date.
|
||||
start := cert.NotBefore
|
||||
|
||||
// Thresholds is an ordered array of lifetime periods and their expected # of
|
||||
// SCTs. A lifetime period is defined by the cutoff date relative to the
|
||||
// start of the certificate's lifetime.
|
||||
thresholds := []struct {
|
||||
CutoffDate time.Time
|
||||
Expected int
|
||||
}{
|
||||
// Start date ... 15 months
|
||||
{CutoffDate: start.AddDate(0, 15, 0), Expected: 2},
|
||||
// Start date ... 27 months
|
||||
{CutoffDate: start.AddDate(0, 27, 0), Expected: 3},
|
||||
// Start date ... 39 months
|
||||
{CutoffDate: start.AddDate(0, 39, 0), Expected: 4},
|
||||
}
|
||||
|
||||
// If the certificate's lifetime falls into any of the cutoff date ranges then
|
||||
// we expect that range's expected # of SCTs for this certificate. This loop
|
||||
// assumes the `thresholds` list is sorted in ascending order.
|
||||
for _, threshold := range thresholds {
|
||||
if cert.NotAfter.Before(threshold.CutoffDate) {
|
||||
return threshold.Expected
|
||||
}
|
||||
}
|
||||
|
||||
// The certificate had a validity > 39 months.
|
||||
return 5
|
||||
}
|
61
vendor/github.com/zmap/zlint/v3/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go
generated
vendored
Normal file
61
vendor/github.com/zmap/zlint/v3/lints/apple/lint_e_server_cert_valid_time_longer_than_398_days.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package apple
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type serverCertValidityTooLong struct{}
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "e_tls_server_cert_valid_time_longer_than_398_days",
|
||||
Description: "TLS server certificates issued on or after September 1, 2020 " +
|
||||
"00:00 GMT/UTC must not have a validity period greater than 398 days",
|
||||
Citation: "https://support.apple.com/en-us/HT211025",
|
||||
Source: lint.AppleRootStorePolicy,
|
||||
EffectiveDate: util.AppleReducedLifetimeDate,
|
||||
Lint: &serverCertValidityTooLong{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *serverCertValidityTooLong) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *serverCertValidityTooLong) CheckApplies(c *x509.Certificate) bool {
|
||||
return util.IsServerAuthCert(c) && !c.IsCA
|
||||
}
|
||||
|
||||
func (l *serverCertValidityTooLong) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
// "TLS server certificates issued on or after September 1, 2020 00:00 GMT/UTC
|
||||
// must not have a validity period greater than 398 days."
|
||||
maxValidity := 398 * appleDayLength
|
||||
|
||||
// RFC 5280, section 4.1.2.5: "The validity period for a certificate is the period
|
||||
// of time from notBefore through notAfter, inclusive."
|
||||
certValidity := c.NotAfter.Add(1 * time.Second).Sub(c.NotBefore)
|
||||
|
||||
if certValidity > maxValidity {
|
||||
return &lint.LintResult{Status: lint.Error}
|
||||
}
|
||||
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
}
|
67
vendor/github.com/zmap/zlint/v3/lints/apple/lint_w_server_cert_valid_time_longer_than_397_days.go
generated
vendored
Normal file
67
vendor/github.com/zmap/zlint/v3/lints/apple/lint_w_server_cert_valid_time_longer_than_397_days.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package apple
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type serverCertValidityAlmostTooLong struct{}
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "w_tls_server_cert_valid_time_longer_than_397_days",
|
||||
Description: "TLS server certificates issued on or after September 1, 2020 " +
|
||||
"00:00 GMT/UTC should not have a validity period greater than 397 days",
|
||||
Citation: "https://support.apple.com/en-us/HT211025",
|
||||
Source: lint.AppleRootStorePolicy,
|
||||
EffectiveDate: util.AppleReducedLifetimeDate,
|
||||
Lint: &serverCertValidityAlmostTooLong{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *serverCertValidityAlmostTooLong) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *serverCertValidityAlmostTooLong) CheckApplies(c *x509.Certificate) bool {
|
||||
return util.IsServerAuthCert(c) && !c.IsCA
|
||||
}
|
||||
|
||||
func (l *serverCertValidityAlmostTooLong) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
// "We recommend that certificates be issued with a maximum validity of 397 days."
|
||||
warnValidity := 397 * appleDayLength
|
||||
|
||||
// RFC 5280, section 4.1.2.5: "The validity period for a certificate is the period
|
||||
// of time from notBefore through notAfter, inclusive."
|
||||
certValidity := c.NotAfter.Add(1 * time.Second).Sub(c.NotBefore)
|
||||
|
||||
if certValidity > warnValidity {
|
||||
return &lint.LintResult{
|
||||
// RFC 2119 has SHOULD and RECOMMENDED as equal. Since Apple recommends
|
||||
// 397 days we treat this as a lint.Warn result as a violation of
|
||||
// a SHOULD.
|
||||
Status: lint.Warn,
|
||||
Details: "Apple recommends that certificates be issued with a maximum " +
|
||||
"validity of 397 days.",
|
||||
}
|
||||
}
|
||||
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
}
|
13
vendor/github.com/zmap/zlint/v3/lints/apple/time.go
generated
vendored
Normal file
13
vendor/github.com/zmap/zlint/v3/lints/apple/time.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
package apple
|
||||
|
||||
import "time"
|
||||
|
||||
// In the context of a root policy update on trusted certificate lifetimes[0]
|
||||
// Apple provided an unambiguous definition for the length of a day:
|
||||
// "398 days is measured with a day being equal to 86,400 seconds. Any time
|
||||
// greater than this indicates an additional day of validity."
|
||||
//
|
||||
// We provide that value as a constant here for lints to use.
|
||||
//
|
||||
// [0]: https://support.apple.com/en-us/HT211025
|
||||
var appleDayLength = 86400 * time.Second
|
50
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_common_name_missing.go
generated
vendored
Normal file
50
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_common_name_missing.go
generated
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
package cabf_br
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type caCommonNameMissing struct{}
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "e_ca_common_name_missing",
|
||||
Description: "CA Certificates common name MUST be included.",
|
||||
Citation: "BRs: 7.1.4.3.1",
|
||||
Source: lint.CABFBaselineRequirements,
|
||||
EffectiveDate: util.CABV148Date,
|
||||
Lint: &caCommonNameMissing{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *caCommonNameMissing) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *caCommonNameMissing) CheckApplies(c *x509.Certificate) bool {
|
||||
return util.IsCACert(c)
|
||||
}
|
||||
|
||||
func (l *caCommonNameMissing) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
if c.Subject.CommonName == "" {
|
||||
return &lint.LintResult{Status: lint.Error}
|
||||
} else {
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
}
|
||||
}
|
63
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_country_name_invalid.go
generated
vendored
Normal file
63
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_country_name_invalid.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
package cabf_br
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type caCountryNameInvalid struct{}
|
||||
|
||||
/************************************************
|
||||
BRs: 7.1.2.1e
|
||||
The Certificate Subject MUST contain the following:
|
||||
‐ countryName (OID 2.5.4.6).
|
||||
This field MUST contain the two‐letter ISO 3166‐1 country code for the country
|
||||
in which the CA’s place of business is located.
|
||||
************************************************/
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "e_ca_country_name_invalid",
|
||||
Description: "Root and Subordinate CA certificates MUST have a two-letter country code specified in ISO 3166-1",
|
||||
Citation: "BRs: 7.1.2.1",
|
||||
Source: lint.CABFBaselineRequirements,
|
||||
EffectiveDate: util.CABEffectiveDate,
|
||||
Lint: &caCountryNameInvalid{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *caCountryNameInvalid) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *caCountryNameInvalid) CheckApplies(c *x509.Certificate) bool {
|
||||
return c.IsCA
|
||||
}
|
||||
|
||||
func (l *caCountryNameInvalid) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
if c.Subject.Country != nil {
|
||||
for _, j := range c.Subject.Country {
|
||||
if !util.IsISOCountryCode(j) {
|
||||
return &lint.LintResult{Status: lint.Error}
|
||||
}
|
||||
}
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
} else {
|
||||
return &lint.LintResult{Status: lint.NA}
|
||||
}
|
||||
}
|
58
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_country_name_missing.go
generated
vendored
Normal file
58
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_country_name_missing.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
package cabf_br
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type caCountryNameMissing struct{}
|
||||
|
||||
/************************************************
|
||||
BRs: 7.1.2.1e
|
||||
The Certificate Subject MUST contain the following:
|
||||
‐ countryName (OID 2.5.4.6).
|
||||
This field MUST contain the two‐letter ISO 3166‐1 country code for the country
|
||||
in which the CA’s place of business is located.
|
||||
************************************************/
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "e_ca_country_name_missing",
|
||||
Description: "Root and Subordinate CA certificates MUST have a countryName present in subject information",
|
||||
Citation: "BRs: 7.1.2.1",
|
||||
Source: lint.CABFBaselineRequirements,
|
||||
EffectiveDate: util.CABEffectiveDate,
|
||||
Lint: &caCountryNameMissing{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *caCountryNameMissing) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *caCountryNameMissing) CheckApplies(c *x509.Certificate) bool {
|
||||
return c.IsCA
|
||||
}
|
||||
|
||||
func (l *caCountryNameMissing) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
if c.Subject.Country != nil && c.Subject.Country[0] != "" {
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
} else {
|
||||
return &lint.LintResult{Status: lint.Error}
|
||||
}
|
||||
}
|
57
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_crl_sign_not_set.go
generated
vendored
Normal file
57
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_crl_sign_not_set.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
package cabf_br
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type caCRLSignNotSet struct{}
|
||||
|
||||
/************************************************
|
||||
BRs: 7.1.2.1b
|
||||
This extension MUST be present and MUST be marked critical. Bit positions for
|
||||
keyCertSign and cRLSign MUST be set. If the Root CA Private Key is used for
|
||||
signing OCSP responses, then the digitalSignature bit MUST be set.
|
||||
************************************************/
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "e_ca_crl_sign_not_set",
|
||||
Description: "Root and Subordinate CA certificate keyUsage extension's crlSign bit MUST be set",
|
||||
Citation: "BRs: 7.1.2.1",
|
||||
Source: lint.CABFBaselineRequirements,
|
||||
EffectiveDate: util.CABEffectiveDate,
|
||||
Lint: &caCRLSignNotSet{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *caCRLSignNotSet) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *caCRLSignNotSet) CheckApplies(c *x509.Certificate) bool {
|
||||
return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID)
|
||||
}
|
||||
|
||||
func (l *caCRLSignNotSet) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
if c.KeyUsage&x509.KeyUsageCRLSign != 0 {
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
} else {
|
||||
return &lint.LintResult{Status: lint.Error}
|
||||
}
|
||||
}
|
60
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_digital_signature_not_set.go
generated
vendored
Normal file
60
vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_digital_signature_not_set.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
package cabf_br
|
||||
|
||||
/*
|
||||
* ZLint Copyright 2021 Regents of the University of Michigan
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
import (
|
||||
"github.com/zmap/zcrypto/x509"
|
||||
"github.com/zmap/zlint/v3/lint"
|
||||
"github.com/zmap/zlint/v3/util"
|
||||
)
|
||||
|
||||
type caDigSignNotSet struct{}
|
||||
|
||||
/************************************************
|
||||
BRs: 7.1.2.1b: Root CA Certificate keyUsage
|
||||
This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set.
|
||||
If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set.
|
||||
|
||||
BRs: 7.1.2.2e: Subordinate CA Certificate keyUsage
|
||||
This extension MUST be present and MUST be marked critical. Bit positions for keyCertSign and cRLSign MUST be set.
|
||||
If the Root CA Private Key is used for signing OCSP responses, then the digitalSignature bit MUST be set.
|
||||
************************************************/
|
||||
|
||||
func init() {
|
||||
lint.RegisterLint(&lint.Lint{
|
||||
Name: "n_ca_digital_signature_not_set",
|
||||
Description: "Root and Subordinate CA Certificates that wish to use their private key for signing OCSP responses will not be able to without their digital signature set",
|
||||
Citation: "BRs: 7.1.2.1",
|
||||
Source: lint.CABFBaselineRequirements,
|
||||
EffectiveDate: util.CABEffectiveDate,
|
||||
Lint: &caDigSignNotSet{},
|
||||
})
|
||||
}
|
||||
|
||||
func (l *caDigSignNotSet) Initialize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *caDigSignNotSet) CheckApplies(c *x509.Certificate) bool {
|
||||
return c.IsCA && util.IsExtInCert(c, util.KeyUsageOID)
|
||||
}
|
||||
|
||||
func (l *caDigSignNotSet) Execute(c *x509.Certificate) *lint.LintResult {
|
||||
if c.KeyUsage&x509.KeyUsageDigitalSignature != 0 {
|
||||
return &lint.LintResult{Status: lint.Pass}
|
||||
} else {
|
||||
return &lint.LintResult{Status: lint.Notice}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue