Add vendor for github.com/containerd/imgcrypt

Updates to version using containerd v2.0.0-rc

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan 2024-05-28 13:49:34 -07:00
parent 87bab6cdc7
commit 9857afda44
No known key found for this signature in database
GPG Key ID: F58C5D0A4405ACDB
145 changed files with 32194 additions and 0 deletions

7
go.mod
View File

@ -19,6 +19,7 @@ require (
github.com/containerd/fifo v1.1.0
github.com/containerd/go-cni v1.1.9
github.com/containerd/go-runc v1.1.0
github.com/containerd/imgcrypt v1.1.12-0.20240528203804-3ca09a2db5cd
github.com/containerd/log v0.1.0
github.com/containerd/nri v0.6.1
github.com/containerd/platforms v0.2.0
@ -90,9 +91,11 @@ require (
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cilium/ebpf v0.11.0 // indirect
github.com/containers/ocicrypt v1.1.10 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
@ -107,6 +110,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@ -117,12 +121,15 @@ require (
github.com/prometheus/common v0.48.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/metric v1.26.0 // indirect
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect

27
go.sum
View File

@ -53,6 +53,8 @@ github.com/containerd/go-cni v1.1.9 h1:ORi7P1dYzCwVM6XPN4n3CbkuOx/NZ2DOqy+SHRdo9
github.com/containerd/go-cni v1.1.9/go.mod h1:XYrZJ1d5W6E2VOvjffL3IZq0Dz6bsVlERHbekNK90PM=
github.com/containerd/go-runc v1.1.0 h1:OX4f+/i2y5sUT7LhmcJH7GYrjjhHa1QI4e8yO0gGleA=
github.com/containerd/go-runc v1.1.0/go.mod h1:xJv2hFF7GvHtTJd9JqTS2UVxMkULUYw4JN5XAUZqH5U=
github.com/containerd/imgcrypt v1.1.12-0.20240528203804-3ca09a2db5cd h1:GjAKQysk1gNYupyhuvCyNvNRNtmPF7e8/+OhqT/8zu4=
github.com/containerd/imgcrypt v1.1.12-0.20240528203804-3ca09a2db5cd/go.mod h1:HwgRdLSki2P6QOWbrqnK9vBs5Ew9WNjY1nPTB/xA9w0=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/nri v0.6.1 h1:xSQ6elnQ4Ynidm9u49ARK9wRKHs80HCUI+bkXOxV4mA=
@ -69,6 +71,8 @@ github.com/containernetworking/cni v1.2.0 h1:fEjhlfWwWAXEvlcMQu/i6z8DA0Kbu7EcmR5
github.com/containernetworking/cni v1.2.0/go.mod h1:/r+vA/7vrynNfbvSP9g8tIKEoy6win7sALJAw4ZiJks=
github.com/containernetworking/plugins v1.4.1 h1:+sJRRv8PKhLkXIl6tH1D7RMi+CbbHutDGU+ErLBORWA=
github.com/containernetworking/plugins v1.4.1/go.mod h1:n6FFGKcaY4o2o5msgu/UImtoC+fpQXM3076VHfHbj60=
github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic=
github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
@ -96,6 +100,8 @@ github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@ -201,6 +207,8 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ=
github.com/mdlayher/vsock v1.2.1/go.mod h1:NRfCibel++DgeMD8z/hP+PPTjlNJsdPOmxcnENvE+SE=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
@ -283,6 +291,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I=
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@ -324,6 +334,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0=
go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
@ -353,6 +365,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4=
golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
@ -362,6 +377,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -377,6 +393,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -389,6 +407,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -410,16 +429,23 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
@ -433,6 +459,7 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

2
vendor/github.com/containerd/imgcrypt/.gitignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
*~
/bin/

31
vendor/github.com/containerd/imgcrypt/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,31 @@
linters:
enable:
- depguard
- staticcheck
- unconvert
- gofmt
- goimports
- revive
- ineffassign
- vet
- unused
- misspell
run:
skip-dirs:
- cmd/ctr/commands/run
- cmd/ctr/commands/images
- cmd\\ctr\\commands\\run
- cmd\\ctr\\commands\\images
skip-files:
- cmd/ctr/commands/commands.go
- cmd\\ctr\\commands\\commands.go
linters-settings:
depguard:
rules:
main:
files:
- $all
deny:
- pkg: "io/ioutil"

63
vendor/github.com/containerd/imgcrypt/CHANGES generated vendored Normal file
View File

@ -0,0 +1,63 @@
CHANGES
v1.1.10:
- Updated to ocicrypt v1.1.10
- Added test cases with JKW EC key and added 2 more RSA keys
- Sync'ed enc-ctr with ctr of containerd v1.6.30
- Updated dependencies
v1.1.9:
- Updated to ocicrypt v1.1.9
- Updated dependencies
v1.1.8:
- Updated to containerd v1.6.23
- Sync'ed enc-ctr with ctr of containerd v1.6.23
- Updated to ocicrypt v1.1.8
v1.1.7:
- Added support for zstd-compressed layers
- Update to ocicrypt v1.1.6 for zstd-related dependencies
- Update to containerd v1.6.8
- Sync'ed ctr-enc with upstream ctr changes to import command
- Add support for --all-platforms to encrypt command of ctr-enc
v1.1.6:
- Update to ocicrypt v1.1.5 for yaml v3.0 dependency
- Update to containerd v1.6.6 for runc v1.1.2 dependency
v1.1.5:
- Update to ocicrypt v1.1.4; sha256 is the default now for padding in OAEP
for pkcs11; Set OCICRYPT_OAEP_HASHALG=sha1 environment variable to force
sha1 usage, which is required for example for SoftHSM 2.6.1.
v1.1.4:
- Fixed issue in CheckAuthorization() callpath for images with a ManifestList
- CVE-2022-24778
- Fix: https://github.com/containerd/imgcrypt/commit/6fdd9818a4d8142107b7ecd767d839c9707700d9
- Added test case covering this
- Updated to ocicrypt 1.1.3
- Updated to containerd 1.6.1
v1.1.3:
- Release v1.1.3 addresses issue #62 due to re-tagging of v1.1.2
- docs: update referenced containerd project branch to main
- Update linter to match containerd repo
- Update CI golang version
- Updated to containerd 1.5.8
v1.1.2:
- Decouple CreateCryptoConfig() from github.com/urfave/cli
- Updated to containerd 1.5.7
- Implemented ConvertFunc for image en- and decryption
- Replace pkg/errors with errors package
- Updated to ocicrypt 1.1.2
- Sync'ed ctr-enc with ctr of containerd-1.5.0
v1.1.1:
- rebased on ocicrypt 1.1.1
v1.1.0:
- rebased on ocicrypt 1.1.0
- added pkcs11 support; experimental
- added keyprovider support

191
vendor/github.com/containerd/imgcrypt/LICENSE generated vendored Normal file
View File

@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
https://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
Copyright The containerd Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

9
vendor/github.com/containerd/imgcrypt/MAINTAINERS generated vendored Normal file
View File

@ -0,0 +1,9 @@
# imgcrypt maintainers
#
# As a containerd sub-project, containerd maintainers are also included from https://github.com/containerd/project/blob/main/MAINTAINERS.
# See https://github.com/containerd/project/blob/main/GOVERNANCE.md for description of maintainer role
#
# MAINTAINERS
# GitHub ID, Name, Email address
stefanberger, Stefan Berger, stefanb@linux.ibm.com
lumjjb, Brandon Lum, lumjjb@gmail.com

67
vendor/github.com/containerd/imgcrypt/Makefile generated vendored Normal file
View File

@ -0,0 +1,67 @@
# Copyright The containerd Authors.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Base path used to install.
DESTDIR ?= /usr/local
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always)
CTR_LDFLAGS=-ldflags '-X github.com/containerd/containerd/v2/version.Version=$(VERSION)'
COMMANDS=ctd-decoder ctr-enc
RELEASE_COMMANDS=ctd-decoder
BINARIES=$(addprefix bin/,$(COMMANDS))
RELEASE_BINARIES=$(addprefix bin/,$(RELEASE_COMMANDS))
.PHONY: check build ctd-decoder
all: build
build: $(BINARIES)
FORCE:
bin/ctd-decoder: cmd/ctd-decoder FORCE
cd cmd && go build -o ../$@ -v ./ctd-decoder/
bin/ctr-enc: cmd/ctr FORCE
cd cmd && go build -o ../$@ ${CTR_LDFLAGS} -v ./ctr/
check:
@echo "$@"
@golangci-lint run
@script/check_format.sh
install:
@echo "$@"
@mkdir -p $(DESTDIR)/bin
@install $(BINARIES) $(DESTDIR)/bin
containerd-release:
@echo "$@"
@mkdir -p $(DESTDIR)/bin
@install $(RELEASE_BINARIES) $(DESTDIR)/bin
uninstall:
@echo "$@"
@rm -f $(addprefix $(DESTDIR)/bin/,$(notdir $(BINARIES)))
clean:
@echo "$@"
@rm -f $(BINARIES)
test:
@echo "$@"
@go test ./...

108
vendor/github.com/containerd/imgcrypt/README.md generated vendored Normal file
View File

@ -0,0 +1,108 @@
# imgcrypt image encryption library and command line tool
Project `imgcrypt` is a non-core subproject of containerd.
The `imgcrypt` library provides API extensions for containerd to support encrypted container images and implements
the `ctd-decoder` command line tool for use by containerd to decrypt encrypted container images. An extended version
of containerd's `ctr` tool (`ctr-enc`) with support for encrypting and decrypting container images is also provided.
`imgcrypt` relies on the [`ocicrypt`](https://github.com/containers/ocicrypt) library for crypto functions on image layers.
# Usage
`imgcrypt` requires containerd 1.3 or later. Containerd 1.4 or later is required when used with Kubernetes.
For configuration instructions for kubernetes, please consult the [CRI decryption document](https://github.com/containerd/containerd/blob/main/docs/cri/decryption.md).
Build and install `imgcrypt`:
```
# make
# sudo make install
```
Start containerd with a configuration file that looks as follows. To avoid interference with a containerd from a Docker
installation we use /tmp for directories. Also, we build containerd 1.3 from the source but do not install it.
```
# cat config.toml
version = 2
disabled_plugins = ["io.containerd.grpc.v1.cri"]
root = "/tmp/var/lib/containerd"
state = "/tmp/run/containerd"
[grpc]
address = "/tmp/run/containerd/containerd.sock"
uid = 0
gid = 0
[stream_processors]
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.gzip"]
accepts = ["application/vnd.oci.image.layer.v1.tar+gzip+encrypted"]
returns = "application/vnd.oci.image.layer.v1.tar+gzip"
path = "/usr/local/bin/ctd-decoder"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar.zstd"]
accepts = ["application/vnd.oci.image.layer.v1.tar+zstd+encrypted"]
returns = "application/vnd.oci.image.layer.v1.tar+zstd"
path = "/usr/local/bin/ctd-decoder"
[stream_processors."io.containerd.ocicrypt.decoder.v1.tar"]
accepts = ["application/vnd.oci.image.layer.v1.tar+encrypted"]
returns = "application/vnd.oci.image.layer.v1.tar"
path = "/usr/local/bin/ctd-decoder"
# sudo ~/src/github.com/containerd/containerd/bin/containerd -c config.toml
```
Create an RSA key pair using the openssl command line tool and encrypted an image:
```
# openssl genrsa -out mykey.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................................+++++
............................+++++
e is 65537 (0x010001)
# openssl rsa -in mykey.pem -pubout -out mypubkey.pem
writing RSA key
# sudo chmod 0666 /tmp/run/containerd/containerd.sock
# CTR="/usr/local/bin/ctr-enc -a /tmp/run/containerd/containerd.sock"
# $CTR images pull --all-platforms docker.io/library/bash:latest
[...]
# $CTR images layerinfo --platform linux/amd64 docker.io/library/bash:latest
# DIGEST PLATFORM SIZE ENCRYPTION RECIPIENTS
0 sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609 linux/amd64 2789669
1 sha256:7dd01fd971d4ec7058c5636a505327b24e5fc8bd7f62816a9d518472bd9b15c0 linux/amd64 3174665
2 sha256:691cfbca522787898c8b37f063dd20e5524e7d103e1a3b298bd2e2b8da54faf5 linux/amd64 340
# $CTR images encrypt --recipient jwe:mypubkey.pem --platform linux/amd64 docker.io/library/bash:latest bash.enc:latest
Encrypting docker.io/library/bash:latest to bash.enc:latest
$ $CTR images layerinfo --platform linux/amd64 bash.enc:latest
# DIGEST PLATFORM SIZE ENCRYPTION RECIPIENTS
0 sha256:360be141b01f69b25427a9085b36ba8ad7d7a335449013fa6b32c1ecb894ab5b linux/amd64 2789669 jwe [jwe]
1 sha256:ac601e66cdd275ee0e10afead03a2722e153a60982122d2d369880ea54fe82f8 linux/amd64 3174665 jwe [jwe]
2 sha256:41e47064fd00424e328915ad2f7f716bd86ea2d0d8315edaf33ecaa6a2464530 linux/amd64 340 jwe [jwe]
```
Start a local image registry so we can push the encrypted image to it. A recent versions of the registry is required
to accept encrypted container images.
```
# docker pull registry:latest
# docker run -d -p 5000:5000 --restart=always --name registry registry
```
Push the encrypted image to the local registry, pull it using `ctr-enc`, and then run the image.
```
# $CTR images tag bash.enc:latest localhost:5000/bash.enc:latest
# $CTR images push localhost:5000/bash.enc:latest
# $CTR images rm localhost:5000/bash.enc:latest bash.enc:latest
# $CTR images pull localhost:5000/bash.enc:latest
# sudo $CTR run --rm localhost:5000/bash.enc:latest test echo 'Hello World!'
ctr: you are not authorized to use this image: missing private key needed for decryption
# sudo $CTR run --rm --key mykey.pem localhost:5000/bash.enc:latest test echo 'Hello World!'
Hello World!
```
## Project details
**imgcrypt** is a non-core containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
As a containerd sub-project, you will find the:
* [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),
* [Maintainers](MAINTAINERS),
* and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)
information in our [`containerd/project`](https://github.com/containerd/project) repository.

View File

@ -0,0 +1,83 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 encryption
import (
"context"
"fmt"
containerd "github.com/containerd/containerd/v2/client"
"github.com/containerd/containerd/v2/core/containers"
"github.com/containerd/containerd/v2/core/diff"
"github.com/containerd/errdefs"
"github.com/containerd/imgcrypt"
"github.com/containerd/typeurl/v2"
encconfig "github.com/containers/ocicrypt/config"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
// WithDecryptedUnpack allows to pass parameters the 'layertool' needs to the applier
func WithDecryptedUnpack(data *imgcrypt.Payload) diff.ApplyOpt {
return func(_ context.Context, desc ocispec.Descriptor, c *diff.ApplyConfig) error {
data.Descriptor = desc
anything, err := typeurl.MarshalAny(data)
if err != nil {
return fmt.Errorf("failed to marshal payload: %w", err)
}
if c.ProcessorPayloads == nil {
c.ProcessorPayloads = make(map[string]typeurl.Any, len(imgcrypt.PayloadToolIDs))
}
for _, id := range imgcrypt.PayloadToolIDs {
c.ProcessorPayloads[id] = anything
}
return nil
}
}
// WithUnpackConfigApplyOpts allows to pass an ApplyOpt
func WithUnpackConfigApplyOpts(opt diff.ApplyOpt) containerd.UnpackOpt {
return func(_ context.Context, uc *containerd.UnpackConfig) error {
uc.ApplyOpts = append(uc.ApplyOpts, opt)
return nil
}
}
// WithUnpackOpts is used to add unpack options to the unpacker.
func WithUnpackOpts(opts []containerd.UnpackOpt) containerd.RemoteOpt {
return func(_ *containerd.Client, c *containerd.RemoteContext) error {
c.UnpackOpts = append(c.UnpackOpts, opts...)
return nil
}
}
// WithAuthorizationCheck checks the authorization of keys used for encrypted containers
// be checked upon creation of a container
func WithAuthorizationCheck(dc *encconfig.DecryptConfig) containerd.NewContainerOpts {
return func(ctx context.Context, client *containerd.Client, c *containers.Container) error {
image, err := client.ImageService().Get(ctx, c.Image)
if errdefs.IsNotFound(err) {
// allow creation of container without a existing image
return nil
} else if err != nil {
return err
}
return CheckAuthorization(ctx, client.ContentStore(), image.Target, dc)
}
}

View File

@ -0,0 +1,512 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 encryption
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"math/rand"
"github.com/containerd/containerd/v2/core/content"
"github.com/containerd/containerd/v2/core/images"
"github.com/containerd/containerd/v2/core/images/converter"
"github.com/containerd/errdefs"
"github.com/containerd/platforms"
"github.com/containers/ocicrypt"
encconfig "github.com/containers/ocicrypt/config"
encocispec "github.com/containers/ocicrypt/spec"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
type cryptoOp int
const (
cryptoOpEncrypt cryptoOp = iota
cryptoOpDecrypt = iota
cryptoOpUnwrapOnly = iota
)
// LayerFilter allows to select Layers by certain criteria
type LayerFilter func(desc ocispec.Descriptor) bool
// isLocalPlatform determines whether the given platform matches the local one
func isLocalPlatform(platform *ocispec.Platform) bool {
matcher := platforms.NewMatcher(*platform)
return matcher.Match(platforms.DefaultSpec())
}
// IsEncryptedDiff returns true if mediaType is a known encrypted media type.
func IsEncryptedDiff(_ context.Context, mediaType string) bool {
switch mediaType {
case encocispec.MediaTypeLayerZstdEnc, encocispec.MediaTypeLayerGzipEnc, encocispec.MediaTypeLayerEnc:
return true
}
return false
}
// HasEncryptedLayer returns true if any LayerInfo indicates that the layer is encrypted
func HasEncryptedLayer(ctx context.Context, layerInfos []ocispec.Descriptor) bool {
for i := 0; i < len(layerInfos); i++ {
if IsEncryptedDiff(ctx, layerInfos[i].MediaType) {
return true
}
}
return false
}
// encryptLayer encrypts the layer using the CryptoConfig and creates a new OCI Descriptor.
// A call to this function may also only manipulate the wrapped keys list.
// The caller is expected to store the returned encrypted data and OCI Descriptor
func encryptLayer(cc *encconfig.CryptoConfig, dataReader content.ReaderAt, desc ocispec.Descriptor) (ocispec.Descriptor, io.Reader, ocicrypt.EncryptLayerFinalizer, error) {
var (
size int64
d digest.Digest
err error
)
encLayerReader, encLayerFinalizer, err := ocicrypt.EncryptLayer(cc.EncryptConfig, ocicrypt.ReaderFromReaderAt(dataReader), desc)
if err != nil {
return ocispec.Descriptor{}, nil, nil, err
}
// were data touched ?
if encLayerReader != nil {
size = 0
d = ""
} else {
size = desc.Size
d = desc.Digest
}
newDesc := ocispec.Descriptor{
Digest: d,
Size: size,
Platform: desc.Platform,
}
switch desc.MediaType {
case images.MediaTypeDockerSchema2LayerGzip:
newDesc.MediaType = encocispec.MediaTypeLayerGzipEnc
case images.MediaTypeDockerSchema2Layer:
newDesc.MediaType = encocispec.MediaTypeLayerEnc
case encocispec.MediaTypeLayerGzipEnc:
newDesc.MediaType = encocispec.MediaTypeLayerGzipEnc
case encocispec.MediaTypeLayerZstdEnc:
newDesc.MediaType = encocispec.MediaTypeLayerZstdEnc
case encocispec.MediaTypeLayerEnc:
newDesc.MediaType = encocispec.MediaTypeLayerEnc
// TODO: Mediatypes to be added in ocispec
case ocispec.MediaTypeImageLayerGzip:
newDesc.MediaType = encocispec.MediaTypeLayerGzipEnc
case ocispec.MediaTypeImageLayerZstd:
newDesc.MediaType = encocispec.MediaTypeLayerZstdEnc
case ocispec.MediaTypeImageLayer:
newDesc.MediaType = encocispec.MediaTypeLayerEnc
default:
return ocispec.Descriptor{}, nil, nil, fmt.Errorf("unsupporter layer MediaType: %s", desc.MediaType)
}
return newDesc, encLayerReader, encLayerFinalizer, nil
}
// DecryptLayer decrypts the layer using the DecryptConfig and creates a new OCI Descriptor.
// The caller is expected to store the returned plain data and OCI Descriptor
func DecryptLayer(dc *encconfig.DecryptConfig, dataReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (ocispec.Descriptor, io.Reader, digest.Digest, error) {
resultReader, layerDigest, err := ocicrypt.DecryptLayer(dc, dataReader, desc, unwrapOnly)
if err != nil || unwrapOnly {
return ocispec.Descriptor{}, nil, "", err
}
newDesc := ocispec.Descriptor{
Size: 0,
Platform: desc.Platform,
}
switch desc.MediaType {
case encocispec.MediaTypeLayerGzipEnc:
newDesc.MediaType = images.MediaTypeDockerSchema2LayerGzip
case encocispec.MediaTypeLayerZstdEnc:
newDesc.MediaType = ocispec.MediaTypeImageLayerZstd
case encocispec.MediaTypeLayerEnc:
newDesc.MediaType = images.MediaTypeDockerSchema2Layer
default:
return ocispec.Descriptor{}, nil, "", fmt.Errorf("unsupporter layer MediaType: %s", desc.MediaType)
}
return newDesc, resultReader, layerDigest, nil
}
// decryptLayer decrypts the layer using the CryptoConfig and creates a new OCI Descriptor.
// The caller is expected to store the returned plain data and OCI Descriptor
func decryptLayer(cc *encconfig.CryptoConfig, dataReader content.ReaderAt, desc ocispec.Descriptor, unwrapOnly bool) (ocispec.Descriptor, io.Reader, error) {
resultReader, d, err := ocicrypt.DecryptLayer(cc.DecryptConfig, ocicrypt.ReaderFromReaderAt(dataReader), desc, unwrapOnly)
if err != nil || unwrapOnly {
return ocispec.Descriptor{}, nil, err
}
newDesc := ocispec.Descriptor{
Digest: d,
Size: 0,
Platform: desc.Platform,
}
switch desc.MediaType {
case encocispec.MediaTypeLayerGzipEnc:
newDesc.MediaType = images.MediaTypeDockerSchema2LayerGzip
case encocispec.MediaTypeLayerZstdEnc:
newDesc.MediaType = ocispec.MediaTypeImageLayerZstd
case encocispec.MediaTypeLayerEnc:
newDesc.MediaType = images.MediaTypeDockerSchema2Layer
default:
return ocispec.Descriptor{}, nil, fmt.Errorf("unsupporter layer MediaType: %s", desc.MediaType)
}
return newDesc, resultReader, nil
}
// cryptLayer handles the changes due to encryption or decryption of a layer
func cryptLayer(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, cryptoOp cryptoOp) (ocispec.Descriptor, error) {
var (
resultReader io.Reader
newDesc ocispec.Descriptor
encLayerFinalizer ocicrypt.EncryptLayerFinalizer
)
dataReader, err := cs.ReaderAt(ctx, desc)
if err != nil {
return ocispec.Descriptor{}, err
}
defer dataReader.Close()
if cryptoOp == cryptoOpEncrypt {
newDesc, resultReader, encLayerFinalizer, err = encryptLayer(cc, dataReader, desc)
} else {
newDesc, resultReader, err = decryptLayer(cc, dataReader, desc, cryptoOp == cryptoOpUnwrapOnly)
}
if err != nil || cryptoOp == cryptoOpUnwrapOnly {
return ocispec.Descriptor{}, err
}
newDesc.Annotations = ocicrypt.FilterOutAnnotations(desc.Annotations)
// some operations, such as changing recipients, may not touch the layer at all
if resultReader != nil {
var ref string
// If we have the digest, write blob with checks
haveDigest := newDesc.Digest.String() != ""
if haveDigest {
ref = fmt.Sprintf("layer-%s", newDesc.Digest.String())
} else {
ref = fmt.Sprintf("blob-%d-%d", rand.Int(), rand.Int())
}
if haveDigest {
if err := content.WriteBlob(ctx, cs, ref, resultReader, newDesc); err != nil {
return ocispec.Descriptor{}, fmt.Errorf("failed to write config: %w", err)
}
} else {
newDesc.Digest, newDesc.Size, err = ingestReader(ctx, cs, ref, resultReader)
if err != nil {
return ocispec.Descriptor{}, err
}
}
}
// After performing encryption, call finalizer to get annotations
if encLayerFinalizer != nil {
annotations, err := encLayerFinalizer()
if err != nil {
return ocispec.Descriptor{}, fmt.Errorf("error getting annotations from encLayer finalizer: %w", err)
}
for k, v := range annotations {
newDesc.Annotations[k] = v
}
}
return newDesc, err
}
func ingestReader(ctx context.Context, cs content.Ingester, ref string, r io.Reader) (digest.Digest, int64, error) {
cw, err := content.OpenWriter(ctx, cs, content.WithRef(ref))
if err != nil {
return "", 0, fmt.Errorf("failed to open writer: %w", err)
}
defer cw.Close()
if _, err := content.CopyReader(cw, r); err != nil {
return "", 0, fmt.Errorf("copy failed: %w", err)
}
st, err := cw.Status()
if err != nil {
return "", 0, fmt.Errorf("failed to get state: %w", err)
}
if err := cw.Commit(ctx, st.Offset, ""); err != nil {
if !errdefs.IsAlreadyExists(err) {
return "", 0, fmt.Errorf("failed commit on ref %q: %w", ref, err)
}
}
return cw.Digest(), st.Offset, nil
}
// Encrypt or decrypt all the Children of a given descriptor
func cryptChildren(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp, _ *ocispec.Platform) (ocispec.Descriptor, bool, error) {
children, err := images.Children(ctx, cs, desc)
if err != nil {
if errdefs.IsNotFound(err) {
return desc, false, nil
}
return ocispec.Descriptor{}, false, err
}
var newLayers []ocispec.Descriptor
var config ocispec.Descriptor
modified := false
for _, child := range children {
// we only encrypt child layers and have to update their parents if encryption happened
switch child.MediaType {
case images.MediaTypeDockerSchema2Config, ocispec.MediaTypeImageConfig:
config = child
case images.MediaTypeDockerSchema2LayerGzip, images.MediaTypeDockerSchema2Layer,
ocispec.MediaTypeImageLayerGzip, ocispec.MediaTypeImageLayer,
ocispec.MediaTypeImageLayerZstd:
if cryptoOp == cryptoOpEncrypt && lf(child) {
nl, err := cryptLayer(ctx, cs, child, cc, cryptoOp)
if err != nil {
return ocispec.Descriptor{}, false, err
}
modified = true
newLayers = append(newLayers, nl)
} else {
newLayers = append(newLayers, child)
}
case encocispec.MediaTypeLayerGzipEnc, encocispec.MediaTypeLayerZstdEnc, encocispec.MediaTypeLayerEnc:
// this one can be decrypted but also its recipients list changed
if lf(child) {
nl, err := cryptLayer(ctx, cs, child, cc, cryptoOp)
if err != nil || cryptoOp == cryptoOpUnwrapOnly {
return ocispec.Descriptor{}, false, err
}
modified = true
newLayers = append(newLayers, nl)
} else {
newLayers = append(newLayers, child)
}
case images.MediaTypeDockerSchema2LayerForeign, images.MediaTypeDockerSchema2LayerForeignGzip, "application/vnd.in-toto+json":
// never encrypt/decrypt
newLayers = append(newLayers, child)
default:
return ocispec.Descriptor{}, false, fmt.Errorf("bad/unhandled MediaType %s in encryptChildren", child.MediaType)
}
}
if modified && len(newLayers) > 0 {
newManifest := ocispec.Manifest{
Versioned: specs.Versioned{
SchemaVersion: 2,
},
Config: config,
Layers: newLayers,
}
mb, err := json.MarshalIndent(newManifest, "", " ")
if err != nil {
return ocispec.Descriptor{}, false, fmt.Errorf("failed to marshal image: %w", err)
}
newDesc := ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageManifest,
Size: int64(len(mb)),
Digest: digest.Canonical.FromBytes(mb),
Platform: desc.Platform,
}
labels := map[string]string{}
labels["containerd.io/gc.ref.content.0"] = newManifest.Config.Digest.String()
for i, ch := range newManifest.Layers {
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i+1)] = ch.Digest.String()
}
ref := fmt.Sprintf("manifest-%s", newDesc.Digest.String())
if err := content.WriteBlob(ctx, cs, ref, bytes.NewReader(mb), newDesc, content.WithLabels(labels)); err != nil {
return ocispec.Descriptor{}, false, fmt.Errorf("failed to write config: %w", err)
}
return newDesc, true, nil
}
return desc, modified, nil
}
// cryptManifest encrypts or decrypts the children of a top level manifest
func cryptManifest(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp) (ocispec.Descriptor, bool, error) {
p, err := content.ReadBlob(ctx, cs, desc)
if err != nil {
return ocispec.Descriptor{}, false, err
}
var manifest ocispec.Manifest
if err := json.Unmarshal(p, &manifest); err != nil {
return ocispec.Descriptor{}, false, err
}
platform := platforms.DefaultSpec()
newDesc, modified, err := cryptChildren(ctx, cs, desc, cc, lf, cryptoOp, &platform)
if err != nil || cryptoOp == cryptoOpUnwrapOnly {
return ocispec.Descriptor{}, false, err
}
return newDesc, modified, nil
}
// cryptManifestList encrypts or decrypts the children of a top level manifest list
func cryptManifestList(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp) (ocispec.Descriptor, bool, error) {
// read the index; if any layer is encrypted and any manifests change we will need to rewrite it
b, err := content.ReadBlob(ctx, cs, desc)
if err != nil {
return ocispec.Descriptor{}, false, err
}
var index ocispec.Index
if err := json.Unmarshal(b, &index); err != nil {
return ocispec.Descriptor{}, false, err
}
var newManifests []ocispec.Descriptor
modified := false
for _, manifest := range index.Manifests {
if cryptoOp == cryptoOpUnwrapOnly && !isLocalPlatform(manifest.Platform) {
continue
}
newManifest, m, err := cryptChildren(ctx, cs, manifest, cc, lf, cryptoOp, manifest.Platform)
if err != nil || cryptoOp == cryptoOpUnwrapOnly {
return ocispec.Descriptor{}, false, err
}
if m {
modified = true
}
newManifests = append(newManifests, newManifest)
}
if cryptoOp == cryptoOpUnwrapOnly {
return ocispec.Descriptor{}, false, fmt.Errorf("No manifest found for local platform")
}
if modified {
// we need to update the index
newIndex := ocispec.Index{
Versioned: index.Versioned,
Manifests: newManifests,
}
mb, err := json.MarshalIndent(newIndex, "", " ")
if err != nil {
return ocispec.Descriptor{}, false, fmt.Errorf("failed to marshal index: %w", err)
}
newDesc := ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageIndex,
Size: int64(len(mb)),
Digest: digest.Canonical.FromBytes(mb),
}
labels := map[string]string{}
for i, m := range newIndex.Manifests {
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = m.Digest.String()
}
ref := fmt.Sprintf("index-%s", newDesc.Digest.String())
if err = content.WriteBlob(ctx, cs, ref, bytes.NewReader(mb), newDesc, content.WithLabels(labels)); err != nil {
return ocispec.Descriptor{}, false, fmt.Errorf("failed to write index: %w", err)
}
return newDesc, true, nil
}
return desc, false, nil
}
// cryptImage is the dispatcher to encrypt/decrypt an image; it accepts either an OCI descriptor
// representing a manifest list or a single manifest
func cryptImage(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter, cryptoOp cryptoOp) (ocispec.Descriptor, bool, error) {
if cc == nil {
return ocispec.Descriptor{}, false, errors.New("invalid argument: CryptoConfig must not be nil")
}
switch desc.MediaType {
case ocispec.MediaTypeImageIndex, images.MediaTypeDockerSchema2ManifestList:
return cryptManifestList(ctx, cs, desc, cc, lf, cryptoOp)
case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest:
return cryptManifest(ctx, cs, desc, cc, lf, cryptoOp)
default:
return ocispec.Descriptor{}, false, fmt.Errorf("unhandled media type: %s", desc.MediaType)
}
}
// EncryptImage encrypts an image; it accepts either an OCI descriptor representing a manifest list or a single manifest
func EncryptImage(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter) (ocispec.Descriptor, bool, error) {
return cryptImage(ctx, cs, desc, cc, lf, cryptoOpEncrypt)
}
// DecryptImage decrypts an image; it accepts either an OCI descriptor representing a manifest list or a single manifest
func DecryptImage(ctx context.Context, cs content.Store, desc ocispec.Descriptor, cc *encconfig.CryptoConfig, lf LayerFilter) (ocispec.Descriptor, bool, error) {
return cryptImage(ctx, cs, desc, cc, lf, cryptoOpDecrypt)
}
// GetImageEncryptConverter returns a converter function for image encryption
func GetImageEncryptConverter(cc *encconfig.CryptoConfig, lf LayerFilter) converter.ConvertFunc {
return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) {
newDesc, _, err := EncryptImage(ctx, cs, desc, cc, lf)
if err != nil {
return nil, err
}
return &newDesc, nil
}
}
// GetImageDecryptConverter returns a converter function for image decryption
func GetImageDecryptConverter(cc *encconfig.CryptoConfig, lf LayerFilter) converter.ConvertFunc {
return func(ctx context.Context, cs content.Store, desc ocispec.Descriptor) (*ocispec.Descriptor, error) {
newDesc, _, err := DecryptImage(ctx, cs, desc, cc, lf)
if err != nil {
return nil, err
}
return &newDesc, nil
}
}
// CheckAuthorization checks whether a user has the right keys to be allowed to access an image (every layer)
// It takes decrypting of the layers only as far as decrypting the asymmetrically encrypted data
// The decryption is only done for the current platform
func CheckAuthorization(ctx context.Context, cs content.Store, desc ocispec.Descriptor, dc *encconfig.DecryptConfig) error {
cc := encconfig.InitDecryption(dc.Parameters)
lf := func(desc ocispec.Descriptor) bool {
return true
}
_, _, err := cryptImage(ctx, cs, desc, &cc, lf, cryptoOpUnwrapOnly)
if err != nil {
return fmt.Errorf("you are not authorized to use this image: %w", err)
}
return nil
}

44
vendor/github.com/containerd/imgcrypt/payload.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright The containerd Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 imgcrypt
import (
"github.com/containerd/typeurl/v2"
encconfig "github.com/containers/ocicrypt/config"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
const (
PayloadURI = "io.containerd.ocicrypt.v1.Payload"
)
var PayloadToolIDs = []string{
"io.containerd.ocicrypt.decoder.v1.tar",
"io.containerd.ocicrypt.decoder.v1.tar.gzip",
}
func init() {
typeurl.Register(&Payload{}, PayloadURI)
}
// Payload holds data that the external layer decryption tool
// needs for decrypting a layer
type Payload struct {
DecryptConfig encconfig.DecryptConfig
Descriptor ocispec.Descriptor
}

1
vendor/github.com/containers/ocicrypt/.gitignore generated vendored Normal file
View File

@ -0,0 +1 @@
*~

35
vendor/github.com/containers/ocicrypt/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,35 @@
linters:
enable:
- depguard
- staticcheck
- unconvert
- gofmt
- goimports
- revive
- ineffassign
- vet
- unused
- misspell
linters-settings:
depguard:
rules:
main:
files:
- $all
deny:
- pkg: "io/ioutil"
revive:
severity: error
rules:
- name: indent-error-flow
severity: warning
disabled: false
- name: error-strings
disabled: false
staticcheck:
# Suppress reports of deprecated packages
checks: ["-SA1019"]

10
vendor/github.com/containers/ocicrypt/ADOPTERS.md generated vendored Normal file
View File

@ -0,0 +1,10 @@
Below are list of adopters of the `ocicrypt` library or supports use of OCI encrypted images:
- [skopeo](https://github.com/containers/skopeo)
- [buildah](https://github.com/containers/buildah)
- [containerd](https://github.com/containerd/imgcrypt)
- [nerdctl](https://github.com/containerd/nerdctl)
- [distribution](https://github.com/distribution/distribution)
Below are the list of projects that are in the process of adopting support:
- [quay](https://github.com/quay/quay)
- [kata-containers](https://github.com/kata-containers/kata-containers)

View File

@ -0,0 +1,3 @@
## The OCIcrypt Library Project Community Code of Conduct
The OCIcrypt Library project follows the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md).

189
vendor/github.com/containers/ocicrypt/LICENSE generated vendored Normal file
View File

@ -0,0 +1,189 @@
Apache License
Version 2.0, January 2004
https://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
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

6
vendor/github.com/containers/ocicrypt/MAINTAINERS generated vendored Normal file
View File

@ -0,0 +1,6 @@
# ocicrypt maintainers
#
# Github ID, Name, Email Address
lumjjb, Brandon Lum, lumjjb@gmail.com
stefanberger, Stefan Berger, stefanb@linux.ibm.com
arronwy, Arron Wang, arron.wang@intel.com

35
vendor/github.com/containers/ocicrypt/Makefile generated vendored Normal file
View File

@ -0,0 +1,35 @@
# Copyright The containerd Authors.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
.PHONY: check build decoder generate-protobuf
all: build
FORCE:
check:
golangci-lint run
build: vendor
go build ./...
vendor:
go mod tidy
test:
go clean -testcache
go test ./... -test.v
generate-protobuf:
protoc -I utils/keyprovider/ utils/keyprovider/keyprovider.proto --go_out=plugins=grpc:utils/keyprovider

50
vendor/github.com/containers/ocicrypt/README.md generated vendored Normal file
View File

@ -0,0 +1,50 @@
# OCIcrypt Library
The `ocicrypt` library is the OCI image spec implementation of container image encryption. More details of the spec can be seen in the [OCI repository](https://github.com/opencontainers/image-spec/pull/775). The purpose of this library is to encode spec structures and consts in code, as well as provide a consistent implementation of image encryption across container runtimes and build tools.
Consumers of OCIcrypt:
- [containerd/imgcrypt](https://github.com/containerd/imgcrypt)
- [cri-o](https://github.com/cri-o/cri-o)
- [skopeo](https://github.com/containers/skopeo)
## Usage
There are various levels of usage for this library. The main consumers of these would be runtime/build tools, and a more specific use would be in the ability to extend cryptographic function.
### Runtime/Build tool usage
The general exposed interface a runtime/build tool would use, would be to perform encryption or decryption of layers:
```
package "github.com/containers/ocicrypt"
func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, desc ocispec.Descriptor) (io.Reader, EncryptLayerFinalizer, error)
func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error)
```
The settings/parameters to these functions can be specified via creation of an encryption config with the `github.com/containers/ocicrypt/config` package. We note that because setting of annotations and other fields of the layer descriptor is done through various means in different runtimes/build tools, it is the responsibility of the caller to still ensure that the layer descriptor follows the OCI specification (i.e. encoding, setting annotations, etc.).
### Crypto Agility and Extensibility
The implementation for both symmetric and asymmetric encryption used in this library are behind 2 main interfaces, which users can extend if need be. These are in the following packages:
- github.com/containers/ocicrypt/blockcipher - LayerBlockCipher interface for block ciphers
- github.com/containers/ocicrypt/keywrap - KeyWrapper interface for key wrapping
We note that adding interfaces here is risky outside the OCI spec is not recommended, unless for very specialized and confined usecases. Please open an issue or PR if there is a general usecase that could be added to the OCI spec.
#### Keyprovider interface
As part of the keywrap interface, there is a [keyprovider](https://github.com/containers/ocicrypt/blob/main/docs/keyprovider.md) implementation that allows one to call out to a binary or service.
## Security Issues
We consider security issues related to this library critical. Please report and security related issues by emailing maintainers in the [MAINTAINERS](MAINTAINERS) file.
## Ocicrypt Pkcs11 Support
Ocicrypt Pkcs11 support is currently experiemental. For more details, please refer to the [this document](docs/pkcs11.md).

3
vendor/github.com/containers/ocicrypt/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,3 @@
## Security and Disclosure Information Policy for the OCIcrypt Library Project
The OCIcrypt Library Project follows the [Security and Disclosure Information Policy](https://github.com/containers/common/blob/main/SECURITY.md) for the Containers Projects.

View File

@ -0,0 +1,161 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 blockcipher
import (
"errors"
"fmt"
"io"
"github.com/opencontainers/go-digest"
)
// LayerCipherType is the ciphertype as specified in the layer metadata
type LayerCipherType string
// TODO: Should be obtained from OCI spec once included
const (
AES256CTR LayerCipherType = "AES_256_CTR_HMAC_SHA256"
)
// PrivateLayerBlockCipherOptions includes the information required to encrypt/decrypt
// an image which are sensitive and should not be in plaintext
type PrivateLayerBlockCipherOptions struct {
// SymmetricKey represents the symmetric key used for encryption/decryption
// This field should be populated by Encrypt/Decrypt calls
SymmetricKey []byte `json:"symkey"`
// Digest is the digest of the original data for verification.
// This is NOT populated by Encrypt/Decrypt calls
Digest digest.Digest `json:"digest"`
// CipherOptions contains the cipher metadata used for encryption/decryption
// This field should be populated by Encrypt/Decrypt calls
CipherOptions map[string][]byte `json:"cipheroptions"`
}
// PublicLayerBlockCipherOptions includes the information required to encrypt/decrypt
// an image which are public and can be deduplicated in plaintext across multiple
// recipients
type PublicLayerBlockCipherOptions struct {
// CipherType denotes the cipher type according to the list of OCI suppported
// cipher types.
CipherType LayerCipherType `json:"cipher"`
// Hmac contains the hmac string to help verify encryption
Hmac []byte `json:"hmac"`
// CipherOptions contains the cipher metadata used for encryption/decryption
// This field should be populated by Encrypt/Decrypt calls
CipherOptions map[string][]byte `json:"cipheroptions"`
}
// LayerBlockCipherOptions contains the public and private LayerBlockCipherOptions
// required to encrypt/decrypt an image
type LayerBlockCipherOptions struct {
Public PublicLayerBlockCipherOptions
Private PrivateLayerBlockCipherOptions
}
// LayerBlockCipher returns a provider for encrypt/decrypt functionality
// for handling the layer data for a specific algorithm
type LayerBlockCipher interface {
// GenerateKey creates a symmetric key
GenerateKey() ([]byte, error)
// Encrypt takes in layer data and returns the ciphertext and relevant LayerBlockCipherOptions
Encrypt(layerDataReader io.Reader, opt LayerBlockCipherOptions) (io.Reader, Finalizer, error)
// Decrypt takes in layer ciphertext data and returns the plaintext and relevant LayerBlockCipherOptions
Decrypt(layerDataReader io.Reader, opt LayerBlockCipherOptions) (io.Reader, LayerBlockCipherOptions, error)
}
// LayerBlockCipherHandler is the handler for encrypt/decrypt for layers
type LayerBlockCipherHandler struct {
cipherMap map[LayerCipherType]LayerBlockCipher
}
// Finalizer is called after data blobs are written, and returns the LayerBlockCipherOptions for the encrypted blob
type Finalizer func() (LayerBlockCipherOptions, error)
// GetOpt returns the value of the cipher option and if the option exists
func (lbco LayerBlockCipherOptions) GetOpt(key string) (value []byte, ok bool) {
if v, ok := lbco.Public.CipherOptions[key]; ok {
return v, ok
} else if v, ok := lbco.Private.CipherOptions[key]; ok {
return v, ok
} else {
return nil, false
}
}
func wrapFinalizerWithType(fin Finalizer, typ LayerCipherType) Finalizer {
return func() (LayerBlockCipherOptions, error) {
lbco, err := fin()
if err != nil {
return LayerBlockCipherOptions{}, err
}
lbco.Public.CipherType = typ
return lbco, err
}
}
// Encrypt is the handler for the layer decryption routine
func (h *LayerBlockCipherHandler) Encrypt(plainDataReader io.Reader, typ LayerCipherType) (io.Reader, Finalizer, error) {
if c, ok := h.cipherMap[typ]; ok {
sk, err := c.GenerateKey()
if err != nil {
return nil, nil, err
}
opt := LayerBlockCipherOptions{
Private: PrivateLayerBlockCipherOptions{
SymmetricKey: sk,
},
}
encDataReader, fin, err := c.Encrypt(plainDataReader, opt)
if err == nil {
fin = wrapFinalizerWithType(fin, typ)
}
return encDataReader, fin, err
}
return nil, nil, fmt.Errorf("unsupported cipher type: %s", typ)
}
// Decrypt is the handler for the layer decryption routine
func (h *LayerBlockCipherHandler) Decrypt(encDataReader io.Reader, opt LayerBlockCipherOptions) (io.Reader, LayerBlockCipherOptions, error) {
typ := opt.Public.CipherType
if typ == "" {
return nil, LayerBlockCipherOptions{}, errors.New("no cipher type provided")
}
if c, ok := h.cipherMap[typ]; ok {
return c.Decrypt(encDataReader, opt)
}
return nil, LayerBlockCipherOptions{}, fmt.Errorf("unsupported cipher type: %s", typ)
}
// NewLayerBlockCipherHandler returns a new default handler
func NewLayerBlockCipherHandler() (*LayerBlockCipherHandler, error) {
h := LayerBlockCipherHandler{
cipherMap: map[LayerCipherType]LayerBlockCipher{},
}
var err error
h.cipherMap[AES256CTR], err = NewAESCTRLayerBlockCipher(256)
if err != nil {
return nil, fmt.Errorf("unable to set up Cipher AES-256-CTR: %w", err)
}
return &h, nil
}

View File

@ -0,0 +1,193 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 blockcipher
import (
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"errors"
"fmt"
"hash"
"io"
"github.com/containers/ocicrypt/utils"
)
// AESCTRLayerBlockCipher implements the AES CTR stream cipher
type AESCTRLayerBlockCipher struct {
keylen int // in bytes
reader io.Reader
encrypt bool
stream cipher.Stream
err error
hmac hash.Hash
expHmac []byte
doneEncrypting bool
}
type aesctrcryptor struct {
bc *AESCTRLayerBlockCipher
}
// NewAESCTRLayerBlockCipher returns a new AES SIV block cipher of 256 or 512 bits
func NewAESCTRLayerBlockCipher(bits int) (LayerBlockCipher, error) {
if bits != 256 {
return nil, errors.New("AES CTR bit count not supported")
}
return &AESCTRLayerBlockCipher{keylen: bits / 8}, nil
}
func (r *aesctrcryptor) Read(p []byte) (int, error) {
var (
o int
)
if r.bc.err != nil {
return 0, r.bc.err
}
o, err := utils.FillBuffer(r.bc.reader, p)
if err != nil {
if err == io.EOF {
r.bc.err = err
} else {
return 0, err
}
}
if !r.bc.encrypt {
if _, err := r.bc.hmac.Write(p[:o]); err != nil {
r.bc.err = fmt.Errorf("could not write to hmac: %w", err)
return 0, r.bc.err
}
if r.bc.err == io.EOF {
// Before we return EOF we let the HMAC comparison
// provide a verdict
if !hmac.Equal(r.bc.hmac.Sum(nil), r.bc.expHmac) {
r.bc.err = fmt.Errorf("could not properly decrypt byte stream; exp hmac: '%x', actual hmac: '%s'", r.bc.expHmac, r.bc.hmac.Sum(nil))
return 0, r.bc.err
}
}
}
r.bc.stream.XORKeyStream(p[:o], p[:o])
if r.bc.encrypt {
if _, err := r.bc.hmac.Write(p[:o]); err != nil {
r.bc.err = fmt.Errorf("could not write to hmac: %w", err)
return 0, r.bc.err
}
if r.bc.err == io.EOF {
// Final data encrypted; Do the 'then-MAC' part
r.bc.doneEncrypting = true
}
}
return o, r.bc.err
}
// init initializes an instance
func (bc *AESCTRLayerBlockCipher) init(encrypt bool, reader io.Reader, opts LayerBlockCipherOptions) (LayerBlockCipherOptions, error) {
var (
err error
)
key := opts.Private.SymmetricKey
if len(key) != bc.keylen {
return LayerBlockCipherOptions{}, fmt.Errorf("invalid key length of %d bytes; need %d bytes", len(key), bc.keylen)
}
nonce, ok := opts.GetOpt("nonce")
if !ok {
nonce = make([]byte, aes.BlockSize)
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return LayerBlockCipherOptions{}, fmt.Errorf("unable to generate random nonce: %w", err)
}
}
block, err := aes.NewCipher(key)
if err != nil {
return LayerBlockCipherOptions{}, fmt.Errorf("aes.NewCipher failed: %w", err)
}
bc.reader = reader
bc.encrypt = encrypt
bc.stream = cipher.NewCTR(block, nonce)
bc.err = nil
bc.hmac = hmac.New(sha256.New, key)
bc.expHmac = opts.Public.Hmac
bc.doneEncrypting = false
if !encrypt && len(bc.expHmac) == 0 {
return LayerBlockCipherOptions{}, errors.New("HMAC is not provided for decryption process")
}
lbco := LayerBlockCipherOptions{
Private: PrivateLayerBlockCipherOptions{
SymmetricKey: key,
CipherOptions: map[string][]byte{
"nonce": nonce,
},
},
}
return lbco, nil
}
// GenerateKey creates a synmmetric key
func (bc *AESCTRLayerBlockCipher) GenerateKey() ([]byte, error) {
key := make([]byte, bc.keylen)
if _, err := io.ReadFull(rand.Reader, key); err != nil {
return nil, err
}
return key, nil
}
// Encrypt takes in layer data and returns the ciphertext and relevant LayerBlockCipherOptions
func (bc *AESCTRLayerBlockCipher) Encrypt(plainDataReader io.Reader, opt LayerBlockCipherOptions) (io.Reader, Finalizer, error) {
lbco, err := bc.init(true, plainDataReader, opt)
if err != nil {
return nil, nil, err
}
finalizer := func() (LayerBlockCipherOptions, error) {
if !bc.doneEncrypting {
return LayerBlockCipherOptions{}, errors.New("Read()ing not complete, unable to finalize")
}
if lbco.Public.CipherOptions == nil {
lbco.Public.CipherOptions = map[string][]byte{}
}
lbco.Public.Hmac = bc.hmac.Sum(nil)
return lbco, nil
}
return &aesctrcryptor{bc}, finalizer, nil
}
// Decrypt takes in layer ciphertext data and returns the plaintext and relevant LayerBlockCipherOptions
func (bc *AESCTRLayerBlockCipher) Decrypt(encDataReader io.Reader, opt LayerBlockCipherOptions) (io.Reader, LayerBlockCipherOptions, error) {
lbco, err := bc.init(false, encDataReader, opt)
if err != nil {
return nil, LayerBlockCipherOptions{}, err
}
return utils.NewDelayedReader(&aesctrcryptor{bc}, 1024*10), lbco, nil
}

114
vendor/github.com/containers/ocicrypt/config/config.go generated vendored Normal file
View File

@ -0,0 +1,114 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 config
// EncryptConfig is the container image PGP encryption configuration holding
// the identifiers of those that will be able to decrypt the container and
// the PGP public keyring file data that contains their public keys.
type EncryptConfig struct {
// map holding 'gpg-recipients', 'gpg-pubkeyringfile', 'pubkeys', 'x509s'
Parameters map[string][][]byte
DecryptConfig DecryptConfig
}
// DecryptConfig wraps the Parameters map that holds the decryption key
type DecryptConfig struct {
// map holding 'privkeys', 'x509s', 'gpg-privatekeys'
Parameters map[string][][]byte
}
// CryptoConfig is a common wrapper for EncryptConfig and DecrypConfig that can
// be passed through functions that share much code for encryption and decryption
type CryptoConfig struct {
EncryptConfig *EncryptConfig
DecryptConfig *DecryptConfig
}
// InitDecryption initialized a CryptoConfig object with parameters used for decryption
func InitDecryption(dcparameters map[string][][]byte) CryptoConfig {
return CryptoConfig{
DecryptConfig: &DecryptConfig{
Parameters: dcparameters,
},
}
}
// InitEncryption initializes a CryptoConfig object with parameters used for encryption
// It also takes dcparameters that may be needed for decryption when adding a recipient
// to an already encrypted image
func InitEncryption(parameters, dcparameters map[string][][]byte) CryptoConfig {
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: parameters,
DecryptConfig: DecryptConfig{
Parameters: dcparameters,
},
},
}
}
// CombineCryptoConfigs takes a CryptoConfig list and creates a single CryptoConfig
// containing the crypto configuration of all the key bundles
func CombineCryptoConfigs(ccs []CryptoConfig) CryptoConfig {
ecparam := map[string][][]byte{}
ecdcparam := map[string][][]byte{}
dcparam := map[string][][]byte{}
for _, cc := range ccs {
if ec := cc.EncryptConfig; ec != nil {
addToMap(ecparam, ec.Parameters)
addToMap(ecdcparam, ec.DecryptConfig.Parameters)
}
if dc := cc.DecryptConfig; dc != nil {
addToMap(dcparam, dc.Parameters)
}
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ecparam,
DecryptConfig: DecryptConfig{
Parameters: ecdcparam,
},
},
DecryptConfig: &DecryptConfig{
Parameters: dcparam,
},
}
}
// AttachDecryptConfig adds DecryptConfig to the field of EncryptConfig so that
// the decryption parameters can be used to add recipients to an existing image
// if the user is able to decrypt it.
func (ec *EncryptConfig) AttachDecryptConfig(dc *DecryptConfig) {
if dc != nil {
addToMap(ec.DecryptConfig.Parameters, dc.Parameters)
}
}
func addToMap(orig map[string][][]byte, add map[string][][]byte) {
for k, v := range add {
if ov, ok := orig[k]; ok {
orig[k] = append(ov, v...)
} else {
orig[k] = v
}
}
}

View File

@ -0,0 +1,246 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 config
import (
"errors"
"fmt"
"strings"
"github.com/containers/ocicrypt/crypto/pkcs11"
"gopkg.in/yaml.v3"
)
// EncryptWithJwe returns a CryptoConfig to encrypt with jwe public keys
func EncryptWithJwe(pubKeys [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{
"pubkeys": pubKeys,
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithPkcs7 returns a CryptoConfig to encrypt with pkcs7 x509 certs
func EncryptWithPkcs7(x509s [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{
"x509s": x509s,
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithGpg returns a CryptoConfig to encrypt with configured gpg parameters
func EncryptWithGpg(gpgRecipients [][]byte, gpgPubRingFile []byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{
"gpg-recipients": gpgRecipients,
"gpg-pubkeyringfile": {gpgPubRingFile},
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithPkcs11 returns a CryptoConfig to encrypt with configured pkcs11 parameters
func EncryptWithPkcs11(pkcs11Config *pkcs11.Pkcs11Config, pkcs11Pubkeys, pkcs11Yamls [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := map[string][][]byte{}
if len(pkcs11Yamls) > 0 {
if pkcs11Config == nil {
return CryptoConfig{}, errors.New("pkcs11Config must not be nil")
}
p11confYaml, err := yaml.Marshal(pkcs11Config)
if err != nil {
return CryptoConfig{}, fmt.Errorf("Could not marshal Pkcs11Config to Yaml: %w", err)
}
dc = DecryptConfig{
Parameters: map[string][][]byte{
"pkcs11-config": {p11confYaml},
},
}
ep["pkcs11-yamls"] = pkcs11Yamls
}
if len(pkcs11Pubkeys) > 0 {
ep["pkcs11-pubkeys"] = pkcs11Pubkeys
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// EncryptWithKeyProvider returns a CryptoConfig to encrypt with configured keyprovider parameters
func EncryptWithKeyProvider(keyProviders [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{}
ep := make(map[string][][]byte)
for _, keyProvider := range keyProviders {
keyProvidersStr := string(keyProvider)
idx := strings.Index(keyProvidersStr, ":")
if idx > 0 {
ep[keyProvidersStr[:idx]] = append(ep[keyProvidersStr[:idx]], []byte(keyProvidersStr[idx+1:]))
} else {
ep[keyProvidersStr] = append(ep[keyProvidersStr], []byte("Enabled"))
}
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithKeyProvider returns a CryptoConfig to decrypt with configured keyprovider parameters
func DecryptWithKeyProvider(keyProviders [][]byte) (CryptoConfig, error) {
dp := make(map[string][][]byte)
ep := map[string][][]byte{}
for _, keyProvider := range keyProviders {
keyProvidersStr := string(keyProvider)
idx := strings.Index(keyProvidersStr, ":")
if idx > 0 {
dp[keyProvidersStr[:idx]] = append(dp[keyProvidersStr[:idx]], []byte(keyProvidersStr[idx+1:]))
} else {
dp[keyProvidersStr] = append(dp[keyProvidersStr], []byte("Enabled"))
}
}
dc := DecryptConfig{
Parameters: dp,
}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithPrivKeys returns a CryptoConfig to decrypt with configured private keys
func DecryptWithPrivKeys(privKeys [][]byte, privKeysPasswords [][]byte) (CryptoConfig, error) {
if len(privKeys) != len(privKeysPasswords) {
return CryptoConfig{}, errors.New("Length of privKeys should match length of privKeysPasswords")
}
dc := DecryptConfig{
Parameters: map[string][][]byte{
"privkeys": privKeys,
"privkeys-passwords": privKeysPasswords,
},
}
ep := map[string][][]byte{}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithX509s returns a CryptoConfig to decrypt with configured x509 certs
func DecryptWithX509s(x509s [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{
Parameters: map[string][][]byte{
"x509s": x509s,
},
}
ep := map[string][][]byte{}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithGpgPrivKeys returns a CryptoConfig to decrypt with configured gpg private keys
func DecryptWithGpgPrivKeys(gpgPrivKeys, gpgPrivKeysPwds [][]byte) (CryptoConfig, error) {
dc := DecryptConfig{
Parameters: map[string][][]byte{
"gpg-privatekeys": gpgPrivKeys,
"gpg-privatekeys-passwords": gpgPrivKeysPwds,
},
}
ep := map[string][][]byte{}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}
// DecryptWithPkcs11Yaml returns a CryptoConfig to decrypt with pkcs11 YAML formatted key files
func DecryptWithPkcs11Yaml(pkcs11Config *pkcs11.Pkcs11Config, pkcs11Yamls [][]byte) (CryptoConfig, error) {
p11confYaml, err := yaml.Marshal(pkcs11Config)
if err != nil {
return CryptoConfig{}, fmt.Errorf("Could not marshal Pkcs11Config to Yaml: %w", err)
}
dc := DecryptConfig{
Parameters: map[string][][]byte{
"pkcs11-yamls": pkcs11Yamls,
"pkcs11-config": {p11confYaml},
},
}
ep := map[string][][]byte{}
return CryptoConfig{
EncryptConfig: &EncryptConfig{
Parameters: ep,
DecryptConfig: dc,
},
DecryptConfig: &dc,
}, nil
}

View File

@ -0,0 +1,80 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 config
import (
"encoding/json"
"fmt"
"os"
)
// Command describes the structure of command, it consist of path and args, where path defines the location of
// binary executable and args are passed on to the binary executable
type Command struct {
Path string `json:"path,omitempty"`
Args []string `json:"args,omitempty"`
}
// KeyProviderAttrs describes the structure of key provider, it defines the way of invocation to key provider
type KeyProviderAttrs struct {
Command *Command `json:"cmd,omitempty"`
Grpc string `json:"grpc,omitempty"`
}
// OcicryptConfig represents the format of an ocicrypt_provider.conf config file
type OcicryptConfig struct {
KeyProviderConfig map[string]KeyProviderAttrs `json:"key-providers"`
}
const ENVVARNAME = "OCICRYPT_KEYPROVIDER_CONFIG"
// parseConfigFile parses a configuration file; it is not an error if the configuration file does
// not exist, so no error is returned.
func parseConfigFile(filename string) (*OcicryptConfig, error) {
// a non-existent config file is not an error
_, err := os.Stat(filename)
if os.IsNotExist(err) {
return nil, nil
}
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
ic := &OcicryptConfig{}
err = json.Unmarshal(data, ic)
return ic, err
}
// getConfiguration tries to read the configuration file at the following locations
// ${OCICRYPT_KEYPROVIDER_CONFIG} == "/etc/ocicrypt_keyprovider.yaml"
// If no configuration file could be found or read a null pointer is returned
func GetConfiguration() (*OcicryptConfig, error) {
var ic *OcicryptConfig
var err error
filename := os.Getenv(ENVVARNAME)
if len(filename) > 0 {
ic, err = parseConfigFile(filename)
if err != nil {
return nil, fmt.Errorf("Error while parsing keyprovider config file: %w", err)
}
} else {
return nil, nil
}
return ic, nil
}

View File

@ -0,0 +1,134 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs11
import (
"fmt"
pkcs11uri "github.com/stefanberger/go-pkcs11uri"
"gopkg.in/yaml.v3"
)
// Pkcs11KeyFile describes the format of the pkcs11 (private) key file.
// It also carries pkcs11 module related environment variables that are transferred to the
// Pkcs11URI object and activated when the pkcs11 module is used.
type Pkcs11KeyFile struct {
Pkcs11 struct {
Uri string `yaml:"uri"`
} `yaml:"pkcs11"`
Module struct {
Env map[string]string `yaml:"env,omitempty"`
} `yaml:"module"`
}
// Pkcs11KeyFileObject is a representation of the Pkcs11KeyFile with the pkcs11 URI as an object
type Pkcs11KeyFileObject struct {
Uri *pkcs11uri.Pkcs11URI
}
// ParsePkcs11Uri parses a pkcs11 URI
func ParsePkcs11Uri(uri string) (*pkcs11uri.Pkcs11URI, error) {
p11uri := pkcs11uri.New()
err := p11uri.Parse(uri)
if err != nil {
return nil, fmt.Errorf("Could not parse Pkcs11URI from file: %w", err)
}
return p11uri, err
}
// ParsePkcs11KeyFile parses a pkcs11 key file holding a pkcs11 URI describing a private key.
// The file has the following yaml format:
// pkcs11:
// - uri : <pkcs11 uri>
// An error is returned if the pkcs11 URI is malformed
func ParsePkcs11KeyFile(yamlstr []byte) (*Pkcs11KeyFileObject, error) {
p11keyfile := Pkcs11KeyFile{}
err := yaml.Unmarshal(yamlstr, &p11keyfile)
if err != nil {
return nil, fmt.Errorf("Could not unmarshal pkcs11 keyfile: %w", err)
}
p11uri, err := ParsePkcs11Uri(p11keyfile.Pkcs11.Uri)
if err != nil {
return nil, err
}
p11uri.SetEnvMap(p11keyfile.Module.Env)
return &Pkcs11KeyFileObject{Uri: p11uri}, err
}
// IsPkcs11PrivateKey checks whether the given YAML represents a Pkcs11 private key
func IsPkcs11PrivateKey(yamlstr []byte) bool {
_, err := ParsePkcs11KeyFile(yamlstr)
return err == nil
}
// IsPkcs11PublicKey checks whether the given YAML represents a Pkcs11 public key
func IsPkcs11PublicKey(yamlstr []byte) bool {
_, err := ParsePkcs11KeyFile(yamlstr)
return err == nil
}
// Pkcs11Config describes the layout of a pkcs11 config file
// The file has the following yaml format:
// module-directories:
// - /usr/lib64/pkcs11/
// allowd-module-paths
// - /usr/lib64/pkcs11/libsofthsm2.so
type Pkcs11Config struct {
ModuleDirectories []string `yaml:"module-directories"`
AllowedModulePaths []string `yaml:"allowed-module-paths"`
}
// GetDefaultModuleDirectories returns module directories covering
// a variety of Linux distros
func GetDefaultModuleDirectories() []string {
dirs := []string{
"/usr/lib64/pkcs11/", // Fedora,RHEL,openSUSE
"/usr/lib/pkcs11/", // Fedora,ArchLinux
"/usr/local/lib/pkcs11/",
"/usr/lib/softhsm/", // Debian,Ubuntu
}
// Debian directory: /usr/lib/(x86_64|aarch64|arm|powerpc64le|riscv64|s390x)-linux-gnu/
hosttype, ostype, q := getHostAndOsType()
if len(hosttype) > 0 {
dir := fmt.Sprintf("/usr/lib/%s-%s-%s/", hosttype, ostype, q)
dirs = append(dirs, dir)
}
return dirs
}
// GetDefaultModuleDirectoresFormatted returns the default module directories formatted for YAML
func GetDefaultModuleDirectoriesYaml(indent string) string {
res := ""
for _, dir := range GetDefaultModuleDirectories() {
res += indent + "- " + dir + "\n"
}
return res
}
// ParsePkcs11ConfigFile parses a pkcs11 config file hat influences the module search behavior
// as well as the set of modules that users are allowed to use
func ParsePkcs11ConfigFile(yamlstr []byte) (*Pkcs11Config, error) {
p11conf := Pkcs11Config{}
err := yaml.Unmarshal(yamlstr, &p11conf)
if err != nil {
return &p11conf, fmt.Errorf("Could not parse Pkcs11Config: %w", err)
}
return &p11conf, nil
}

View File

@ -0,0 +1,485 @@
//go:build cgo
// +build cgo
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs11
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"hash"
"net/url"
"os"
"strconv"
"strings"
"github.com/miekg/pkcs11"
pkcs11uri "github.com/stefanberger/go-pkcs11uri"
)
var (
// OAEPLabel defines the label we use for OAEP encryption; this cannot be changed
OAEPLabel = []byte("")
// OAEPSha1Params describes the OAEP parameters with sha1 hash algorithm; needed by SoftHSM
OAEPSha1Params = &pkcs11.OAEPParams{
HashAlg: pkcs11.CKM_SHA_1,
MGF: pkcs11.CKG_MGF1_SHA1,
SourceType: pkcs11.CKZ_DATA_SPECIFIED,
SourceData: OAEPLabel,
}
// OAEPSha256Params describes the OAEP parameters with sha256 hash algorithm
OAEPSha256Params = &pkcs11.OAEPParams{
HashAlg: pkcs11.CKM_SHA256,
MGF: pkcs11.CKG_MGF1_SHA256,
SourceType: pkcs11.CKZ_DATA_SPECIFIED,
SourceData: OAEPLabel,
}
)
// rsaPublicEncryptOAEP encrypts the given plaintext with the given *rsa.PublicKey; the
// environment variable OCICRYPT_OAEP_HASHALG can be set to 'sha1' to force usage of sha1 for OAEP (SoftHSM).
// This function is needed by clients who are using a public key file for pkcs11 encryption
func rsaPublicEncryptOAEP(pubKey *rsa.PublicKey, plaintext []byte) ([]byte, string, error) {
var (
hashfunc hash.Hash
hashalg string
)
oaephash := os.Getenv("OCICRYPT_OAEP_HASHALG")
// The default is sha256 (previously was sha1)
switch strings.ToLower(oaephash) {
case "sha1":
hashfunc = sha1.New()
hashalg = "sha1"
case "sha256", "":
hashfunc = sha256.New()
hashalg = "sha256"
default:
return nil, "", fmt.Errorf("Unsupported OAEP hash '%s'", oaephash)
}
ciphertext, err := rsa.EncryptOAEP(hashfunc, rand.Reader, pubKey, plaintext, OAEPLabel)
if err != nil {
return nil, "", fmt.Errorf("rss.EncryptOAEP failed: %w", err)
}
return ciphertext, hashalg, nil
}
// pkcs11UriGetLoginParameters gets the parameters necessary for login from the Pkcs11URI
// PIN and module are mandatory; slot-id is optional and if not found -1 will be returned
// For a privateKeyOperation a PIN is required and if none is given, this function will return an error
func pkcs11UriGetLoginParameters(p11uri *pkcs11uri.Pkcs11URI, privateKeyOperation bool) (string, string, int64, error) {
var (
pin string
err error
)
if privateKeyOperation {
if !p11uri.HasPIN() {
return "", "", 0, errors.New("Missing PIN for private key operation")
}
}
// some devices require a PIN to find a *public* key object, others don't
pin, _ = p11uri.GetPIN()
module, err := p11uri.GetModule()
if err != nil {
return "", "", 0, fmt.Errorf("No module available in pkcs11 URI: %w", err)
}
slotid := int64(-1)
slot, ok := p11uri.GetPathAttribute("slot-id", false)
if ok {
slotid, err = strconv.ParseInt(slot, 10, 64)
if err != nil {
return "", "", 0, fmt.Errorf("slot-id is not a valid number: %w", err)
}
if slotid < 0 {
return "", "", 0, fmt.Errorf("slot-id is a negative number")
}
if uint64(slotid) > 0xffffffff {
return "", "", 0, fmt.Errorf("slot-id is larger than 32 bit")
}
}
return pin, module, slotid, nil
}
// pkcs11UriGetKeyIdAndLabel gets the key label by retrieving the value of the 'object' attribute
func pkcs11UriGetKeyIdAndLabel(p11uri *pkcs11uri.Pkcs11URI) (string, string, error) {
keyid, ok2 := p11uri.GetPathAttribute("id", false)
label, ok1 := p11uri.GetPathAttribute("object", false)
if !ok1 && !ok2 {
return "", "", errors.New("Neither 'id' nor 'object' attributes were found in pkcs11 URI")
}
return keyid, label, nil
}
// pkcs11OpenSession opens a session with a pkcs11 device at the given slot and logs in with the given PIN
func pkcs11OpenSession(p11ctx *pkcs11.Ctx, slotid uint, pin string) (session pkcs11.SessionHandle, err error) {
session, err = p11ctx.OpenSession(slotid, pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
if err != nil {
return 0, fmt.Errorf("OpenSession to slot %d failed: %w", slotid, err)
}
if len(pin) > 0 {
err = p11ctx.Login(session, pkcs11.CKU_USER, pin)
if err != nil {
_ = p11ctx.CloseSession(session)
return 0, fmt.Errorf("Could not login to device: %w", err)
}
}
return session, nil
}
// pkcs11UriLogin uses the given pkcs11 URI to select the pkcs11 module (shared library) and to get
// the PIN to use for login; if the URI contains a slot-id, the given slot-id will be used, otherwise
// one slot after the other will be attempted and the first one where login succeeds will be used
func pkcs11UriLogin(p11uri *pkcs11uri.Pkcs11URI, privateKeyOperation bool) (ctx *pkcs11.Ctx, session pkcs11.SessionHandle, err error) {
pin, module, slotid, err := pkcs11UriGetLoginParameters(p11uri, privateKeyOperation)
if err != nil {
return nil, 0, err
}
p11ctx := pkcs11.New(module)
if p11ctx == nil {
return nil, 0, errors.New("Please check module path, input is: " + module)
}
err = p11ctx.Initialize()
if err != nil {
p11Err := err.(pkcs11.Error)
if p11Err != pkcs11.CKR_CRYPTOKI_ALREADY_INITIALIZED {
return nil, 0, fmt.Errorf("Initialize failed: %w", err)
}
}
if slotid >= 0 {
session, err := pkcs11OpenSession(p11ctx, uint(slotid), pin)
return p11ctx, session, err
}
slots, err := p11ctx.GetSlotList(true)
if err != nil {
return nil, 0, fmt.Errorf("GetSlotList failed: %w", err)
}
tokenlabel, ok := p11uri.GetPathAttribute("token", false)
if !ok {
return nil, 0, errors.New("Missing 'token' attribute since 'slot-id' was not given")
}
for _, slot := range slots {
ti, err := p11ctx.GetTokenInfo(slot)
if err != nil || ti.Label != tokenlabel {
continue
}
session, err = pkcs11OpenSession(p11ctx, slot, pin)
if err == nil {
return p11ctx, session, err
}
}
if len(pin) > 0 {
return nil, 0, errors.New("Could not create session to any slot and/or log in")
}
return nil, 0, errors.New("Could not create session to any slot")
}
func pkcs11Logout(ctx *pkcs11.Ctx, session pkcs11.SessionHandle) {
_ = ctx.Logout(session)
_ = ctx.CloseSession(session)
_ = ctx.Finalize()
ctx.Destroy()
}
// findObject finds an object of the given class with the given keyid and/or label
func findObject(p11ctx *pkcs11.Ctx, session pkcs11.SessionHandle, class uint, keyid, label string) (pkcs11.ObjectHandle, error) {
msg := ""
template := []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_CLASS, class),
}
if len(label) > 0 {
template = append(template, pkcs11.NewAttribute(pkcs11.CKA_LABEL, label))
msg = fmt.Sprintf("label '%s'", label)
}
if len(keyid) > 0 {
template = append(template, pkcs11.NewAttribute(pkcs11.CKA_ID, keyid))
if len(msg) > 0 {
msg += " and "
}
msg += url.PathEscape(keyid)
}
if err := p11ctx.FindObjectsInit(session, template); err != nil {
return 0, fmt.Errorf("FindObjectsInit failed: %w", err)
}
obj, _, err := p11ctx.FindObjects(session, 100)
if err != nil {
return 0, fmt.Errorf("FindObjects failed: %w", err)
}
if err := p11ctx.FindObjectsFinal(session); err != nil {
return 0, fmt.Errorf("FindObjectsFinal failed: %w", err)
}
if len(obj) > 1 {
return 0, fmt.Errorf("There are too many (=%d) keys with %s", len(obj), msg)
} else if len(obj) == 1 {
return obj[0], nil
}
return 0, fmt.Errorf("Could not find any object with %s", msg)
}
// publicEncryptOAEP uses a public key described by a pkcs11 URI to OAEP encrypt the given plaintext
func publicEncryptOAEP(pubKey *Pkcs11KeyFileObject, plaintext []byte) ([]byte, string, error) {
oldenv, err := setEnvVars(pubKey.Uri.GetEnvMap())
if err != nil {
return nil, "", err
}
defer restoreEnv(oldenv)
p11ctx, session, err := pkcs11UriLogin(pubKey.Uri, false)
if err != nil {
return nil, "", err
}
defer pkcs11Logout(p11ctx, session)
keyid, label, err := pkcs11UriGetKeyIdAndLabel(pubKey.Uri)
if err != nil {
return nil, "", err
}
p11PubKey, err := findObject(p11ctx, session, pkcs11.CKO_PUBLIC_KEY, keyid, label)
if err != nil {
return nil, "", err
}
var hashalg string
var oaep *pkcs11.OAEPParams
oaephash := os.Getenv("OCICRYPT_OAEP_HASHALG")
// The default is sha256 (previously was sha1)
switch strings.ToLower(oaephash) {
case "sha1":
oaep = OAEPSha1Params
hashalg = "sha1"
case "sha256", "":
oaep = OAEPSha256Params
hashalg = "sha256"
default:
return nil, "", fmt.Errorf("Unsupported OAEP hash '%s'", oaephash)
}
err = p11ctx.EncryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP, oaep)}, p11PubKey)
if err != nil {
return nil, "", fmt.Errorf("EncryptInit error: %w", err)
}
ciphertext, err := p11ctx.Encrypt(session, plaintext)
if err != nil {
return nil, "", fmt.Errorf("Encrypt failed: %w", err)
}
return ciphertext, hashalg, nil
}
// privateDecryptOAEP uses a pkcs11 URI describing a private key to OAEP decrypt a ciphertext
func privateDecryptOAEP(privKeyObj *Pkcs11KeyFileObject, ciphertext []byte, hashalg string) ([]byte, error) {
oldenv, err := setEnvVars(privKeyObj.Uri.GetEnvMap())
if err != nil {
return nil, err
}
defer restoreEnv(oldenv)
p11ctx, session, err := pkcs11UriLogin(privKeyObj.Uri, true)
if err != nil {
return nil, err
}
defer pkcs11Logout(p11ctx, session)
keyid, label, err := pkcs11UriGetKeyIdAndLabel(privKeyObj.Uri)
if err != nil {
return nil, err
}
p11PrivKey, err := findObject(p11ctx, session, pkcs11.CKO_PRIVATE_KEY, keyid, label)
if err != nil {
return nil, err
}
var oaep *pkcs11.OAEPParams
// An empty string from the Hash in the JSON historically defaults to sha1.
switch hashalg {
case "sha1", "":
oaep = OAEPSha1Params
case "sha256":
oaep = OAEPSha256Params
default:
return nil, fmt.Errorf("Unsupported hash algorithm '%s' for decryption", hashalg)
}
err = p11ctx.DecryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_RSA_PKCS_OAEP, oaep)}, p11PrivKey)
if err != nil {
return nil, fmt.Errorf("DecryptInit failed: %w", err)
}
plaintext, err := p11ctx.Decrypt(session, ciphertext)
if err != nil {
return nil, fmt.Errorf("Decrypt failed: %w", err)
}
return plaintext, err
}
//
// The following part deals with the JSON formatted message for multiple pkcs11 recipients
//
// Pkcs11Blob holds the encrypted blobs for all recipients; this is what we will put into the image's annotations
type Pkcs11Blob struct {
Version uint `json:"version"`
Recipients []Pkcs11Recipient `json:"recipients"`
}
// Pkcs11Recipient holds the b64-encoded and encrypted blob for a particular recipient
type Pkcs11Recipient struct {
Version uint `json:"version"`
Blob string `json:"blob"`
Hash string `json:"hash,omitempty"`
}
// EncryptMultiple encrypts for one or multiple pkcs11 devices; the public keys passed to this function
// may either be *rsa.PublicKey or *pkcs11uri.Pkcs11URI; the returned byte array is a JSON string of the
// following format:
// {
// recipients: [ // recipient list
// {
// "version": 0,
// "blob": <base64 encoded RSA OAEP encrypted blob>,
// "hash": <hash used for OAEP other than 'sha256'>
// } ,
// {
// "version": 0,
// "blob": <base64 encoded RSA OAEP encrypted blob>,
// "hash": <hash used for OAEP other than 'sha256'>
// } ,
// [...]
// ]
// }
func EncryptMultiple(pubKeys []interface{}, data []byte) ([]byte, error) {
var (
ciphertext []byte
err error
pkcs11blob Pkcs11Blob = Pkcs11Blob{Version: 0}
hashalg string
)
for _, pubKey := range pubKeys {
switch pkey := pubKey.(type) {
case *rsa.PublicKey:
ciphertext, hashalg, err = rsaPublicEncryptOAEP(pkey, data)
case *Pkcs11KeyFileObject:
ciphertext, hashalg, err = publicEncryptOAEP(pkey, data)
default:
err = fmt.Errorf("Unsupported key object type for pkcs11 public key")
}
if err != nil {
return nil, err
}
recipient := Pkcs11Recipient{
Version: 0,
Blob: base64.StdEncoding.EncodeToString(ciphertext),
Hash: hashalg,
}
pkcs11blob.Recipients = append(pkcs11blob.Recipients, recipient)
}
return json.Marshal(&pkcs11blob)
}
// Decrypt tries to decrypt one of the recipients' blobs using a pkcs11 private key.
// The input pkcs11blobstr is a string with the following format:
// {
// recipients: [ // recipient list
// {
// "version": 0,
// "blob": <base64 encoded RSA OAEP encrypted blob>,
// "hash": <hash used for OAEP other than 'sha1'>
// } ,
// {
// "version": 0,
// "blob": <base64 encoded RSA OAEP encrypted blob>,
// "hash": <hash used for OAEP other than 'sha1'>
// } ,
// [...]
// }
// Note: More recent versions of this code explicitly write 'sha1'
// while older versions left it empty in case of 'sha1'.
func Decrypt(privKeyObjs []*Pkcs11KeyFileObject, pkcs11blobstr []byte) ([]byte, error) {
pkcs11blob := Pkcs11Blob{}
err := json.Unmarshal(pkcs11blobstr, &pkcs11blob)
if err != nil {
return nil, fmt.Errorf("Could not parse Pkcs11Blob: %w", err)
}
switch pkcs11blob.Version {
case 0:
// latest supported version
default:
return nil, fmt.Errorf("found Pkcs11Blob with version %d but maximum supported version is 0", pkcs11blob.Version)
}
// since we do trial and error, collect all encountered errors
errs := ""
for _, recipient := range pkcs11blob.Recipients {
switch recipient.Version {
case 0:
// last supported version
default:
return nil, fmt.Errorf("found Pkcs11Recipient with version %d but maximum supported version is 0", recipient.Version)
}
ciphertext, err := base64.StdEncoding.DecodeString(recipient.Blob)
if err != nil || len(ciphertext) == 0 {
// This should never happen... we skip over decoding issues
errs += fmt.Sprintf("Base64 decoding failed: %s\n", err)
continue
}
// try all keys until one works
for _, privKeyObj := range privKeyObjs {
plaintext, err := privateDecryptOAEP(privKeyObj, ciphertext, recipient.Hash)
if err == nil {
return plaintext, nil
}
if uri, err2 := privKeyObj.Uri.Format(); err2 == nil {
errs += fmt.Sprintf("%s : %s\n", uri, err)
} else {
errs += fmt.Sprintf("%s\n", err)
}
}
}
return nil, fmt.Errorf("Could not find a pkcs11 key for decryption:\n%s", errs)
}

View File

@ -0,0 +1,30 @@
//go:build !cgo
// +build !cgo
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs11
import "fmt"
func EncryptMultiple(pubKeys []interface{}, data []byte) ([]byte, error) {
return nil, fmt.Errorf("ocicrypt pkcs11 not supported on this build")
}
func Decrypt(privKeyObjs []*Pkcs11KeyFileObject, pkcs11blobstr []byte) ([]byte, error) {
return nil, fmt.Errorf("ocicrypt pkcs11 not supported on this build")
}

View File

@ -0,0 +1,115 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs11
import (
"fmt"
"os"
"runtime"
"strings"
"sync"
)
var (
envLock sync.Mutex
)
// setEnvVars sets the environment variables given in the map and locks the environment from
// modification with the same function; if successful, you *must* call restoreEnv with the return
// value from this function
func setEnvVars(env map[string]string) ([]string, error) {
envLock.Lock()
if len(env) == 0 {
return nil, nil
}
oldenv := os.Environ()
for k, v := range env {
err := os.Setenv(k, v)
if err != nil {
restoreEnv(oldenv)
return nil, fmt.Errorf("Could not set environment variable '%s' to '%s': %w", k, v, err)
}
}
return oldenv, nil
}
func arrayToMap(elements []string) map[string]string {
o := make(map[string]string)
for _, element := range elements {
p := strings.SplitN(element, "=", 2)
if len(p) == 2 {
o[p[0]] = p[1]
}
}
return o
}
// restoreEnv restores the environment to be exactly as given in the array of strings
// and unlocks the lock
func restoreEnv(envs []string) {
if envs != nil && len(envs) >= 0 {
target := arrayToMap(envs)
curr := arrayToMap(os.Environ())
for nc, vc := range curr {
vt, ok := target[nc]
if !ok {
os.Unsetenv(nc)
} else if vc == vt {
delete(target, nc)
}
}
for nt, vt := range target {
os.Setenv(nt, vt)
}
}
envLock.Unlock()
}
func getHostAndOsType() (string, string, string) {
ht := ""
ot := ""
st := ""
switch runtime.GOOS {
case "linux":
ot = "linux"
st = "gnu"
switch runtime.GOARCH {
case "arm":
ht = "arm"
case "arm64":
ht = "aarch64"
case "amd64":
ht = "x86_64"
case "ppc64le":
ht = "powerpc64le"
case "riscv64":
ht = "riscv64"
case "s390x":
ht = "s390x"
}
}
return ht, ot, st
}

356
vendor/github.com/containers/ocicrypt/encryption.go generated vendored Normal file
View File

@ -0,0 +1,356 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 ocicrypt
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"strings"
"github.com/containers/ocicrypt/blockcipher"
"github.com/containers/ocicrypt/config"
keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/keywrap/jwe"
"github.com/containers/ocicrypt/keywrap/keyprovider"
"github.com/containers/ocicrypt/keywrap/pgp"
"github.com/containers/ocicrypt/keywrap/pkcs11"
"github.com/containers/ocicrypt/keywrap/pkcs7"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
log "github.com/sirupsen/logrus"
)
// EncryptLayerFinalizer is a finalizer run to return the annotations to set for
// the encrypted layer
type EncryptLayerFinalizer func() (map[string]string, error)
func init() {
keyWrappers = make(map[string]keywrap.KeyWrapper)
keyWrapperAnnotations = make(map[string]string)
RegisterKeyWrapper("pgp", pgp.NewKeyWrapper())
RegisterKeyWrapper("jwe", jwe.NewKeyWrapper())
RegisterKeyWrapper("pkcs7", pkcs7.NewKeyWrapper())
RegisterKeyWrapper("pkcs11", pkcs11.NewKeyWrapper())
ic, err := keyproviderconfig.GetConfiguration()
if err != nil {
log.Error(err)
} else if ic != nil {
for provider, attrs := range ic.KeyProviderConfig {
RegisterKeyWrapper("provider."+provider, keyprovider.NewKeyWrapper(provider, attrs))
}
}
}
var keyWrappers map[string]keywrap.KeyWrapper
var keyWrapperAnnotations map[string]string
// RegisterKeyWrapper allows to register key wrappers by their encryption scheme
func RegisterKeyWrapper(scheme string, iface keywrap.KeyWrapper) {
keyWrappers[scheme] = iface
keyWrapperAnnotations[iface.GetAnnotationID()] = scheme
}
// GetKeyWrapper looks up the encryptor interface given an encryption scheme (gpg, jwe)
func GetKeyWrapper(scheme string) keywrap.KeyWrapper {
return keyWrappers[scheme]
}
// GetWrappedKeysMap returns a map of wrappedKeys as values in a
// map with the encryption scheme(s) as the key(s)
func GetWrappedKeysMap(desc ocispec.Descriptor) map[string]string {
wrappedKeysMap := make(map[string]string)
for annotationsID, scheme := range keyWrapperAnnotations {
if annotation, ok := desc.Annotations[annotationsID]; ok {
wrappedKeysMap[scheme] = annotation
}
}
return wrappedKeysMap
}
// EncryptLayer encrypts the layer by running one encryptor after the other
func EncryptLayer(ec *config.EncryptConfig, encOrPlainLayerReader io.Reader, desc ocispec.Descriptor) (io.Reader, EncryptLayerFinalizer, error) {
var (
encLayerReader io.Reader
err error
encrypted bool
bcFin blockcipher.Finalizer
privOptsData []byte
pubOptsData []byte
)
if ec == nil {
return nil, nil, errors.New("EncryptConfig must not be nil")
}
for annotationsID := range keyWrapperAnnotations {
annotation := desc.Annotations[annotationsID]
if annotation != "" {
privOptsData, err = decryptLayerKeyOptsData(&ec.DecryptConfig, desc)
if err != nil {
return nil, nil, err
}
pubOptsData, err = getLayerPubOpts(desc)
if err != nil {
return nil, nil, err
}
// already encrypted!
encrypted = true
}
}
if !encrypted {
encLayerReader, bcFin, err = commonEncryptLayer(encOrPlainLayerReader, desc.Digest, blockcipher.AES256CTR)
if err != nil {
return nil, nil, err
}
}
encLayerFinalizer := func() (map[string]string, error) {
// If layer was already encrypted, bcFin should be nil, use existing optsData
if bcFin != nil {
opts, err := bcFin()
if err != nil {
return nil, err
}
privOptsData, err = json.Marshal(opts.Private)
if err != nil {
return nil, fmt.Errorf("could not JSON marshal opts: %w", err)
}
pubOptsData, err = json.Marshal(opts.Public)
if err != nil {
return nil, fmt.Errorf("could not JSON marshal opts: %w", err)
}
}
newAnnotations := make(map[string]string)
keysWrapped := false
if len(keyWrapperAnnotations) == 0 {
return nil, errors.New("missing Annotations needed for decryption")
}
for annotationsID, scheme := range keyWrapperAnnotations {
b64Annotations := desc.Annotations[annotationsID]
keywrapper := GetKeyWrapper(scheme)
b64Annotations, err = preWrapKeys(keywrapper, ec, b64Annotations, privOptsData)
if err != nil {
return nil, err
}
if b64Annotations != "" {
keysWrapped = true
newAnnotations[annotationsID] = b64Annotations
}
}
if !keysWrapped {
return nil, errors.New("no wrapped keys produced by encryption")
}
newAnnotations["org.opencontainers.image.enc.pubopts"] = base64.StdEncoding.EncodeToString(pubOptsData)
if len(newAnnotations) == 0 {
return nil, errors.New("no encryptor found to handle encryption")
}
return newAnnotations, err
}
// if nothing was encrypted, we just return encLayer = nil
return encLayerReader, encLayerFinalizer, err
}
// preWrapKeys calls WrapKeys and handles the base64 encoding and concatenation of the
// annotation data
func preWrapKeys(keywrapper keywrap.KeyWrapper, ec *config.EncryptConfig, b64Annotations string, optsData []byte) (string, error) {
newAnnotation, err := keywrapper.WrapKeys(ec, optsData)
if err != nil || len(newAnnotation) == 0 {
return b64Annotations, err
}
b64newAnnotation := base64.StdEncoding.EncodeToString(newAnnotation)
if b64Annotations == "" {
return b64newAnnotation, nil
}
return b64Annotations + "," + b64newAnnotation, nil
}
// DecryptLayer decrypts a layer trying one keywrap.KeyWrapper after the other to see whether it
// can apply the provided private key
// If unwrapOnly is set we will only try to decrypt the layer encryption key and return
func DecryptLayer(dc *config.DecryptConfig, encLayerReader io.Reader, desc ocispec.Descriptor, unwrapOnly bool) (io.Reader, digest.Digest, error) {
if dc == nil {
return nil, "", errors.New("DecryptConfig must not be nil")
}
privOptsData, err := decryptLayerKeyOptsData(dc, desc)
if err != nil || unwrapOnly {
return nil, "", err
}
var pubOptsData []byte
pubOptsData, err = getLayerPubOpts(desc)
if err != nil {
return nil, "", err
}
return commonDecryptLayer(encLayerReader, privOptsData, pubOptsData)
}
func decryptLayerKeyOptsData(dc *config.DecryptConfig, desc ocispec.Descriptor) ([]byte, error) {
privKeyGiven := false
errs := ""
if len(keyWrapperAnnotations) == 0 {
return nil, errors.New("missing Annotations needed for decryption")
}
for annotationsID, scheme := range keyWrapperAnnotations {
b64Annotation := desc.Annotations[annotationsID]
if b64Annotation != "" {
keywrapper := GetKeyWrapper(scheme)
if keywrapper.NoPossibleKeys(dc.Parameters) {
continue
}
if len(keywrapper.GetPrivateKeys(dc.Parameters)) > 0 {
privKeyGiven = true
}
optsData, err := preUnwrapKey(keywrapper, dc, b64Annotation)
if err != nil {
// try next keywrap.KeyWrapper
errs += fmt.Sprintf("%s\n", err)
continue
}
if optsData == nil {
// try next keywrap.KeyWrapper
continue
}
return optsData, nil
}
}
if !privKeyGiven {
return nil, fmt.Errorf("missing private key needed for decryption:\n%s", errs)
}
return nil, fmt.Errorf("no suitable key unwrapper found or none of the private keys could be used for decryption:\n%s", errs)
}
func getLayerPubOpts(desc ocispec.Descriptor) ([]byte, error) {
pubOptsString := desc.Annotations["org.opencontainers.image.enc.pubopts"]
if pubOptsString == "" {
return json.Marshal(blockcipher.PublicLayerBlockCipherOptions{})
}
return base64.StdEncoding.DecodeString(pubOptsString)
}
// preUnwrapKey decodes the comma separated base64 strings and calls the Unwrap function
// of the given keywrapper with it and returns the result in case the Unwrap functions
// does not return an error. If all attempts fail, an error is returned.
func preUnwrapKey(keywrapper keywrap.KeyWrapper, dc *config.DecryptConfig, b64Annotations string) ([]byte, error) {
if b64Annotations == "" {
return nil, nil
}
errs := ""
for _, b64Annotation := range strings.Split(b64Annotations, ",") {
annotation, err := base64.StdEncoding.DecodeString(b64Annotation)
if err != nil {
return nil, errors.New("could not base64 decode the annotation")
}
optsData, err := keywrapper.UnwrapKey(dc, annotation)
if err != nil {
errs += fmt.Sprintf("- %s\n", err)
continue
}
return optsData, nil
}
return nil, fmt.Errorf("no suitable key found for decrypting layer key:\n%s", errs)
}
// commonEncryptLayer is a function to encrypt the plain layer using a new random
// symmetric key and return the LayerBlockCipherHandler's JSON in string form for
// later use during decryption
func commonEncryptLayer(plainLayerReader io.Reader, d digest.Digest, typ blockcipher.LayerCipherType) (io.Reader, blockcipher.Finalizer, error) {
lbch, err := blockcipher.NewLayerBlockCipherHandler()
if err != nil {
return nil, nil, err
}
encLayerReader, bcFin, err := lbch.Encrypt(plainLayerReader, typ)
if err != nil {
return nil, nil, err
}
newBcFin := func() (blockcipher.LayerBlockCipherOptions, error) {
lbco, err := bcFin()
if err != nil {
return blockcipher.LayerBlockCipherOptions{}, err
}
lbco.Private.Digest = d
return lbco, nil
}
return encLayerReader, newBcFin, err
}
// commonDecryptLayer decrypts an encrypted layer previously encrypted with commonEncryptLayer
// by passing along the optsData
func commonDecryptLayer(encLayerReader io.Reader, privOptsData []byte, pubOptsData []byte) (io.Reader, digest.Digest, error) {
privOpts := blockcipher.PrivateLayerBlockCipherOptions{}
err := json.Unmarshal(privOptsData, &privOpts)
if err != nil {
return nil, "", fmt.Errorf("could not JSON unmarshal privOptsData: %w", err)
}
lbch, err := blockcipher.NewLayerBlockCipherHandler()
if err != nil {
return nil, "", err
}
pubOpts := blockcipher.PublicLayerBlockCipherOptions{}
if len(pubOptsData) > 0 {
err := json.Unmarshal(pubOptsData, &pubOpts)
if err != nil {
return nil, "", fmt.Errorf("could not JSON unmarshal pubOptsData: %w", err)
}
}
opts := blockcipher.LayerBlockCipherOptions{
Private: privOpts,
Public: pubOpts,
}
plainLayerReader, opts, err := lbch.Decrypt(encLayerReader, opts)
if err != nil {
return nil, "", err
}
return plainLayerReader, opts.Private.Digest, nil
}
// FilterOutAnnotations filters out the annotations belonging to the image encryption 'namespace'
// and returns a map with those taken out
func FilterOutAnnotations(annotations map[string]string) map[string]string {
a := make(map[string]string)
if len(annotations) > 0 {
for k, v := range annotations {
if strings.HasPrefix(k, "org.opencontainers.image.enc.") {
continue
}
a[k] = v
}
}
return a
}

432
vendor/github.com/containers/ocicrypt/gpg.go generated vendored Normal file
View File

@ -0,0 +1,432 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 ocicrypt
import (
"errors"
"fmt"
"io"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"sync"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"golang.org/x/term"
)
// GPGVersion enum representing the GPG client version to use.
type GPGVersion int
const (
// GPGv2 signifies gpgv2+
GPGv2 GPGVersion = iota
// GPGv1 signifies gpgv1+
GPGv1
// GPGVersionUndetermined signifies gpg client version undetermined
GPGVersionUndetermined
)
// GPGClient defines an interface for wrapping the gpg command line tools
type GPGClient interface {
// ReadGPGPubRingFile gets the byte sequence of the gpg public keyring
ReadGPGPubRingFile() ([]byte, error)
// GetGPGPrivateKey gets the private key bytes of a keyid given a passphrase
GetGPGPrivateKey(keyid uint64, passphrase string) ([]byte, error)
// GetSecretKeyDetails gets the details of a secret key
GetSecretKeyDetails(keyid uint64) ([]byte, bool, error)
// GetKeyDetails gets the details of a public key
GetKeyDetails(keyid uint64) ([]byte, bool, error)
// ResolveRecipients resolves PGP key ids to user names
ResolveRecipients([]string) []string
}
// gpgClient contains generic gpg client information
type gpgClient struct {
gpgHomeDir string
}
// gpgv2Client is a gpg2 client
type gpgv2Client struct {
gpgClient
}
// gpgv1Client is a gpg client
type gpgv1Client struct {
gpgClient
}
// GuessGPGVersion guesses the version of gpg. Defaults to gpg2 if exists, if
// not defaults to regular gpg.
func GuessGPGVersion() GPGVersion {
if err := exec.Command("gpg2", "--version").Run(); err == nil {
return GPGv2
} else if err := exec.Command("gpg", "--version").Run(); err == nil {
return GPGv1
} else {
return GPGVersionUndetermined
}
}
// NewGPGClient creates a new GPGClient object representing the given version
// and using the given home directory
func NewGPGClient(gpgVersion, gpgHomeDir string) (GPGClient, error) {
v := new(GPGVersion)
switch gpgVersion {
case "v1":
*v = GPGv1
case "v2":
*v = GPGv2
default:
v = nil
}
return newGPGClient(v, gpgHomeDir)
}
func newGPGClient(version *GPGVersion, homedir string) (GPGClient, error) {
var gpgVersion GPGVersion
if version != nil {
gpgVersion = *version
} else {
gpgVersion = GuessGPGVersion()
}
switch gpgVersion {
case GPGv1:
return &gpgv1Client{
gpgClient: gpgClient{gpgHomeDir: homedir},
}, nil
case GPGv2:
return &gpgv2Client{
gpgClient: gpgClient{gpgHomeDir: homedir},
}, nil
case GPGVersionUndetermined:
return nil, fmt.Errorf("unable to determine GPG version")
default:
return nil, fmt.Errorf("unhandled case: NewGPGClient")
}
}
// GetGPGPrivateKey gets the bytes of a specified keyid, supplying a passphrase
func (gc *gpgv2Client) GetGPGPrivateKey(keyid uint64, passphrase string) ([]byte, error) {
var args []string
if gc.gpgHomeDir != "" {
args = append(args, []string{"--homedir", gc.gpgHomeDir}...)
}
rfile, wfile, err := os.Pipe()
if err != nil {
return nil, fmt.Errorf("could not create pipe: %w", err)
}
defer func() {
rfile.Close()
wfile.Close()
}()
// fill pipe in background
go func(passphrase string) {
_, _ = wfile.Write([]byte(passphrase))
wfile.Close()
}(passphrase)
args = append(args, []string{"--pinentry-mode", "loopback", "--batch", "--passphrase-fd", fmt.Sprintf("%d", 3), "--export-secret-key", fmt.Sprintf("0x%x", keyid)}...)
cmd := exec.Command("gpg2", args...)
cmd.ExtraFiles = []*os.File{rfile}
return runGPGGetOutput(cmd)
}
// ReadGPGPubRingFile reads the GPG public key ring file
func (gc *gpgv2Client) ReadGPGPubRingFile() ([]byte, error) {
var args []string
if gc.gpgHomeDir != "" {
args = append(args, []string{"--homedir", gc.gpgHomeDir}...)
}
args = append(args, []string{"--batch", "--export"}...)
cmd := exec.Command("gpg2", args...)
return runGPGGetOutput(cmd)
}
func (gc *gpgv2Client) getKeyDetails(option string, keyid uint64) ([]byte, bool, error) {
var args []string
if gc.gpgHomeDir != "" {
args = []string{"--homedir", gc.gpgHomeDir}
}
args = append(args, option, fmt.Sprintf("0x%x", keyid))
cmd := exec.Command("gpg2", args...)
keydata, err := runGPGGetOutput(cmd)
return keydata, err == nil, err
}
// GetSecretKeyDetails retrieves the secret key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv2Client) GetSecretKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-K", keyid)
}
// GetKeyDetails retrieves the public key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv2Client) GetKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-k", keyid)
}
// ResolveRecipients converts PGP keyids to email addresses, if possible
func (gc *gpgv2Client) ResolveRecipients(recipients []string) []string {
return resolveRecipients(gc, recipients)
}
// GetGPGPrivateKey gets the bytes of a specified keyid, supplying a passphrase
func (gc *gpgv1Client) GetGPGPrivateKey(keyid uint64, _ string) ([]byte, error) {
var args []string
if gc.gpgHomeDir != "" {
args = append(args, []string{"--homedir", gc.gpgHomeDir}...)
}
args = append(args, []string{"--batch", "--export-secret-key", fmt.Sprintf("0x%x", keyid)}...)
cmd := exec.Command("gpg", args...)
return runGPGGetOutput(cmd)
}
// ReadGPGPubRingFile reads the GPG public key ring file
func (gc *gpgv1Client) ReadGPGPubRingFile() ([]byte, error) {
var args []string
if gc.gpgHomeDir != "" {
args = append(args, []string{"--homedir", gc.gpgHomeDir}...)
}
args = append(args, []string{"--batch", "--export"}...)
cmd := exec.Command("gpg", args...)
return runGPGGetOutput(cmd)
}
func (gc *gpgv1Client) getKeyDetails(option string, keyid uint64) ([]byte, bool, error) {
var args []string
if gc.gpgHomeDir != "" {
args = []string{"--homedir", gc.gpgHomeDir}
}
args = append(args, option, fmt.Sprintf("0x%x", keyid))
cmd := exec.Command("gpg", args...)
keydata, err := runGPGGetOutput(cmd)
return keydata, err == nil, err
}
// GetSecretKeyDetails retrieves the secret key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv1Client) GetSecretKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-K", keyid)
}
// GetKeyDetails retrieves the public key details of key with keyid.
// returns a byte array of the details and a bool if the key exists
func (gc *gpgv1Client) GetKeyDetails(keyid uint64) ([]byte, bool, error) {
return gc.getKeyDetails("-k", keyid)
}
// ResolveRecipients converts PGP keyids to email addresses, if possible
func (gc *gpgv1Client) ResolveRecipients(recipients []string) []string {
return resolveRecipients(gc, recipients)
}
// runGPGGetOutput runs the GPG commandline and returns stdout as byte array
// and any stderr in the error
func runGPGGetOutput(cmd *exec.Cmd) ([]byte, error) {
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, err := cmd.StderrPipe()
if err != nil {
return nil, err
}
if err := cmd.Start(); err != nil {
return nil, err
}
stdoutstr, err2 := io.ReadAll(stdout)
stderrstr, _ := io.ReadAll(stderr)
if err := cmd.Wait(); err != nil {
return nil, fmt.Errorf("error from %s: %s", cmd.Path, string(stderrstr))
}
return stdoutstr, err2
}
// resolveRecipients walks the list of recipients and attempts to convert
// all keyIds to email addresses; if something goes wrong during the
// conversion of a recipient, the original string is returned for that
// recpient
func resolveRecipients(gc GPGClient, recipients []string) []string {
var result []string
for _, recipient := range recipients {
keyID, err := strconv.ParseUint(recipient, 0, 64)
if err != nil {
result = append(result, recipient)
} else {
details, found, _ := gc.GetKeyDetails(keyID)
if !found {
result = append(result, recipient)
} else {
email := extractEmailFromDetails(details)
if email == "" {
result = append(result, recipient)
} else {
result = append(result, email)
}
}
}
}
return result
}
var (
onceRegexp sync.Once
emailPattern *regexp.Regexp
)
func extractEmailFromDetails(details []byte) string {
onceRegexp.Do(func() {
emailPattern = regexp.MustCompile(`uid\s+\[.*\]\s.*\s<(?P<email>.+)>`)
})
loc := emailPattern.FindSubmatchIndex(details)
if len(loc) == 0 {
return ""
}
return string(emailPattern.Expand(nil, []byte("$email"), details, loc))
}
// uint64ToStringArray converts an array of uint64's to an array of strings
// by applying a format string to each uint64
func uint64ToStringArray(format string, in []uint64) []string {
var ret []string
for _, v := range in {
ret = append(ret, fmt.Sprintf(format, v))
}
return ret
}
// GPGGetPrivateKey walks the list of layerInfos and tries to decrypt the
// wrapped symmetric keys. For this it determines whether a private key is
// in the GPGVault or on this system and prompts for the passwords for those
// that are available. If we do not find a private key on the system for
// getting to the symmetric key of a layer then an error is generated.
func GPGGetPrivateKey(descs []ocispec.Descriptor, gpgClient GPGClient, gpgVault GPGVault, mustFindKey bool) (gpgPrivKeys [][]byte, gpgPrivKeysPwds [][]byte, err error) {
// PrivateKeyData describes a private key
type PrivateKeyData struct {
KeyData []byte
KeyDataPassword []byte
}
var pkd PrivateKeyData
keyIDPasswordMap := make(map[uint64]PrivateKeyData)
for _, desc := range descs {
for scheme, b64pgpPackets := range GetWrappedKeysMap(desc) {
if scheme != "pgp" {
continue
}
keywrapper := GetKeyWrapper(scheme)
if keywrapper == nil {
return nil, nil, fmt.Errorf("could not get KeyWrapper for %s", scheme)
}
keyIds, err := keywrapper.GetKeyIdsFromPacket(b64pgpPackets)
if err != nil {
return nil, nil, err
}
found := false
for _, keyid := range keyIds {
// do we have this key? -- first check the vault
if gpgVault != nil {
_, keydata := gpgVault.GetGPGPrivateKey(keyid)
if len(keydata) > 0 {
pkd = PrivateKeyData{
KeyData: keydata,
KeyDataPassword: nil, // password not supported in this case
}
keyIDPasswordMap[keyid] = pkd
found = true
break
}
} else if gpgClient != nil {
// check the local system's gpg installation
keyinfo, haveKey, _ := gpgClient.GetSecretKeyDetails(keyid)
// this may fail if the key is not here; we ignore the error
if !haveKey {
// key not on this system
continue
}
_, found = keyIDPasswordMap[keyid]
if !found {
fmt.Printf("Passphrase required for Key id 0x%x: \n%v", keyid, string(keyinfo))
fmt.Printf("Enter passphrase for key with Id 0x%x: ", keyid)
password, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
if err != nil {
return nil, nil, err
}
keydata, err := gpgClient.GetGPGPrivateKey(keyid, string(password))
if err != nil {
return nil, nil, err
}
pkd = PrivateKeyData{
KeyData: keydata,
KeyDataPassword: password,
}
keyIDPasswordMap[keyid] = pkd
found = true
}
break
} else {
return nil, nil, errors.New("no GPGVault or GPGClient passed")
}
}
if !found && len(b64pgpPackets) > 0 && mustFindKey {
ids := uint64ToStringArray("0x%x", keyIds)
return nil, nil, fmt.Errorf("missing key for decryption of layer %x of %s. Need one of the following keys: %s", desc.Digest, desc.Platform, strings.Join(ids, ", "))
}
}
}
for _, pkd := range keyIDPasswordMap {
gpgPrivKeys = append(gpgPrivKeys, pkd.KeyData)
gpgPrivKeysPwds = append(gpgPrivKeysPwds, pkd.KeyDataPassword)
}
return gpgPrivKeys, gpgPrivKeysPwds, nil
}

100
vendor/github.com/containers/ocicrypt/gpgvault.go generated vendored Normal file
View File

@ -0,0 +1,100 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 ocicrypt
import (
"bytes"
"fmt"
"os"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
// GPGVault defines an interface for wrapping multiple secret key rings
type GPGVault interface {
// AddSecretKeyRingData adds a secret keyring via its raw byte array
AddSecretKeyRingData(gpgSecretKeyRingData []byte) error
// AddSecretKeyRingDataArray adds secret keyring via its raw byte arrays
AddSecretKeyRingDataArray(gpgSecretKeyRingDataArray [][]byte) error
// AddSecretKeyRingFiles adds secret keyrings given their filenames
AddSecretKeyRingFiles(filenames []string) error
// GetGPGPrivateKey gets the private key bytes of a keyid given a passphrase
GetGPGPrivateKey(keyid uint64) ([]openpgp.Key, []byte)
}
// gpgVault wraps an array of gpgSecretKeyRing
type gpgVault struct {
entityLists []openpgp.EntityList
keyDataList [][]byte // the raw data original passed in
}
// NewGPGVault creates an empty GPGVault
func NewGPGVault() GPGVault {
return &gpgVault{}
}
// AddSecretKeyRingData adds a secret keyring's to the gpgVault; the raw byte
// array read from the file must be passed and will be parsed by this function
func (g *gpgVault) AddSecretKeyRingData(gpgSecretKeyRingData []byte) error {
// read the private keys
r := bytes.NewReader(gpgSecretKeyRingData)
entityList, err := openpgp.ReadKeyRing(r)
if err != nil {
return fmt.Errorf("could not read keyring: %w", err)
}
g.entityLists = append(g.entityLists, entityList)
g.keyDataList = append(g.keyDataList, gpgSecretKeyRingData)
return nil
}
// AddSecretKeyRingDataArray adds secret keyrings to the gpgVault; the raw byte
// arrays read from files must be passed
func (g *gpgVault) AddSecretKeyRingDataArray(gpgSecretKeyRingDataArray [][]byte) error {
for _, gpgSecretKeyRingData := range gpgSecretKeyRingDataArray {
if err := g.AddSecretKeyRingData(gpgSecretKeyRingData); err != nil {
return err
}
}
return nil
}
// AddSecretKeyRingFiles adds the secret key rings given their filenames
func (g *gpgVault) AddSecretKeyRingFiles(filenames []string) error {
for _, filename := range filenames {
gpgSecretKeyRingData, err := os.ReadFile(filename)
if err != nil {
return err
}
err = g.AddSecretKeyRingData(gpgSecretKeyRingData)
if err != nil {
return err
}
}
return nil
}
// GetGPGPrivateKey gets the bytes of a specified keyid, supplying a passphrase
func (g *gpgVault) GetGPGPrivateKey(keyid uint64) ([]openpgp.Key, []byte) {
for i, el := range g.entityLists {
decKeys := el.KeysByIdUsage(keyid, packet.KeyFlagEncryptCommunications)
if len(decKeys) > 0 {
return decKeys, g.keyDataList[i]
}
}
return nil, nil
}

View File

@ -0,0 +1,152 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 jwe
import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/containers/ocicrypt/config"
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/utils"
"github.com/go-jose/go-jose/v3"
)
type jweKeyWrapper struct {
}
func (kw *jweKeyWrapper) GetAnnotationID() string {
return "org.opencontainers.image.enc.keys.jwe"
}
// NewKeyWrapper returns a new key wrapping interface using jwe
func NewKeyWrapper() keywrap.KeyWrapper {
return &jweKeyWrapper{}
}
// WrapKeys wraps the session key for recpients and encrypts the optsData, which
// describe the symmetric key used for encrypting the layer
func (kw *jweKeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
var joseRecipients []jose.Recipient
err := addPubKeys(&joseRecipients, ec.Parameters["pubkeys"])
if err != nil {
return nil, err
}
// no recipients is not an error...
if len(joseRecipients) == 0 {
return nil, nil
}
encrypter, err := jose.NewMultiEncrypter(jose.A256GCM, joseRecipients, nil)
if err != nil {
return nil, fmt.Errorf("jose.NewMultiEncrypter failed: %w", err)
}
jwe, err := encrypter.Encrypt(optsData)
if err != nil {
return nil, fmt.Errorf("JWE Encrypt failed: %w", err)
}
return []byte(jwe.FullSerialize()), nil
}
func (kw *jweKeyWrapper) UnwrapKey(dc *config.DecryptConfig, jweString []byte) ([]byte, error) {
jwe, err := jose.ParseEncrypted(string(jweString))
if err != nil {
return nil, errors.New("jose.ParseEncrypted failed")
}
privKeys := kw.GetPrivateKeys(dc.Parameters)
if len(privKeys) == 0 {
return nil, errors.New("No private keys found for JWE decryption")
}
privKeysPasswords := kw.getPrivateKeysPasswords(dc.Parameters)
if len(privKeysPasswords) != len(privKeys) {
return nil, errors.New("Private key password array length must be same as that of private keys")
}
for idx, privKey := range privKeys {
key, err := utils.ParsePrivateKey(privKey, privKeysPasswords[idx], "JWE")
if err != nil {
return nil, err
}
_, _, plain, err := jwe.DecryptMulti(key)
if err == nil {
return plain, nil
}
}
return nil, errors.New("JWE: No suitable private key found for decryption")
}
func (kw *jweKeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
return len(kw.GetPrivateKeys(dcparameters)) == 0
}
func (kw *jweKeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
return dcparameters["privkeys"]
}
func (kw *jweKeyWrapper) getPrivateKeysPasswords(dcparameters map[string][][]byte) [][]byte {
return dcparameters["privkeys-passwords"]
}
func (kw *jweKeyWrapper) GetKeyIdsFromPacket(b64jwes string) ([]uint64, error) {
return nil, nil
}
func (kw *jweKeyWrapper) GetRecipients(b64jwes string) ([]string, error) {
return []string{"[jwe]"}, nil
}
func addPubKeys(joseRecipients *[]jose.Recipient, pubKeys [][]byte) error {
if len(pubKeys) == 0 {
return nil
}
for _, pubKey := range pubKeys {
key, err := utils.ParsePublicKey(pubKey, "JWE")
if err != nil {
return err
}
alg := jose.RSA_OAEP
switch key := key.(type) {
case *ecdsa.PublicKey:
alg = jose.ECDH_ES_A256KW
case *jose.JSONWebKey:
if key.Algorithm != "" {
alg = jose.KeyAlgorithm(key.Algorithm)
switch alg {
/* accepted algorithms */
case jose.RSA_OAEP:
case jose.RSA_OAEP_256:
case jose.ECDH_ES_A128KW:
case jose.ECDH_ES_A192KW:
case jose.ECDH_ES_A256KW:
/* all others are rejected */
default:
return fmt.Errorf("%s is an unsupported JWE key algorithm", alg)
}
}
}
*joseRecipients = append(*joseRecipients, jose.Recipient{
Algorithm: alg,
Key: key,
})
}
return nil
}

View File

@ -0,0 +1,244 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 keyprovider
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/containers/ocicrypt/config"
keyproviderconfig "github.com/containers/ocicrypt/config/keyprovider-config"
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/utils"
keyproviderpb "github.com/containers/ocicrypt/utils/keyprovider"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc"
)
type keyProviderKeyWrapper struct {
provider string
attrs keyproviderconfig.KeyProviderAttrs
}
func (kw *keyProviderKeyWrapper) GetAnnotationID() string {
return "org.opencontainers.image.enc.keys.provider." + kw.provider
}
// NewKeyWrapper returns a new key wrapping interface using keyprovider
func NewKeyWrapper(p string, a keyproviderconfig.KeyProviderAttrs) keywrap.KeyWrapper {
return &keyProviderKeyWrapper{provider: p, attrs: a}
}
type KeyProviderKeyWrapProtocolOperation string
var (
OpKeyWrap KeyProviderKeyWrapProtocolOperation = "keywrap"
OpKeyUnwrap KeyProviderKeyWrapProtocolOperation = "keyunwrap"
)
// KeyProviderKeyWrapProtocolInput defines the input to the key provider binary or grpc method.
type KeyProviderKeyWrapProtocolInput struct {
// Operation is either "keywrap" or "keyunwrap"
Operation KeyProviderKeyWrapProtocolOperation `json:"op"`
// KeyWrapParams encodes the arguments to key wrap if operation is set to wrap
KeyWrapParams KeyWrapParams `json:"keywrapparams,omitempty"`
// KeyUnwrapParams encodes the arguments to key unwrap if operation is set to unwrap
KeyUnwrapParams KeyUnwrapParams `json:"keyunwrapparams,omitempty"`
}
// KeyProviderKeyWrapProtocolOutput defines the output of the key provider binary or grpc method.
type KeyProviderKeyWrapProtocolOutput struct {
// KeyWrapResult encodes the results to key wrap if operation is to wrap
KeyWrapResults KeyWrapResults `json:"keywrapresults,omitempty"`
// KeyUnwrapResult encodes the result to key unwrap if operation is to unwrap
KeyUnwrapResults KeyUnwrapResults `json:"keyunwrapresults,omitempty"`
}
type KeyWrapParams struct {
Ec *config.EncryptConfig `json:"ec"`
OptsData []byte `json:"optsdata"`
}
type KeyUnwrapParams struct {
Dc *config.DecryptConfig `json:"dc"`
Annotation []byte `json:"annotation"`
}
type KeyUnwrapResults struct {
OptsData []byte `json:"optsdata"`
}
type KeyWrapResults struct {
Annotation []byte `json:"annotation"`
}
var runner utils.CommandExecuter
func init() {
runner = utils.Runner{}
}
// WrapKeys calls appropriate binary executable/grpc server for wrapping the session key for recipients and gets encrypted optsData, which
// describe the symmetric key used for encrypting the layer
func (kw *keyProviderKeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
input, err := json.Marshal(KeyProviderKeyWrapProtocolInput{
Operation: OpKeyWrap,
KeyWrapParams: KeyWrapParams{
Ec: ec,
OptsData: optsData,
},
})
if err != nil {
return nil, err
}
if _, ok := ec.Parameters[kw.provider]; ok {
if kw.attrs.Command != nil {
protocolOuput, err := getProviderCommandOutput(input, kw.attrs.Command)
if err != nil {
return nil, fmt.Errorf("error while retrieving keyprovider protocol command output: %w", err)
}
return protocolOuput.KeyWrapResults.Annotation, nil
} else if kw.attrs.Grpc != "" {
protocolOuput, err := getProviderGRPCOutput(input, kw.attrs.Grpc, OpKeyWrap)
if err != nil {
return nil, fmt.Errorf("error while retrieving keyprovider protocol grpc output: %w", err)
}
return protocolOuput.KeyWrapResults.Annotation, nil
} else {
return nil, errors.New("Unsupported keyprovider invocation. Supported invocation methods are grpc and cmd")
}
}
return nil, nil
}
// UnwrapKey calls appropriate binary executable/grpc server for unwrapping the session key based on the protocol given in annotation for recipients and gets decrypted optsData,
// which describe the symmetric key used for decrypting the layer
func (kw *keyProviderKeyWrapper) UnwrapKey(dc *config.DecryptConfig, jsonString []byte) ([]byte, error) {
input, err := json.Marshal(KeyProviderKeyWrapProtocolInput{
Operation: OpKeyUnwrap,
KeyUnwrapParams: KeyUnwrapParams{
Dc: dc,
Annotation: jsonString,
},
})
if err != nil {
return nil, err
}
if kw.attrs.Command != nil {
protocolOuput, err := getProviderCommandOutput(input, kw.attrs.Command)
if err != nil {
// If err is not nil, then ignore it and continue with rest of the given keyproviders
return nil, err
}
return protocolOuput.KeyUnwrapResults.OptsData, nil
} else if kw.attrs.Grpc != "" {
protocolOuput, err := getProviderGRPCOutput(input, kw.attrs.Grpc, OpKeyUnwrap)
if err != nil {
// If err is not nil, then ignore it and continue with rest of the given keyproviders
return nil, err
}
return protocolOuput.KeyUnwrapResults.OptsData, nil
} else {
return nil, errors.New("Unsupported keyprovider invocation. Supported invocation methods are grpc and cmd")
}
}
func getProviderGRPCOutput(input []byte, connString string, operation KeyProviderKeyWrapProtocolOperation) (*KeyProviderKeyWrapProtocolOutput, error) {
var protocolOuput KeyProviderKeyWrapProtocolOutput
var grpcOutput *keyproviderpb.KeyProviderKeyWrapProtocolOutput
cc, err := grpc.Dial(connString, grpc.WithInsecure())
if err != nil {
return nil, fmt.Errorf("error while dialing rpc server: %w", err)
}
defer func() {
derr := cc.Close()
if derr != nil {
log.WithError(derr).Error("Error closing grpc socket")
}
}()
client := keyproviderpb.NewKeyProviderServiceClient(cc)
req := &keyproviderpb.KeyProviderKeyWrapProtocolInput{
KeyProviderKeyWrapProtocolInput: input,
}
if operation == OpKeyWrap {
grpcOutput, err = client.WrapKey(context.Background(), req)
if err != nil {
return nil, fmt.Errorf("Error from grpc method: %w", err)
}
} else if operation == OpKeyUnwrap {
grpcOutput, err = client.UnWrapKey(context.Background(), req)
if err != nil {
return nil, fmt.Errorf("Error from grpc method: %w", err)
}
} else {
return nil, errors.New("Unsupported operation")
}
respBytes := grpcOutput.GetKeyProviderKeyWrapProtocolOutput()
err = json.Unmarshal(respBytes, &protocolOuput)
if err != nil {
return nil, fmt.Errorf("Error while unmarshalling grpc method output: %w", err)
}
return &protocolOuput, nil
}
func getProviderCommandOutput(input []byte, command *keyproviderconfig.Command) (*KeyProviderKeyWrapProtocolOutput, error) {
var protocolOuput KeyProviderKeyWrapProtocolOutput
// Convert interface to command structure
respBytes, err := runner.Exec(command.Path, command.Args, input)
if err != nil {
return nil, err
}
err = json.Unmarshal(respBytes, &protocolOuput)
if err != nil {
return nil, fmt.Errorf("Error while unmarshalling binary executable command output: %w", err)
}
return &protocolOuput, nil
}
// Return false as it is not applicable to keyprovider protocol
func (kw *keyProviderKeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
return false
}
// Return nil as it is not applicable to keyprovider protocol
func (kw *keyProviderKeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
return nil
}
// Return nil as it is not applicable to keyprovider protocol
func (kw *keyProviderKeyWrapper) GetKeyIdsFromPacket(_ string) ([]uint64, error) {
return nil, nil
}
// Return nil as it is not applicable to keyprovider protocol
func (kw *keyProviderKeyWrapper) GetRecipients(_ string) ([]string, error) {
return nil, nil
}

View File

@ -0,0 +1,48 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 keywrap
import (
"github.com/containers/ocicrypt/config"
)
// KeyWrapper is the interface used for wrapping keys using
// a specific encryption technology (pgp, jwe)
type KeyWrapper interface {
WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error)
UnwrapKey(dc *config.DecryptConfig, annotation []byte) ([]byte, error)
GetAnnotationID() string
// NoPossibleKeys returns true if there is no possibility of performing
// decryption for parameters provided.
NoPossibleKeys(dcparameters map[string][][]byte) bool
// GetPrivateKeys (optional) gets the array of private keys. It is an optional implementation
// as in some key services, a private key may not be exportable (i.e. HSM)
// If not implemented, return nil
GetPrivateKeys(dcparameters map[string][][]byte) [][]byte
// GetKeyIdsFromPacket (optional) gets a list of key IDs. This is optional as some encryption
// schemes may not have a notion of key IDs
// If not implemented, return the nil slice
GetKeyIdsFromPacket(packet string) ([]uint64, error)
// GetRecipients (optional) gets a list of recipients. It is optional due to the validity of
// recipients in a particular encryptiong scheme
// If not implemented, return the nil slice
GetRecipients(packet string) ([]string, error)
}

View File

@ -0,0 +1,272 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pgp
import (
"bytes"
"crypto"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"io"
"net/mail"
"strconv"
"strings"
"github.com/containers/ocicrypt/config"
"github.com/containers/ocicrypt/keywrap"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
type gpgKeyWrapper struct {
}
// NewKeyWrapper returns a new key wrapping interface for pgp
func NewKeyWrapper() keywrap.KeyWrapper {
return &gpgKeyWrapper{}
}
var (
// GPGDefaultEncryptConfig is the default configuration for layer encryption/decryption
GPGDefaultEncryptConfig = &packet.Config{
Rand: rand.Reader,
DefaultHash: crypto.SHA256,
DefaultCipher: packet.CipherAES256,
CompressionConfig: &packet.CompressionConfig{Level: 0}, // No compression
RSABits: 2048,
}
)
func (kw *gpgKeyWrapper) GetAnnotationID() string {
return "org.opencontainers.image.enc.keys.pgp"
}
// WrapKeys wraps the session key for recpients and encrypts the optsData, which
// describe the symmetric key used for encrypting the layer
func (kw *gpgKeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
ciphertext := new(bytes.Buffer)
el, err := kw.createEntityList(ec)
if err != nil {
return nil, fmt.Errorf("unable to create entity list: %w", err)
}
if len(el) == 0 {
// nothing to do -- not an error
return nil, nil
}
plaintextWriter, err := openpgp.Encrypt(ciphertext,
el, /*EntityList*/
nil, /* Sign*/
nil, /* FileHint */
GPGDefaultEncryptConfig)
if err != nil {
return nil, err
}
if _, err = plaintextWriter.Write(optsData); err != nil {
return nil, err
} else if err = plaintextWriter.Close(); err != nil {
return nil, err
}
return ciphertext.Bytes(), err
}
// UnwrapKey unwraps the symmetric key with which the layer is encrypted
// This symmetric key is encrypted in the PGP payload.
func (kw *gpgKeyWrapper) UnwrapKey(dc *config.DecryptConfig, pgpPacket []byte) ([]byte, error) {
pgpPrivateKeys, pgpPrivateKeysPwd, err := kw.getKeyParameters(dc.Parameters)
if err != nil {
return nil, err
}
for idx, pgpPrivateKey := range pgpPrivateKeys {
r := bytes.NewBuffer(pgpPrivateKey)
entityList, err := openpgp.ReadKeyRing(r)
if err != nil {
return nil, fmt.Errorf("unable to parse private keys: %w", err)
}
var prompt openpgp.PromptFunction
if len(pgpPrivateKeysPwd) > idx {
responded := false
prompt = func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
if responded {
return nil, fmt.Errorf("don't seem to have the right password")
}
responded = true
for _, key := range keys {
if key.PrivateKey != nil {
_ = key.PrivateKey.Decrypt(pgpPrivateKeysPwd[idx])
}
}
return pgpPrivateKeysPwd[idx], nil
}
}
r = bytes.NewBuffer(pgpPacket)
md, err := openpgp.ReadMessage(r, entityList, prompt, GPGDefaultEncryptConfig)
if err != nil {
continue
}
// we get the plain key options back
optsData, err := io.ReadAll(md.UnverifiedBody)
if err != nil {
continue
}
return optsData, nil
}
return nil, errors.New("PGP: No suitable key found to unwrap key")
}
// GetKeyIdsFromWrappedKeys converts the base64 encoded PGPPacket to uint64 keyIds
func (kw *gpgKeyWrapper) GetKeyIdsFromPacket(b64pgpPackets string) ([]uint64, error) {
var keyids []uint64
for _, b64pgpPacket := range strings.Split(b64pgpPackets, ",") {
pgpPacket, err := base64.StdEncoding.DecodeString(b64pgpPacket)
if err != nil {
return nil, fmt.Errorf("could not decode base64 encoded PGP packet: %w", err)
}
newids, err := kw.getKeyIDs(pgpPacket)
if err != nil {
return nil, err
}
keyids = append(keyids, newids...)
}
return keyids, nil
}
// getKeyIDs parses a PGPPacket and gets the list of recipients' key IDs
func (kw *gpgKeyWrapper) getKeyIDs(pgpPacket []byte) ([]uint64, error) {
var keyids []uint64
kbuf := bytes.NewBuffer(pgpPacket)
packets := packet.NewReader(kbuf)
ParsePackets:
for {
p, err := packets.Next()
if err == io.EOF {
break ParsePackets
}
if err != nil {
return []uint64{}, fmt.Errorf("packets.Next() failed: %w", err)
}
switch p := p.(type) {
case *packet.EncryptedKey:
keyids = append(keyids, p.KeyId)
case *packet.SymmetricallyEncrypted:
break ParsePackets
}
}
return keyids, nil
}
// GetRecipients converts the wrappedKeys to an array of recipients
func (kw *gpgKeyWrapper) GetRecipients(b64pgpPackets string) ([]string, error) {
keyIds, err := kw.GetKeyIdsFromPacket(b64pgpPackets)
if err != nil {
return nil, err
}
var array []string
for _, keyid := range keyIds {
array = append(array, "0x"+strconv.FormatUint(keyid, 16))
}
return array, nil
}
func (kw *gpgKeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
return len(kw.GetPrivateKeys(dcparameters)) == 0
}
func (kw *gpgKeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
return dcparameters["gpg-privatekeys"]
}
func (kw *gpgKeyWrapper) getKeyParameters(dcparameters map[string][][]byte) ([][]byte, [][]byte, error) {
privKeys := kw.GetPrivateKeys(dcparameters)
if len(privKeys) == 0 {
return nil, nil, errors.New("GPG: Missing private key parameter")
}
return privKeys, dcparameters["gpg-privatekeys-passwords"], nil
}
// createEntityList creates the opengpg EntityList by reading the KeyRing
// first and then filtering out recipients' keys
func (kw *gpgKeyWrapper) createEntityList(ec *config.EncryptConfig) (openpgp.EntityList, error) {
pgpPubringFile := ec.Parameters["gpg-pubkeyringfile"]
if len(pgpPubringFile) == 0 {
return nil, nil
}
r := bytes.NewReader(pgpPubringFile[0])
entityList, err := openpgp.ReadKeyRing(r)
if err != nil {
return nil, err
}
gpgRecipients := ec.Parameters["gpg-recipients"]
if len(gpgRecipients) == 0 {
return nil, nil
}
rSet := make(map[string]int)
for _, r := range gpgRecipients {
rSet[string(r)] = 0
}
var filteredList openpgp.EntityList
for _, entity := range entityList {
for k := range entity.Identities {
addr, err := mail.ParseAddress(k)
if err != nil {
return nil, err
}
for _, r := range gpgRecipients {
recp := string(r)
if strings.Compare(addr.Name, recp) == 0 || strings.Compare(addr.Address, recp) == 0 {
filteredList = append(filteredList, entity)
rSet[recp] = rSet[recp] + 1
}
}
}
}
// make sure we found keys for all the Recipients...
var buffer bytes.Buffer
notFound := false
buffer.WriteString("PGP: No key found for the following recipients: ")
for k, v := range rSet {
if v == 0 {
if notFound {
buffer.WriteString(", ")
}
buffer.WriteString(k)
notFound = true
}
}
if notFound {
return nil, errors.New(buffer.String())
}
return filteredList, nil
}

View File

@ -0,0 +1,152 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs11
import (
"errors"
"fmt"
"github.com/containers/ocicrypt/config"
"github.com/containers/ocicrypt/crypto/pkcs11"
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/utils"
)
type pkcs11KeyWrapper struct {
}
func (kw *pkcs11KeyWrapper) GetAnnotationID() string {
return "org.opencontainers.image.enc.keys.pkcs11"
}
// NewKeyWrapper returns a new key wrapping interface using pkcs11
func NewKeyWrapper() keywrap.KeyWrapper {
return &pkcs11KeyWrapper{}
}
// WrapKeys wraps the session key for recpients and encrypts the optsData, which
// describe the symmetric key used for encrypting the layer
func (kw *pkcs11KeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
// append({}, ...) allocates a fresh backing array, and that's necessary to guarantee concurrent calls to WrapKeys (as in c/image/copy.Image)
// can't race writing to the same backing array.
pubKeys := append([][]byte{}, ec.Parameters["pkcs11-pubkeys"]...) // In Go 1.21, slices.Clone(ec.Parameters["pkcs11-pubkeys"])
pubKeys = append(pubKeys, ec.Parameters["pkcs11-yamls"]...)
pkcs11Recipients, err := addPubKeys(&ec.DecryptConfig, pubKeys)
if err != nil {
return nil, err
}
// no recipients is not an error...
if len(pkcs11Recipients) == 0 {
return nil, nil
}
jsonString, err := pkcs11.EncryptMultiple(pkcs11Recipients, optsData)
if err != nil {
return nil, fmt.Errorf("PKCS11 EncryptMulitple failed: %w", err)
}
return jsonString, nil
}
func (kw *pkcs11KeyWrapper) UnwrapKey(dc *config.DecryptConfig, jsonString []byte) ([]byte, error) {
var pkcs11PrivKeys []*pkcs11.Pkcs11KeyFileObject
privKeys := kw.GetPrivateKeys(dc.Parameters)
if len(privKeys) == 0 {
return nil, errors.New("No private keys found for PKCS11 decryption")
}
p11conf, err := p11confFromParameters(dc.Parameters)
if err != nil {
return nil, err
}
for _, privKey := range privKeys {
key, err := utils.ParsePrivateKey(privKey, nil, "PKCS11")
if err != nil {
return nil, err
}
switch pkcs11PrivKey := key.(type) {
case *pkcs11.Pkcs11KeyFileObject:
if p11conf != nil {
pkcs11PrivKey.Uri.SetModuleDirectories(p11conf.ModuleDirectories)
pkcs11PrivKey.Uri.SetAllowedModulePaths(p11conf.AllowedModulePaths)
}
pkcs11PrivKeys = append(pkcs11PrivKeys, pkcs11PrivKey)
default:
continue
}
}
plaintext, err := pkcs11.Decrypt(pkcs11PrivKeys, jsonString)
if err == nil {
return plaintext, nil
}
return nil, fmt.Errorf("PKCS11: No suitable private key found for decryption: %w", err)
}
func (kw *pkcs11KeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
return len(kw.GetPrivateKeys(dcparameters)) == 0
}
func (kw *pkcs11KeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
return dcparameters["pkcs11-yamls"]
}
func (kw *pkcs11KeyWrapper) GetKeyIdsFromPacket(_ string) ([]uint64, error) {
return nil, nil
}
func (kw *pkcs11KeyWrapper) GetRecipients(_ string) ([]string, error) {
return []string{"[pkcs11]"}, nil
}
func addPubKeys(dc *config.DecryptConfig, pubKeys [][]byte) ([]interface{}, error) {
var pkcs11Keys []interface{}
if len(pubKeys) == 0 {
return pkcs11Keys, nil
}
p11conf, err := p11confFromParameters(dc.Parameters)
if err != nil {
return nil, err
}
for _, pubKey := range pubKeys {
key, err := utils.ParsePublicKey(pubKey, "PKCS11")
if err != nil {
return nil, err
}
switch pkcs11PubKey := key.(type) {
case *pkcs11.Pkcs11KeyFileObject:
if p11conf != nil {
pkcs11PubKey.Uri.SetModuleDirectories(p11conf.ModuleDirectories)
pkcs11PubKey.Uri.SetAllowedModulePaths(p11conf.AllowedModulePaths)
}
}
pkcs11Keys = append(pkcs11Keys, key)
}
return pkcs11Keys, nil
}
func p11confFromParameters(dcparameters map[string][][]byte) (*pkcs11.Pkcs11Config, error) {
if _, ok := dcparameters["pkcs11-config"]; ok {
return pkcs11.ParsePkcs11ConfigFile(dcparameters["pkcs11-config"][0])
}
return nil, nil
}

View File

@ -0,0 +1,137 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 pkcs7
import (
"crypto"
"crypto/x509"
"errors"
"fmt"
"github.com/containers/ocicrypt/config"
"github.com/containers/ocicrypt/keywrap"
"github.com/containers/ocicrypt/utils"
"go.mozilla.org/pkcs7"
)
type pkcs7KeyWrapper struct {
}
// NewKeyWrapper returns a new key wrapping interface using jwe
func NewKeyWrapper() keywrap.KeyWrapper {
return &pkcs7KeyWrapper{}
}
func (kw *pkcs7KeyWrapper) GetAnnotationID() string {
return "org.opencontainers.image.enc.keys.pkcs7"
}
// WrapKeys wraps the session key for recpients and encrypts the optsData, which
// describe the symmetric key used for encrypting the layer
func (kw *pkcs7KeyWrapper) WrapKeys(ec *config.EncryptConfig, optsData []byte) ([]byte, error) {
x509Certs, err := collectX509s(ec.Parameters["x509s"])
if err != nil {
return nil, err
}
// no recipients is not an error...
if len(x509Certs) == 0 {
return nil, nil
}
pkcs7.ContentEncryptionAlgorithm = pkcs7.EncryptionAlgorithmAES128GCM
return pkcs7.Encrypt(optsData, x509Certs)
}
func collectX509s(x509s [][]byte) ([]*x509.Certificate, error) {
if len(x509s) == 0 {
return nil, nil
}
var x509Certs []*x509.Certificate
for _, x509 := range x509s {
x509Cert, err := utils.ParseCertificate(x509, "PKCS7")
if err != nil {
return nil, err
}
x509Certs = append(x509Certs, x509Cert)
}
return x509Certs, nil
}
func (kw *pkcs7KeyWrapper) NoPossibleKeys(dcparameters map[string][][]byte) bool {
return len(kw.GetPrivateKeys(dcparameters)) == 0
}
func (kw *pkcs7KeyWrapper) GetPrivateKeys(dcparameters map[string][][]byte) [][]byte {
return dcparameters["privkeys"]
}
func (kw *pkcs7KeyWrapper) getPrivateKeysPasswords(dcparameters map[string][][]byte) [][]byte {
return dcparameters["privkeys-passwords"]
}
// UnwrapKey unwraps the symmetric key with which the layer is encrypted
// This symmetric key is encrypted in the PKCS7 payload.
func (kw *pkcs7KeyWrapper) UnwrapKey(dc *config.DecryptConfig, pkcs7Packet []byte) ([]byte, error) {
privKeys := kw.GetPrivateKeys(dc.Parameters)
if len(privKeys) == 0 {
return nil, errors.New("no private keys found for PKCS7 decryption")
}
privKeysPasswords := kw.getPrivateKeysPasswords(dc.Parameters)
if len(privKeysPasswords) != len(privKeys) {
return nil, errors.New("private key password array length must be same as that of private keys")
}
x509Certs, err := collectX509s(dc.Parameters["x509s"])
if err != nil {
return nil, err
}
if len(x509Certs) == 0 {
return nil, errors.New("no x509 certificates found needed for PKCS7 decryption")
}
p7, err := pkcs7.Parse(pkcs7Packet)
if err != nil {
return nil, fmt.Errorf("could not parse PKCS7 packet: %w", err)
}
for idx, privKey := range privKeys {
key, err := utils.ParsePrivateKey(privKey, privKeysPasswords[idx], "PKCS7")
if err != nil {
return nil, err
}
for _, x509Cert := range x509Certs {
optsData, err := p7.Decrypt(x509Cert, crypto.PrivateKey(key))
if err != nil {
continue
}
return optsData, nil
}
}
return nil, errors.New("PKCS7: No suitable private key found for decryption")
}
// GetKeyIdsFromWrappedKeys converts the base64 encoded Packet to uint64 keyIds;
// We cannot do this with pkcs7
func (kw *pkcs7KeyWrapper) GetKeyIdsFromPacket(b64pkcs7Packets string) ([]uint64, error) {
return nil, nil
}
// GetRecipients converts the wrappedKeys to an array of recipients
// We cannot do this with pkcs7
func (kw *pkcs7KeyWrapper) GetRecipients(b64pkcs7Packets string) ([]string, error) {
return []string{"[pkcs7]"}, nil
}

40
vendor/github.com/containers/ocicrypt/reader.go generated vendored Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 ocicrypt
import (
"io"
)
type readerAtReader struct {
r io.ReaderAt
off int64
}
// ReaderFromReaderAt takes an io.ReaderAt and returns an io.Reader
func ReaderFromReaderAt(r io.ReaderAt) io.Reader {
return &readerAtReader{
r: r,
off: 0,
}
}
func (rar *readerAtReader) Read(p []byte) (n int, err error) {
n, err = rar.r.ReadAt(p, rar.off)
rar.off += int64(n)
return n, err
}

20
vendor/github.com/containers/ocicrypt/spec/spec.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
package spec
const (
// MediaTypeLayerEnc is MIME type used for encrypted layers.
MediaTypeLayerEnc = "application/vnd.oci.image.layer.v1.tar+encrypted"
// MediaTypeLayerGzipEnc is MIME type used for encrypted gzip-compressed layers.
MediaTypeLayerGzipEnc = "application/vnd.oci.image.layer.v1.tar+gzip+encrypted"
// MediaTypeLayerZstdEnc is MIME type used for encrypted zstd-compressed layers.
MediaTypeLayerZstdEnc = "application/vnd.oci.image.layer.v1.tar+zstd+encrypted"
// MediaTypeLayerNonDistributableEnc is MIME type used for non distributable encrypted layers.
MediaTypeLayerNonDistributableEnc = "application/vnd.oci.image.layer.nondistributable.v1.tar+encrypted"
// MediaTypeLayerNonDistributableGzipEnc is MIME type used for non distributable encrypted gzip-compressed layers.
MediaTypeLayerNonDistributableGzipEnc = "application/vnd.oci.image.layer.nondistributable.v1.tar+gzip+encrypted"
// MediaTypeLayerNonDistributableZstdEnc is MIME type used for non distributable encrypted zstd-compressed layers.
MediaTypeLayerNonDistributableZstdEnc = "application/vnd.oci.image.layer.nondistributable.v1.tar+zstd+encrypted"
// MediaTypeLayerNonDistributableZsdtEnc is MIME type used for non distributable encrypted zstd-compressed layers.
//
// Deprecated: Use [MediaTypeLayerNonDistributableZstdEnc].
MediaTypeLayerNonDistributableZsdtEnc = MediaTypeLayerNonDistributableZstdEnc
)

View File

@ -0,0 +1,109 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 utils
import (
"io"
)
func min(a, b int) int {
if a < b {
return a
}
return b
}
// DelayedReader wraps a io.Reader and allows a client to use the Reader
// interface. The DelayedReader holds back some buffer to the client
// so that it can report any error that occurred on the Reader it wraps
// early to the client while it may still have held some data back.
type DelayedReader struct {
reader io.Reader // Reader to Read() bytes from and delay them
err error // error that occurred on the reader
buffer []byte // delay buffer
bufbytes int // number of bytes in the delay buffer to give to Read(); on '0' we return 'EOF' to caller
bufoff int // offset in the delay buffer to give to Read()
}
// NewDelayedReader wraps a io.Reader and allocates a delay buffer of bufsize bytes
func NewDelayedReader(reader io.Reader, bufsize uint) io.Reader {
return &DelayedReader{
reader: reader,
buffer: make([]byte, bufsize),
}
}
// Read implements the io.Reader interface
func (dr *DelayedReader) Read(p []byte) (int, error) {
if dr.err != nil && dr.err != io.EOF {
return 0, dr.err
}
// if we are completely drained, return io.EOF
if dr.err == io.EOF && dr.bufbytes == 0 {
return 0, io.EOF
}
// only at the beginning we fill our delay buffer in an extra step
if dr.bufbytes < len(dr.buffer) && dr.err == nil {
dr.bufbytes, dr.err = FillBuffer(dr.reader, dr.buffer)
if dr.err != nil && dr.err != io.EOF {
return 0, dr.err
}
}
// dr.err != nil means we have EOF and can drain the delay buffer
// otherwise we need to still read from the reader
var tmpbuf []byte
tmpbufbytes := 0
if dr.err == nil {
tmpbuf = make([]byte, len(p))
tmpbufbytes, dr.err = FillBuffer(dr.reader, tmpbuf)
if dr.err != nil && dr.err != io.EOF {
return 0, dr.err
}
}
// copy out of the delay buffer into 'p'
tocopy1 := min(len(p), dr.bufbytes)
c1 := copy(p[:tocopy1], dr.buffer[dr.bufoff:])
dr.bufoff += c1
dr.bufbytes -= c1
c2 := 0
// can p still hold more data?
if c1 < len(p) {
// copy out of the tmpbuf into 'p'
c2 = copy(p[tocopy1:], tmpbuf[:tmpbufbytes])
}
// if tmpbuf holds data we need to hold onto, copy them
// into the delay buffer
if tmpbufbytes-c2 > 0 {
// left-shift the delay buffer and append the tmpbuf's remaining data
dr.buffer = dr.buffer[dr.bufoff : dr.bufoff+dr.bufbytes]
dr.buffer = append(dr.buffer, tmpbuf[c2:tmpbufbytes]...)
dr.bufoff = 0
dr.bufbytes = len(dr.buffer)
}
var err error
if dr.bufbytes == 0 {
err = io.EOF
}
return c1 + c2, err
}

58
vendor/github.com/containers/ocicrypt/utils/ioutils.go generated vendored Normal file
View File

@ -0,0 +1,58 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 utils
import (
"bytes"
"fmt"
"io"
"os/exec"
)
// FillBuffer fills the given buffer with as many bytes from the reader as possible. It returns
// EOF if an EOF was encountered or any other error.
func FillBuffer(reader io.Reader, buffer []byte) (int, error) {
n, err := io.ReadFull(reader, buffer)
if err == io.ErrUnexpectedEOF {
return n, io.EOF
}
return n, err
}
// first argument is the command, like cat or echo,
// the second is the list of args to pass to it
type CommandExecuter interface {
Exec(string, []string, []byte) ([]byte, error)
}
type Runner struct{}
// ExecuteCommand is used to execute a linux command line command and return the output of the command with an error if it exists.
func (r Runner) Exec(cmdName string, args []string, input []byte) ([]byte, error) {
var out bytes.Buffer
var stderr bytes.Buffer
stdInputBuffer := bytes.NewBuffer(input)
cmd := exec.Command(cmdName, args...)
cmd.Stdin = stdInputBuffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
return nil, fmt.Errorf("Error while running command: %s. stderr: %s: %w", cmdName, stderr.String(), err)
}
return out.Bytes(), nil
}

View File

@ -0,0 +1,243 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: keyprovider.proto
package keyprovider
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type KeyProviderKeyWrapProtocolInput struct {
KeyProviderKeyWrapProtocolInput []byte `protobuf:"bytes,1,opt,name=KeyProviderKeyWrapProtocolInput,proto3" json:"KeyProviderKeyWrapProtocolInput,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *KeyProviderKeyWrapProtocolInput) Reset() { *m = KeyProviderKeyWrapProtocolInput{} }
func (m *KeyProviderKeyWrapProtocolInput) String() string { return proto.CompactTextString(m) }
func (*KeyProviderKeyWrapProtocolInput) ProtoMessage() {}
func (*KeyProviderKeyWrapProtocolInput) Descriptor() ([]byte, []int) {
return fileDescriptor_da74c8e785ad390c, []int{0}
}
func (m *KeyProviderKeyWrapProtocolInput) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Unmarshal(m, b)
}
func (m *KeyProviderKeyWrapProtocolInput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Marshal(b, m, deterministic)
}
func (m *KeyProviderKeyWrapProtocolInput) XXX_Merge(src proto.Message) {
xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Merge(m, src)
}
func (m *KeyProviderKeyWrapProtocolInput) XXX_Size() int {
return xxx_messageInfo_KeyProviderKeyWrapProtocolInput.Size(m)
}
func (m *KeyProviderKeyWrapProtocolInput) XXX_DiscardUnknown() {
xxx_messageInfo_KeyProviderKeyWrapProtocolInput.DiscardUnknown(m)
}
var xxx_messageInfo_KeyProviderKeyWrapProtocolInput proto.InternalMessageInfo
func (m *KeyProviderKeyWrapProtocolInput) GetKeyProviderKeyWrapProtocolInput() []byte {
if m != nil {
return m.KeyProviderKeyWrapProtocolInput
}
return nil
}
type KeyProviderKeyWrapProtocolOutput struct {
KeyProviderKeyWrapProtocolOutput []byte `protobuf:"bytes,1,opt,name=KeyProviderKeyWrapProtocolOutput,proto3" json:"KeyProviderKeyWrapProtocolOutput,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *KeyProviderKeyWrapProtocolOutput) Reset() { *m = KeyProviderKeyWrapProtocolOutput{} }
func (m *KeyProviderKeyWrapProtocolOutput) String() string { return proto.CompactTextString(m) }
func (*KeyProviderKeyWrapProtocolOutput) ProtoMessage() {}
func (*KeyProviderKeyWrapProtocolOutput) Descriptor() ([]byte, []int) {
return fileDescriptor_da74c8e785ad390c, []int{1}
}
func (m *KeyProviderKeyWrapProtocolOutput) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Unmarshal(m, b)
}
func (m *KeyProviderKeyWrapProtocolOutput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Marshal(b, m, deterministic)
}
func (m *KeyProviderKeyWrapProtocolOutput) XXX_Merge(src proto.Message) {
xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Merge(m, src)
}
func (m *KeyProviderKeyWrapProtocolOutput) XXX_Size() int {
return xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.Size(m)
}
func (m *KeyProviderKeyWrapProtocolOutput) XXX_DiscardUnknown() {
xxx_messageInfo_KeyProviderKeyWrapProtocolOutput.DiscardUnknown(m)
}
var xxx_messageInfo_KeyProviderKeyWrapProtocolOutput proto.InternalMessageInfo
func (m *KeyProviderKeyWrapProtocolOutput) GetKeyProviderKeyWrapProtocolOutput() []byte {
if m != nil {
return m.KeyProviderKeyWrapProtocolOutput
}
return nil
}
func init() {
proto.RegisterType((*KeyProviderKeyWrapProtocolInput)(nil), "keyprovider.keyProviderKeyWrapProtocolInput")
proto.RegisterType((*KeyProviderKeyWrapProtocolOutput)(nil), "keyprovider.keyProviderKeyWrapProtocolOutput")
}
func init() {
proto.RegisterFile("keyprovider.proto", fileDescriptor_da74c8e785ad390c)
}
var fileDescriptor_da74c8e785ad390c = []byte{
// 169 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xcc, 0x4e, 0xad, 0x2c,
0x28, 0xca, 0x2f, 0xcb, 0x4c, 0x49, 0x2d, 0xd2, 0x03, 0x32, 0x4a, 0xf2, 0x85, 0xb8, 0x91, 0x84,
0x94, 0xb2, 0xb9, 0xe4, 0x81, 0xdc, 0x00, 0x28, 0xd7, 0x3b, 0xb5, 0x32, 0xbc, 0x28, 0xb1, 0x20,
0x00, 0xa4, 0x2e, 0x39, 0x3f, 0xc7, 0x33, 0xaf, 0xa0, 0xb4, 0x44, 0xc8, 0x83, 0x4b, 0xde, 0x1b,
0xbf, 0x12, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x42, 0xca, 0x94, 0xf2, 0xb8, 0x14, 0x70,
0x5b, 0xe6, 0x5f, 0x5a, 0x02, 0xb2, 0xcd, 0x8b, 0x4b, 0xc1, 0x9b, 0x80, 0x1a, 0xa8, 0x75, 0x04,
0xd5, 0x19, 0xbd, 0x62, 0xe4, 0x12, 0x42, 0x52, 0x14, 0x9c, 0x5a, 0x54, 0x96, 0x99, 0x9c, 0x2a,
0x94, 0xc1, 0xc5, 0x0e, 0x52, 0x0c, 0x94, 0x11, 0xd2, 0xd1, 0x43, 0x0e, 0x1f, 0x02, 0x21, 0x21,
0xa5, 0x4b, 0xa4, 0x6a, 0x88, 0xf5, 0x4a, 0x0c, 0x42, 0x59, 0x5c, 0x9c, 0xa1, 0x79, 0xf4, 0xb1,
0xcb, 0x89, 0x37, 0x0a, 0x39, 0x62, 0x93, 0xd8, 0xc0, 0x91, 0x6d, 0x0c, 0x08, 0x00, 0x00, 0xff,
0xff, 0x9a, 0x10, 0xcb, 0xf9, 0x01, 0x02, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6
// KeyProviderServiceClient is the client API for KeyProviderService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type KeyProviderServiceClient interface {
WrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error)
UnWrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error)
}
type keyProviderServiceClient struct {
cc grpc.ClientConnInterface
}
func NewKeyProviderServiceClient(cc grpc.ClientConnInterface) KeyProviderServiceClient {
return &keyProviderServiceClient{cc}
}
func (c *keyProviderServiceClient) WrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error) {
out := new(KeyProviderKeyWrapProtocolOutput)
err := c.cc.Invoke(ctx, "/keyprovider.KeyProviderService/WrapKey", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *keyProviderServiceClient) UnWrapKey(ctx context.Context, in *KeyProviderKeyWrapProtocolInput, opts ...grpc.CallOption) (*KeyProviderKeyWrapProtocolOutput, error) {
out := new(KeyProviderKeyWrapProtocolOutput)
err := c.cc.Invoke(ctx, "/keyprovider.KeyProviderService/UnWrapKey", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// KeyProviderServiceServer is the server API for KeyProviderService service.
type KeyProviderServiceServer interface {
WrapKey(context.Context, *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error)
UnWrapKey(context.Context, *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error)
}
// UnimplementedKeyProviderServiceServer can be embedded to have forward compatible implementations.
type UnimplementedKeyProviderServiceServer struct {
}
func (*UnimplementedKeyProviderServiceServer) WrapKey(ctx context.Context, req *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error) {
return nil, status.Errorf(codes.Unimplemented, "method WrapKey not implemented")
}
func (*UnimplementedKeyProviderServiceServer) UnWrapKey(ctx context.Context, req *KeyProviderKeyWrapProtocolInput) (*KeyProviderKeyWrapProtocolOutput, error) {
return nil, status.Errorf(codes.Unimplemented, "method UnWrapKey not implemented")
}
func RegisterKeyProviderServiceServer(s *grpc.Server, srv KeyProviderServiceServer) {
s.RegisterService(&_KeyProviderService_serviceDesc, srv)
}
func _KeyProviderService_WrapKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(KeyProviderKeyWrapProtocolInput)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KeyProviderServiceServer).WrapKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/keyprovider.KeyProviderService/WrapKey",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KeyProviderServiceServer).WrapKey(ctx, req.(*KeyProviderKeyWrapProtocolInput))
}
return interceptor(ctx, in, info, handler)
}
func _KeyProviderService_UnWrapKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(KeyProviderKeyWrapProtocolInput)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KeyProviderServiceServer).UnWrapKey(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/keyprovider.KeyProviderService/UnWrapKey",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KeyProviderServiceServer).UnWrapKey(ctx, req.(*KeyProviderKeyWrapProtocolInput))
}
return interceptor(ctx, in, info, handler)
}
var _KeyProviderService_serviceDesc = grpc.ServiceDesc{
ServiceName: "keyprovider.KeyProviderService",
HandlerType: (*KeyProviderServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "WrapKey",
Handler: _KeyProviderService_WrapKey_Handler,
},
{
MethodName: "UnWrapKey",
Handler: _KeyProviderService_UnWrapKey_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "keyprovider.proto",
}

View File

@ -0,0 +1,17 @@
syntax = "proto3";
package keyprovider;
option go_package = "keyprovider";
message keyProviderKeyWrapProtocolInput {
bytes KeyProviderKeyWrapProtocolInput = 1;
}
message keyProviderKeyWrapProtocolOutput {
bytes KeyProviderKeyWrapProtocolOutput = 1;
}
service KeyProviderService {
rpc WrapKey(keyProviderKeyWrapProtocolInput) returns (keyProviderKeyWrapProtocolOutput) {};
rpc UnWrapKey(keyProviderKeyWrapProtocolInput) returns (keyProviderKeyWrapProtocolOutput) {};
}

174
vendor/github.com/containers/ocicrypt/utils/testing.go generated vendored Normal file
View File

@ -0,0 +1,174 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 utils
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"time"
)
// CreateRSAKey creates an RSA key
func CreateRSAKey(bits int) (*rsa.PrivateKey, error) {
key, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return nil, fmt.Errorf("rsa.GenerateKey failed: %w", err)
}
return key, nil
}
// CreateECDSAKey creates an elliptic curve key for the given curve
func CreateECDSAKey(curve elliptic.Curve) (*ecdsa.PrivateKey, error) {
key, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
return nil, fmt.Errorf("ecdsa.GenerateKey failed: %w", err)
}
return key, nil
}
// CreateRSATestKey creates an RSA key of the given size and returns
// the public and private key in PEM or DER format
func CreateRSATestKey(bits int, password []byte, pemencode bool) ([]byte, []byte, error) {
key, err := CreateRSAKey(bits)
if err != nil {
return nil, nil, err
}
pubData, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
if err != nil {
return nil, nil, fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err)
}
privData := x509.MarshalPKCS1PrivateKey(key)
// no more encoding needed for DER
if !pemencode {
return pubData, privData, nil
}
publicKey := pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: pubData,
})
var block *pem.Block
typ := "RSA PRIVATE KEY"
if len(password) > 0 {
block, err = x509.EncryptPEMBlock(rand.Reader, typ, privData, password, x509.PEMCipherAES256) //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if err != nil {
return nil, nil, fmt.Errorf("x509.EncryptPEMBlock failed: %w", err)
}
} else {
block = &pem.Block{
Type: typ,
Bytes: privData,
}
}
privateKey := pem.EncodeToMemory(block)
return publicKey, privateKey, nil
}
// CreateECDSATestKey creates and elliptic curve key for the given curve and returns
// the public and private key in DER format
func CreateECDSATestKey(curve elliptic.Curve) ([]byte, []byte, error) {
key, err := CreateECDSAKey(curve)
if err != nil {
return nil, nil, err
}
pubData, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
if err != nil {
return nil, nil, fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err)
}
privData, err := x509.MarshalECPrivateKey(key)
if err != nil {
return nil, nil, fmt.Errorf("x509.MarshalECPrivateKey failed: %w", err)
}
return pubData, privData, nil
}
// CreateTestCA creates a root CA for testing
func CreateTestCA() (*rsa.PrivateKey, *x509.Certificate, error) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, nil, fmt.Errorf("rsa.GenerateKey failed: %w", err)
}
ca := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: "test-ca",
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
IsCA: true,
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}
caCert, err := certifyKey(&key.PublicKey, ca, key, ca)
return key, caCert, err
}
// CertifyKey certifies a public key using the given CA's private key and cert;
// The certificate template for the public key is optional
func CertifyKey(pubbytes []byte, template *x509.Certificate, caKey *rsa.PrivateKey, caCert *x509.Certificate) (*x509.Certificate, error) {
pubKey, err := ParsePublicKey(pubbytes, "CertifyKey")
if err != nil {
return nil, err
}
return certifyKey(pubKey, template, caKey, caCert)
}
func certifyKey(pub interface{}, template *x509.Certificate, caKey *rsa.PrivateKey, caCert *x509.Certificate) (*x509.Certificate, error) {
if template == nil {
template = &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: "testkey",
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour),
IsCA: false,
KeyUsage: x509.KeyUsageDigitalSignature,
BasicConstraintsValid: true,
}
}
certDER, err := x509.CreateCertificate(rand.Reader, template, caCert, pub, caKey)
if err != nil {
return nil, fmt.Errorf("x509.CreateCertificate failed: %w", err)
}
cert, err := x509.ParseCertificate(certDER)
if err != nil {
return nil, fmt.Errorf("x509.ParseCertificate failed: %w", err)
}
return cert, nil
}

249
vendor/github.com/containers/ocicrypt/utils/utils.go generated vendored Normal file
View File

@ -0,0 +1,249 @@
/*
Copyright The ocicrypt Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT 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 utils
import (
"bytes"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"fmt"
"strings"
"github.com/containers/ocicrypt/crypto/pkcs11"
"github.com/go-jose/go-jose/v3"
"golang.org/x/crypto/openpgp"
)
// parseJWKPrivateKey parses the input byte array as a JWK and makes sure it's a private key
func parseJWKPrivateKey(privKey []byte, prefix string) (interface{}, error) {
jwk := jose.JSONWebKey{}
err := jwk.UnmarshalJSON(privKey)
if err != nil {
return nil, fmt.Errorf("%s: Could not parse input as JWK: %w", prefix, err)
}
if jwk.IsPublic() {
return nil, fmt.Errorf("%s: JWK is not a private key", prefix)
}
return &jwk, nil
}
// parseJWKPublicKey parses the input byte array as a JWK
func parseJWKPublicKey(privKey []byte, prefix string) (interface{}, error) {
jwk := jose.JSONWebKey{}
err := jwk.UnmarshalJSON(privKey)
if err != nil {
return nil, fmt.Errorf("%s: Could not parse input as JWK: %w", prefix, err)
}
if !jwk.IsPublic() {
return nil, fmt.Errorf("%s: JWK is not a public key", prefix)
}
return &jwk, nil
}
// parsePkcs11PrivateKeyYaml parses the input byte array as pkcs11 key file yaml format)
func parsePkcs11PrivateKeyYaml(yaml []byte, prefix string) (*pkcs11.Pkcs11KeyFileObject, error) {
// if the URI does not have enough attributes, we will throw an error when decrypting
return pkcs11.ParsePkcs11KeyFile(yaml)
}
// parsePkcs11URIPublicKey parses the input byte array as a pkcs11 key file yaml
func parsePkcs11PublicKeyYaml(yaml []byte, prefix string) (*pkcs11.Pkcs11KeyFileObject, error) {
// if the URI does not have enough attributes, we will throw an error when decrypting
return pkcs11.ParsePkcs11KeyFile(yaml)
}
// IsPasswordError checks whether an error is related to a missing or wrong
// password
func IsPasswordError(err error) bool {
if err == nil {
return false
}
msg := strings.ToLower(err.Error())
return strings.Contains(msg, "password") &&
(strings.Contains(msg, "missing") || strings.Contains(msg, "wrong"))
}
// ParsePrivateKey tries to parse a private key in DER format first and
// PEM format after, returning an error if the parsing failed
func ParsePrivateKey(privKey, privKeyPassword []byte, prefix string) (interface{}, error) {
key, err := x509.ParsePKCS8PrivateKey(privKey)
if err != nil {
key, err = x509.ParsePKCS1PrivateKey(privKey)
if err != nil {
key, err = x509.ParseECPrivateKey(privKey)
}
}
if err != nil {
block, _ := pem.Decode(privKey)
if block != nil {
var der []byte
if x509.IsEncryptedPEMBlock(block) { //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if privKeyPassword == nil {
return nil, fmt.Errorf("%s: Missing password for encrypted private key", prefix)
}
der, err = x509.DecryptPEMBlock(block, privKeyPassword) //nolint:staticcheck // ignore SA1019, which is kept for backward compatibility
if err != nil {
return nil, fmt.Errorf("%s: Wrong password: could not decrypt private key", prefix)
}
} else {
der = block.Bytes
}
key, err = x509.ParsePKCS8PrivateKey(der)
if err != nil {
key, err = x509.ParsePKCS1PrivateKey(der)
if err != nil {
return nil, fmt.Errorf("%s: Could not parse private key: %w", prefix, err)
}
}
} else {
key, err = parseJWKPrivateKey(privKey, prefix)
if err != nil {
key, err = parsePkcs11PrivateKeyYaml(privKey, prefix)
}
}
}
return key, err
}
// IsPrivateKey returns true in case the given byte array represents a private key
// It returns an error if for example the password is wrong
func IsPrivateKey(data []byte, password []byte) (bool, error) {
_, err := ParsePrivateKey(data, password, "")
return err == nil, err
}
// IsPkcs11PrivateKey returns true in case the given byte array represents a pkcs11 private key
func IsPkcs11PrivateKey(data []byte) bool {
return pkcs11.IsPkcs11PrivateKey(data)
}
// ParsePublicKey tries to parse a public key in DER format first and
// PEM format after, returning an error if the parsing failed
func ParsePublicKey(pubKey []byte, prefix string) (interface{}, error) {
key, err := x509.ParsePKIXPublicKey(pubKey)
if err != nil {
block, _ := pem.Decode(pubKey)
if block != nil {
key, err = x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("%s: Could not parse public key: %w", prefix, err)
}
} else {
key, err = parseJWKPublicKey(pubKey, prefix)
if err != nil {
key, err = parsePkcs11PublicKeyYaml(pubKey, prefix)
}
}
}
return key, err
}
// IsPublicKey returns true in case the given byte array represents a public key
func IsPublicKey(data []byte) bool {
_, err := ParsePublicKey(data, "")
return err == nil
}
// IsPkcs11PublicKey returns true in case the given byte array represents a pkcs11 public key
func IsPkcs11PublicKey(data []byte) bool {
return pkcs11.IsPkcs11PublicKey(data)
}
// ParseCertificate tries to parse a public key in DER format first and
// PEM format after, returning an error if the parsing failed
func ParseCertificate(certBytes []byte, prefix string) (*x509.Certificate, error) {
x509Cert, err := x509.ParseCertificate(certBytes)
if err != nil {
block, _ := pem.Decode(certBytes)
if block == nil {
return nil, fmt.Errorf("%s: Could not PEM decode x509 certificate", prefix)
}
x509Cert, err = x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, fmt.Errorf("%s: Could not parse x509 certificate: %w", prefix, err)
}
}
return x509Cert, err
}
// IsCertificate returns true in case the given byte array represents an x.509 certificate
func IsCertificate(data []byte) bool {
_, err := ParseCertificate(data, "")
return err == nil
}
// IsGPGPrivateKeyRing returns true in case the given byte array represents a GPG private key ring file
func IsGPGPrivateKeyRing(data []byte) bool {
r := bytes.NewBuffer(data)
_, err := openpgp.ReadKeyRing(r)
return err == nil
}
// SortDecryptionKeys parses a list of comma separated base64 entries and sorts the data into
// a map. Each entry in the list may be either a GPG private key ring, private key, or x.509
// certificate
func SortDecryptionKeys(b64ItemList string) (map[string][][]byte, error) {
dcparameters := make(map[string][][]byte)
for _, b64Item := range strings.Split(b64ItemList, ",") {
var password []byte
b64Data := strings.Split(b64Item, ":")
keyData, err := base64.StdEncoding.DecodeString(b64Data[0])
if err != nil {
return nil, errors.New("Could not base64 decode a passed decryption key")
}
if len(b64Data) == 2 {
password, err = base64.StdEncoding.DecodeString(b64Data[1])
if err != nil {
return nil, errors.New("Could not base64 decode a passed decryption key password")
}
}
var key string
isPrivKey, err := IsPrivateKey(keyData, password)
if IsPasswordError(err) {
return nil, err
}
if isPrivKey {
key = "privkeys"
if _, ok := dcparameters["privkeys-passwords"]; !ok {
dcparameters["privkeys-passwords"] = [][]byte{password}
} else {
dcparameters["privkeys-passwords"] = append(dcparameters["privkeys-passwords"], password)
}
} else if IsCertificate(keyData) {
key = "x509s"
} else if IsGPGPrivateKeyRing(keyData) {
key = "gpg-privatekeys"
}
if key != "" {
values := dcparameters[key]
if values == nil {
dcparameters[key] = [][]byte{keyData}
} else {
dcparameters[key] = append(dcparameters[key], keyData)
}
} else {
return nil, errors.New("Unknown decryption key type")
}
}
return dcparameters, nil
}

2
vendor/github.com/go-jose/go-jose/v3/.gitignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
jose-util/jose-util
jose-util.t.err

53
vendor/github.com/go-jose/go-jose/v3/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,53 @@
# https://github.com/golangci/golangci-lint
run:
skip-files:
- doc_test.go
modules-download-mode: readonly
linters:
enable-all: true
disable:
- gochecknoglobals
- goconst
- lll
- maligned
- nakedret
- scopelint
- unparam
- funlen # added in 1.18 (requires go-jose changes before it can be enabled)
linters-settings:
gocyclo:
min-complexity: 35
issues:
exclude-rules:
- text: "don't use ALL_CAPS in Go names"
linters:
- golint
- text: "hardcoded credentials"
linters:
- gosec
- text: "weak cryptographic primitive"
linters:
- gosec
- path: json/
linters:
- dupl
- errcheck
- gocritic
- gocyclo
- golint
- govet
- ineffassign
- staticcheck
- structcheck
- stylecheck
- unused
- path: _test\.go
linters:
- scopelint
- path: jwk.go
linters:
- gocyclo

33
vendor/github.com/go-jose/go-jose/v3/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,33 @@
language: go
matrix:
fast_finish: true
allow_failures:
- go: tip
go:
- "1.13.x"
- "1.14.x"
- tip
before_script:
- export PATH=$HOME/.local/bin:$PATH
before_install:
- go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
- pip install cram --user
script:
- go test -v -covermode=count -coverprofile=profile.cov .
- go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner
- go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher
- go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt
- go test -v ./json # no coverage for forked encoding/json package
- golangci-lint run
- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util
- cd ..
after_success:
- gocovmerge *.cov */*.cov > merged.coverprofile
- goveralls -coverprofile merged.coverprofile -service=travis-ci

78
vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,78 @@
# v4.0.1
## Fixed
- An attacker could send a JWE containing compressed data that used large
amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
Those functions now return an error if the decompressed data would exceed
250kB or 10x the compressed size (whichever is larger). Thanks to
Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
for reporting.
# v4.0.0
This release makes some breaking changes in order to more thoroughly
address the vulnerabilities discussed in [Three New Attacks Against JSON Web
Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
token".
## Changed
- Limit JWT encryption types (exclude password or public key types) (#78)
- Enforce minimum length for HMAC keys (#85)
- jwt: match any audience in a list, rather than requiring all audiences (#81)
- jwt: accept only Compact Serialization (#75)
- jws: Add expected algorithms for signatures (#74)
- Require specifying expected algorithms for ParseEncrypted,
ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
jwt.ParseSignedAndEncrypted (#69, #74)
- Usually there is a small, known set of appropriate algorithms for a program
to use and it's a mistake to allow unexpected algorithms. For instance the
"billion hash attack" relies in part on programs accepting the PBES2
encryption algorithm and doing the necessary work even if they weren't
specifically configured to allow PBES2.
- Revert "Strip padding off base64 strings" (#82)
- The specs require base64url encoding without padding.
- Minimum supported Go version is now 1.21
## Added
- ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
- These allow parsing a specific serialization, as opposed to ParseSigned and
ParseEncrypted, which try to automatically detect which serialization was
provided. It's common to require a specific serialization for a specific
protocol - for instance JWT requires Compact serialization.
[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
# v3.0.3
## Fixed
- Limit decompression output size to prevent a DoS. Backport from v4.0.1.
# v3.0.2
## Fixed
- DecryptMulti: handle decompression error (#19)
## Changed
- jwe/CompactSerialize: improve performance (#67)
- Increase the default number of PBKDF2 iterations to 600k (#48)
- Return the proper algorithm for ECDSA keys (#45)
## Added
- Add Thumbprint support for opaque signers (#38)
# v3.0.1
## Fixed
- Security issue: an attacker specifying a large "p2c" value can cause
JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
disclosure and to Tom Tervoort for originally publishing the category of attack.
https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf

15
vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md generated vendored Normal file
View File

@ -0,0 +1,15 @@
# Contributing
If you would like to contribute code to go-jose you can do so through GitHub by
forking the repository and sending a pull request.
When submitting code, please make every effort to follow existing conventions
and style in order to keep the code as readable as possible. Please also make
sure all tests pass by running `go test`, and format your code with `go fmt`.
We also recommend using `golint` and `errcheck`.
Before your code can be accepted into the project you must also sign the
Individual Contributor License Agreement. We use [cla-assistant.io][1] and you
will be prompted to sign once a pull request is opened.
[1]: https://cla-assistant.io/

202
vendor/github.com/go-jose/go-jose/v3/LICENSE generated vendored Normal file
View 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 [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

108
vendor/github.com/go-jose/go-jose/v3/README.md generated vendored Normal file
View File

@ -0,0 +1,108 @@
# Go JOSE
### Versions
[Version 4](https://github.com/go-jose/go-jose)
([branch](https://github.com/go-jose/go-jose/),
[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version:
import "github.com/go-jose/go-jose/v4"
The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which
are deprecated.
### Summary
Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. This includes support for JSON Web Encryption,
JSON Web Signature, and JSON Web Token standards.
**Disclaimer**: This library contains encryption software that is subject to
the U.S. Export Administration Regulations. You may not export, re-export,
transfer or download this code or any part of it in violation of any United
States law, directive or regulation. In particular this software may not be
exported or re-exported in any form or on any media to Iran, North Sudan,
Syria, Cuba, or North Korea, or to denied persons or entities mentioned on any
US maintained blocked list.
## Overview
The implementation follows the
[JSON Web Encryption](https://dx.doi.org/10.17487/RFC7516) (RFC 7516),
[JSON Web Signature](https://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
[JSON Web Token](https://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
Tables of supported algorithms are shown below. The library supports both
the compact and JWS/JWE JSON Serialization formats, and has optional support for
multiple recipients. It also comes with a small command-line utility
([`jose-util`](https://pkg.go.dev/github.com/go-jose/go-jose/jose-util))
for dealing with JOSE messages in a shell.
**Note**: We use a forked version of the `encoding/json` package from the Go
standard library which uses case-sensitive matching for member names (instead
of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html)).
This is to avoid differences in interpretation of messages between go-jose and
libraries in other languages.
### Supported algorithms
See below for a table of supported algorithms. Algorithm identifiers match
the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
standard where possible. The Godoc reference has a list of constants.
Key encryption | Algorithm identifier(s)
:------------------------- | :------------------------------
RSA-PKCS#1v1.5 | RSA1_5
RSA-OAEP | RSA-OAEP, RSA-OAEP-256
AES key wrap | A128KW, A192KW, A256KW
AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW
ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
ECDH-ES (direct) | ECDH-ES<sup>1</sup>
Direct encryption | dir<sup>1</sup>
<sup>1. Not supported in multi-recipient mode</sup>
Signing / MAC | Algorithm identifier(s)
:------------------------- | :------------------------------
RSASSA-PKCS#1v1.5 | RS256, RS384, RS512
RSASSA-PSS | PS256, PS384, PS512
HMAC | HS256, HS384, HS512
ECDSA | ES256, ES384, ES512
Ed25519 | EdDSA<sup>2</sup>
<sup>2. Only available in version 2 of the package</sup>
Content encryption | Algorithm identifier(s)
:------------------------- | :------------------------------
AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
AES-GCM | A128GCM, A192GCM, A256GCM
Compression | Algorithm identifiers(s)
:------------------------- | -------------------------------
DEFLATE (RFC 1951) | DEF
### Supported key types
See below for a table of supported key types. These are understood by the
library, and can be passed to corresponding functions such as `NewEncrypter` or
`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which
allows attaching a key id.
Algorithm(s) | Corresponding types
:------------------------- | -------------------------------
RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)
ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey)
AES, HMAC | []byte
<sup>1. Only available in version 2 or later of the package</sup>
## Examples
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3)
[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3/jwt)
Examples can be found in the Godoc
reference for this package. The
[`jose-util`](https://github.com/go-jose/go-jose/tree/v3/jose-util)
subdirectory also contains a small command-line utility which might be useful
as an example as well.

13
vendor/github.com/go-jose/go-jose/v3/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,13 @@
# Security Policy
This document explains how to contact the Let's Encrypt security team to report security vulnerabilities.
## Supported Versions
| Version | Supported |
| ------- | ----------|
| >= v3 | &check; |
| v2 | &cross; |
| v1 | &cross; |
## Reporting a vulnerability
Please see [https://letsencrypt.org/contact/#security](https://letsencrypt.org/contact/#security) for the email address to report a vulnerability. Ensure that the subject line for your report contains the word `vulnerability` and is descriptive. Your email should be acknowledged within 24 hours. If you do not receive a response within 24 hours, please follow-up again with another email.

595
vendor/github.com/go-jose/go-jose/v3/asymmetric.go generated vendored Normal file
View File

@ -0,0 +1,595 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"crypto"
"crypto/aes"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"errors"
"fmt"
"math/big"
josecipher "github.com/go-jose/go-jose/v3/cipher"
"github.com/go-jose/go-jose/v3/json"
)
// A generic RSA-based encrypter/verifier
type rsaEncrypterVerifier struct {
publicKey *rsa.PublicKey
}
// A generic RSA-based decrypter/signer
type rsaDecrypterSigner struct {
privateKey *rsa.PrivateKey
}
// A generic EC-based encrypter/verifier
type ecEncrypterVerifier struct {
publicKey *ecdsa.PublicKey
}
type edEncrypterVerifier struct {
publicKey ed25519.PublicKey
}
// A key generator for ECDH-ES
type ecKeyGenerator struct {
size int
algID string
publicKey *ecdsa.PublicKey
}
// A generic EC-based decrypter/signer
type ecDecrypterSigner struct {
privateKey *ecdsa.PrivateKey
}
type edDecrypterSigner struct {
privateKey ed25519.PrivateKey
}
// newRSARecipient creates recipientKeyInfo based on the given key.
func newRSARecipient(keyAlg KeyAlgorithm, publicKey *rsa.PublicKey) (recipientKeyInfo, error) {
// Verify that key management algorithm is supported by this encrypter
switch keyAlg {
case RSA1_5, RSA_OAEP, RSA_OAEP_256:
default:
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
}
if publicKey == nil {
return recipientKeyInfo{}, errors.New("invalid public key")
}
return recipientKeyInfo{
keyAlg: keyAlg,
keyEncrypter: &rsaEncrypterVerifier{
publicKey: publicKey,
},
}, nil
}
// newRSASigner creates a recipientSigInfo based on the given key.
func newRSASigner(sigAlg SignatureAlgorithm, privateKey *rsa.PrivateKey) (recipientSigInfo, error) {
// Verify that key management algorithm is supported by this encrypter
switch sigAlg {
case RS256, RS384, RS512, PS256, PS384, PS512:
default:
return recipientSigInfo{}, ErrUnsupportedAlgorithm
}
if privateKey == nil {
return recipientSigInfo{}, errors.New("invalid private key")
}
return recipientSigInfo{
sigAlg: sigAlg,
publicKey: staticPublicKey(&JSONWebKey{
Key: privateKey.Public(),
}),
signer: &rsaDecrypterSigner{
privateKey: privateKey,
},
}, nil
}
func newEd25519Signer(sigAlg SignatureAlgorithm, privateKey ed25519.PrivateKey) (recipientSigInfo, error) {
if sigAlg != EdDSA {
return recipientSigInfo{}, ErrUnsupportedAlgorithm
}
if privateKey == nil {
return recipientSigInfo{}, errors.New("invalid private key")
}
return recipientSigInfo{
sigAlg: sigAlg,
publicKey: staticPublicKey(&JSONWebKey{
Key: privateKey.Public(),
}),
signer: &edDecrypterSigner{
privateKey: privateKey,
},
}, nil
}
// newECDHRecipient creates recipientKeyInfo based on the given key.
func newECDHRecipient(keyAlg KeyAlgorithm, publicKey *ecdsa.PublicKey) (recipientKeyInfo, error) {
// Verify that key management algorithm is supported by this encrypter
switch keyAlg {
case ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
default:
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
}
if publicKey == nil || !publicKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
return recipientKeyInfo{}, errors.New("invalid public key")
}
return recipientKeyInfo{
keyAlg: keyAlg,
keyEncrypter: &ecEncrypterVerifier{
publicKey: publicKey,
},
}, nil
}
// newECDSASigner creates a recipientSigInfo based on the given key.
func newECDSASigner(sigAlg SignatureAlgorithm, privateKey *ecdsa.PrivateKey) (recipientSigInfo, error) {
// Verify that key management algorithm is supported by this encrypter
switch sigAlg {
case ES256, ES384, ES512:
default:
return recipientSigInfo{}, ErrUnsupportedAlgorithm
}
if privateKey == nil {
return recipientSigInfo{}, errors.New("invalid private key")
}
return recipientSigInfo{
sigAlg: sigAlg,
publicKey: staticPublicKey(&JSONWebKey{
Key: privateKey.Public(),
}),
signer: &ecDecrypterSigner{
privateKey: privateKey,
},
}, nil
}
// Encrypt the given payload and update the object.
func (ctx rsaEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
encryptedKey, err := ctx.encrypt(cek, alg)
if err != nil {
return recipientInfo{}, err
}
return recipientInfo{
encryptedKey: encryptedKey,
header: &rawHeader{},
}, nil
}
// Encrypt the given payload. Based on the key encryption algorithm,
// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
func (ctx rsaEncrypterVerifier) encrypt(cek []byte, alg KeyAlgorithm) ([]byte, error) {
switch alg {
case RSA1_5:
return rsa.EncryptPKCS1v15(RandReader, ctx.publicKey, cek)
case RSA_OAEP:
return rsa.EncryptOAEP(sha1.New(), RandReader, ctx.publicKey, cek, []byte{})
case RSA_OAEP_256:
return rsa.EncryptOAEP(sha256.New(), RandReader, ctx.publicKey, cek, []byte{})
}
return nil, ErrUnsupportedAlgorithm
}
// Decrypt the given payload and return the content encryption key.
func (ctx rsaDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
return ctx.decrypt(recipient.encryptedKey, headers.getAlgorithm(), generator)
}
// Decrypt the given payload. Based on the key encryption algorithm,
// this will either use RSA-PKCS1v1.5 or RSA-OAEP (with SHA-1 or SHA-256).
func (ctx rsaDecrypterSigner) decrypt(jek []byte, alg KeyAlgorithm, generator keyGenerator) ([]byte, error) {
// Note: The random reader on decrypt operations is only used for blinding,
// so stubbing is meanlingless (hence the direct use of rand.Reader).
switch alg {
case RSA1_5:
defer func() {
// DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
// because of an index out of bounds error, which we want to ignore.
// This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
// only exists for preventing crashes with unpatched versions.
// See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
// See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
_ = recover()
}()
// Perform some input validation.
keyBytes := ctx.privateKey.PublicKey.N.BitLen() / 8
if keyBytes != len(jek) {
// Input size is incorrect, the encrypted payload should always match
// the size of the public modulus (e.g. using a 2048 bit key will
// produce 256 bytes of output). Reject this since it's invalid input.
return nil, ErrCryptoFailure
}
cek, _, err := generator.genKey()
if err != nil {
return nil, ErrCryptoFailure
}
// When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
// prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
// the Million Message Attack on Cryptographic Message Syntax". We are
// therefore deliberately ignoring errors here.
_ = rsa.DecryptPKCS1v15SessionKey(rand.Reader, ctx.privateKey, jek, cek)
return cek, nil
case RSA_OAEP:
// Use rand.Reader for RSA blinding
return rsa.DecryptOAEP(sha1.New(), rand.Reader, ctx.privateKey, jek, []byte{})
case RSA_OAEP_256:
// Use rand.Reader for RSA blinding
return rsa.DecryptOAEP(sha256.New(), rand.Reader, ctx.privateKey, jek, []byte{})
}
return nil, ErrUnsupportedAlgorithm
}
// Sign the given payload
func (ctx rsaDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
var hash crypto.Hash
switch alg {
case RS256, PS256:
hash = crypto.SHA256
case RS384, PS384:
hash = crypto.SHA384
case RS512, PS512:
hash = crypto.SHA512
default:
return Signature{}, ErrUnsupportedAlgorithm
}
hasher := hash.New()
// According to documentation, Write() on hash never fails
_, _ = hasher.Write(payload)
hashed := hasher.Sum(nil)
var out []byte
var err error
switch alg {
case RS256, RS384, RS512:
// TODO(https://github.com/go-jose/go-jose/issues/40): As of go1.20, the
// random parameter is legacy and ignored, and it can be nil.
// https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/crypto/rsa/pkcs1v15.go;l=263;bpv=0;bpt=1
out, err = rsa.SignPKCS1v15(RandReader, ctx.privateKey, hash, hashed)
case PS256, PS384, PS512:
out, err = rsa.SignPSS(RandReader, ctx.privateKey, hash, hashed, &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
})
}
if err != nil {
return Signature{}, err
}
return Signature{
Signature: out,
protected: &rawHeader{},
}, nil
}
// Verify the given payload
func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
var hash crypto.Hash
switch alg {
case RS256, PS256:
hash = crypto.SHA256
case RS384, PS384:
hash = crypto.SHA384
case RS512, PS512:
hash = crypto.SHA512
default:
return ErrUnsupportedAlgorithm
}
hasher := hash.New()
// According to documentation, Write() on hash never fails
_, _ = hasher.Write(payload)
hashed := hasher.Sum(nil)
switch alg {
case RS256, RS384, RS512:
return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
case PS256, PS384, PS512:
return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
}
return ErrUnsupportedAlgorithm
}
// Encrypt the given payload and update the object.
func (ctx ecEncrypterVerifier) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
switch alg {
case ECDH_ES:
// ECDH-ES mode doesn't wrap a key, the shared secret is used directly as the key.
return recipientInfo{
header: &rawHeader{},
}, nil
case ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW:
default:
return recipientInfo{}, ErrUnsupportedAlgorithm
}
generator := ecKeyGenerator{
algID: string(alg),
publicKey: ctx.publicKey,
}
switch alg {
case ECDH_ES_A128KW:
generator.size = 16
case ECDH_ES_A192KW:
generator.size = 24
case ECDH_ES_A256KW:
generator.size = 32
}
kek, header, err := generator.genKey()
if err != nil {
return recipientInfo{}, err
}
block, err := aes.NewCipher(kek)
if err != nil {
return recipientInfo{}, err
}
jek, err := josecipher.KeyWrap(block, cek)
if err != nil {
return recipientInfo{}, err
}
return recipientInfo{
encryptedKey: jek,
header: &header,
}, nil
}
// Get key size for EC key generator
func (ctx ecKeyGenerator) keySize() int {
return ctx.size
}
// Get a content encryption key for ECDH-ES
func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
priv, err := ecdsa.GenerateKey(ctx.publicKey.Curve, RandReader)
if err != nil {
return nil, rawHeader{}, err
}
out := josecipher.DeriveECDHES(ctx.algID, []byte{}, []byte{}, priv, ctx.publicKey, ctx.size)
b, err := json.Marshal(&JSONWebKey{
Key: &priv.PublicKey,
})
if err != nil {
return nil, nil, err
}
headers := rawHeader{
headerEPK: makeRawMessage(b),
}
return out, headers, nil
}
// Decrypt the given payload and return the content encryption key.
func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
epk, err := headers.getEPK()
if err != nil {
return nil, errors.New("go-jose/go-jose: invalid epk header")
}
if epk == nil {
return nil, errors.New("go-jose/go-jose: missing epk header")
}
publicKey, ok := epk.Key.(*ecdsa.PublicKey)
if publicKey == nil || !ok {
return nil, errors.New("go-jose/go-jose: invalid epk header")
}
if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
return nil, errors.New("go-jose/go-jose: invalid public key in epk header")
}
apuData, err := headers.getAPU()
if err != nil {
return nil, errors.New("go-jose/go-jose: invalid apu header")
}
apvData, err := headers.getAPV()
if err != nil {
return nil, errors.New("go-jose/go-jose: invalid apv header")
}
deriveKey := func(algID string, size int) []byte {
return josecipher.DeriveECDHES(algID, apuData.bytes(), apvData.bytes(), ctx.privateKey, publicKey, size)
}
var keySize int
algorithm := headers.getAlgorithm()
switch algorithm {
case ECDH_ES:
// ECDH-ES uses direct key agreement, no key unwrapping necessary.
return deriveKey(string(headers.getEncryption()), generator.keySize()), nil
case ECDH_ES_A128KW:
keySize = 16
case ECDH_ES_A192KW:
keySize = 24
case ECDH_ES_A256KW:
keySize = 32
default:
return nil, ErrUnsupportedAlgorithm
}
key := deriveKey(string(algorithm), keySize)
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
return josecipher.KeyUnwrap(block, recipient.encryptedKey)
}
func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
if alg != EdDSA {
return Signature{}, ErrUnsupportedAlgorithm
}
sig, err := ctx.privateKey.Sign(RandReader, payload, crypto.Hash(0))
if err != nil {
return Signature{}, err
}
return Signature{
Signature: sig,
protected: &rawHeader{},
}, nil
}
func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
if alg != EdDSA {
return ErrUnsupportedAlgorithm
}
ok := ed25519.Verify(ctx.publicKey, payload, signature)
if !ok {
return errors.New("go-jose/go-jose: ed25519 signature failed to verify")
}
return nil
}
// Sign the given payload
func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
var expectedBitSize int
var hash crypto.Hash
switch alg {
case ES256:
expectedBitSize = 256
hash = crypto.SHA256
case ES384:
expectedBitSize = 384
hash = crypto.SHA384
case ES512:
expectedBitSize = 521
hash = crypto.SHA512
}
curveBits := ctx.privateKey.Curve.Params().BitSize
if expectedBitSize != curveBits {
return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
}
hasher := hash.New()
// According to documentation, Write() on hash never fails
_, _ = hasher.Write(payload)
hashed := hasher.Sum(nil)
r, s, err := ecdsa.Sign(RandReader, ctx.privateKey, hashed)
if err != nil {
return Signature{}, err
}
keyBytes := curveBits / 8
if curveBits%8 > 0 {
keyBytes++
}
// We serialize the outputs (r and s) into big-endian byte arrays and pad
// them with zeros on the left to make sure the sizes work out. Both arrays
// must be keyBytes long, and the output must be 2*keyBytes long.
rBytes := r.Bytes()
rBytesPadded := make([]byte, keyBytes)
copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
sBytes := s.Bytes()
sBytesPadded := make([]byte, keyBytes)
copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
out := append(rBytesPadded, sBytesPadded...)
return Signature{
Signature: out,
protected: &rawHeader{},
}, nil
}
// Verify the given payload
func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
var keySize int
var hash crypto.Hash
switch alg {
case ES256:
keySize = 32
hash = crypto.SHA256
case ES384:
keySize = 48
hash = crypto.SHA384
case ES512:
keySize = 66
hash = crypto.SHA512
default:
return ErrUnsupportedAlgorithm
}
if len(signature) != 2*keySize {
return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
}
hasher := hash.New()
// According to documentation, Write() on hash never fails
_, _ = hasher.Write(payload)
hashed := hasher.Sum(nil)
r := big.NewInt(0).SetBytes(signature[:keySize])
s := big.NewInt(0).SetBytes(signature[keySize:])
match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
if !match {
return errors.New("go-jose/go-jose: ecdsa signature failed to verify")
}
return nil
}

196
vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go generated vendored Normal file
View File

@ -0,0 +1,196 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 josecipher
import (
"bytes"
"crypto/cipher"
"crypto/hmac"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"encoding/binary"
"errors"
"hash"
)
const (
nonceBytes = 16
)
// NewCBCHMAC instantiates a new AEAD based on CBC+HMAC.
func NewCBCHMAC(key []byte, newBlockCipher func([]byte) (cipher.Block, error)) (cipher.AEAD, error) {
keySize := len(key) / 2
integrityKey := key[:keySize]
encryptionKey := key[keySize:]
blockCipher, err := newBlockCipher(encryptionKey)
if err != nil {
return nil, err
}
var hash func() hash.Hash
switch keySize {
case 16:
hash = sha256.New
case 24:
hash = sha512.New384
case 32:
hash = sha512.New
}
return &cbcAEAD{
hash: hash,
blockCipher: blockCipher,
authtagBytes: keySize,
integrityKey: integrityKey,
}, nil
}
// An AEAD based on CBC+HMAC
type cbcAEAD struct {
hash func() hash.Hash
authtagBytes int
integrityKey []byte
blockCipher cipher.Block
}
func (ctx *cbcAEAD) NonceSize() int {
return nonceBytes
}
func (ctx *cbcAEAD) Overhead() int {
// Maximum overhead is block size (for padding) plus auth tag length, where
// the length of the auth tag is equivalent to the key size.
return ctx.blockCipher.BlockSize() + ctx.authtagBytes
}
// Seal encrypts and authenticates the plaintext.
func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
// Output buffer -- must take care not to mangle plaintext input.
ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)]
copy(ciphertext, plaintext)
ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize())
cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce)
cbc.CryptBlocks(ciphertext, ciphertext)
authtag := ctx.computeAuthTag(data, nonce, ciphertext)
ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag)))
copy(out, ciphertext)
copy(out[len(ciphertext):], authtag)
return ret
}
// Open decrypts and authenticates the ciphertext.
func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(ciphertext) < ctx.authtagBytes {
return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)")
}
offset := len(ciphertext) - ctx.authtagBytes
expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
if match != 1 {
return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)")
}
cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)
// Make copy of ciphertext buffer, don't want to modify in place
buffer := append([]byte{}, ciphertext[:offset]...)
if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)")
}
cbc.CryptBlocks(buffer, buffer)
// Remove padding
plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())
if err != nil {
return nil, err
}
ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext)))
copy(out, plaintext)
return ret, nil
}
// Compute an authentication tag
func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte {
buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8)
n := 0
n += copy(buffer, aad)
n += copy(buffer[n:], nonce)
n += copy(buffer[n:], ciphertext)
binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8)
// According to documentation, Write() on hash.Hash never fails.
hmac := hmac.New(ctx.hash, ctx.integrityKey)
_, _ = hmac.Write(buffer)
return hmac.Sum(nil)[:ctx.authtagBytes]
}
// resize ensures that the given slice has a capacity of at least n bytes.
// If the capacity of the slice is less than n, a new slice is allocated
// and the existing data will be copied.
func resize(in []byte, n uint64) (head, tail []byte) {
if uint64(cap(in)) >= n {
head = in[:n]
} else {
head = make([]byte, n)
copy(head, in)
}
tail = head[len(in):]
return
}
// Apply padding
func padBuffer(buffer []byte, blockSize int) []byte {
missing := blockSize - (len(buffer) % blockSize)
ret, out := resize(buffer, uint64(len(buffer))+uint64(missing))
padding := bytes.Repeat([]byte{byte(missing)}, missing)
copy(out, padding)
return ret
}
// Remove padding
func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {
if len(buffer)%blockSize != 0 {
return nil, errors.New("go-jose/go-jose: invalid padding")
}
last := buffer[len(buffer)-1]
count := int(last)
if count == 0 || count > blockSize || count > len(buffer) {
return nil, errors.New("go-jose/go-jose: invalid padding")
}
padding := bytes.Repeat([]byte{last}, count)
if !bytes.HasSuffix(buffer, padding) {
return nil, errors.New("go-jose/go-jose: invalid padding")
}
return buffer[:len(buffer)-count], nil
}

View File

@ -0,0 +1,75 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 josecipher
import (
"crypto"
"encoding/binary"
"hash"
"io"
)
type concatKDF struct {
z, info []byte
i uint32
cache []byte
hasher hash.Hash
}
// NewConcatKDF builds a KDF reader based on the given inputs.
func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader {
buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo)))
n := 0
n += copy(buffer, algID)
n += copy(buffer[n:], ptyUInfo)
n += copy(buffer[n:], ptyVInfo)
n += copy(buffer[n:], supPubInfo)
copy(buffer[n:], supPrivInfo)
hasher := hash.New()
return &concatKDF{
z: z,
info: buffer,
hasher: hasher,
cache: []byte{},
i: 1,
}
}
func (ctx *concatKDF) Read(out []byte) (int, error) {
copied := copy(out, ctx.cache)
ctx.cache = ctx.cache[copied:]
for copied < len(out) {
ctx.hasher.Reset()
// Write on a hash.Hash never fails
_ = binary.Write(ctx.hasher, binary.BigEndian, ctx.i)
_, _ = ctx.hasher.Write(ctx.z)
_, _ = ctx.hasher.Write(ctx.info)
hash := ctx.hasher.Sum(nil)
chunkCopied := copy(out[copied:], hash)
copied += chunkCopied
ctx.cache = hash[chunkCopied:]
ctx.i++
}
return copied, nil
}

86
vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go generated vendored Normal file
View File

@ -0,0 +1,86 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 josecipher
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"encoding/binary"
)
// DeriveECDHES derives a shared encryption key using ECDH/ConcatKDF as described in JWE/JWA.
// It is an error to call this function with a private/public key that are not on the same
// curve. Callers must ensure that the keys are valid before calling this function. Output
// size may be at most 1<<16 bytes (64 KiB).
func DeriveECDHES(alg string, apuData, apvData []byte, priv *ecdsa.PrivateKey, pub *ecdsa.PublicKey, size int) []byte {
if size > 1<<16 {
panic("ECDH-ES output size too large, must be less than or equal to 1<<16")
}
// algId, partyUInfo, partyVInfo inputs must be prefixed with the length
algID := lengthPrefixed([]byte(alg))
ptyUInfo := lengthPrefixed(apuData)
ptyVInfo := lengthPrefixed(apvData)
// suppPubInfo is the encoded length of the output size in bits
supPubInfo := make([]byte, 4)
binary.BigEndian.PutUint32(supPubInfo, uint32(size)*8)
if !priv.PublicKey.Curve.IsOnCurve(pub.X, pub.Y) {
panic("public key not on same curve as private key")
}
z, _ := priv.Curve.ScalarMult(pub.X, pub.Y, priv.D.Bytes())
zBytes := z.Bytes()
// Note that calling z.Bytes() on a big.Int may strip leading zero bytes from
// the returned byte array. This can lead to a problem where zBytes will be
// shorter than expected which breaks the key derivation. Therefore we must pad
// to the full length of the expected coordinate here before calling the KDF.
octSize := dSize(priv.Curve)
if len(zBytes) != octSize {
zBytes = append(bytes.Repeat([]byte{0}, octSize-len(zBytes)), zBytes...)
}
reader := NewConcatKDF(crypto.SHA256, zBytes, algID, ptyUInfo, ptyVInfo, supPubInfo, []byte{})
key := make([]byte, size)
// Read on the KDF will never fail
_, _ = reader.Read(key)
return key
}
// dSize returns the size in octets for a coordinate on a elliptic curve.
func dSize(curve elliptic.Curve) int {
order := curve.Params().P
bitLen := order.BitLen()
size := bitLen / 8
if bitLen%8 != 0 {
size++
}
return size
}
func lengthPrefixed(data []byte) []byte {
out := make([]byte, len(data)+4)
binary.BigEndian.PutUint32(out, uint32(len(data)))
copy(out[4:], data)
return out
}

109
vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go generated vendored Normal file
View File

@ -0,0 +1,109 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 josecipher
import (
"crypto/cipher"
"crypto/subtle"
"encoding/binary"
"errors"
)
var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}
// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.
func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
if len(cek)%8 != 0 {
return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
}
n := len(cek) / 8
r := make([][]byte, n)
for i := range r {
r[i] = make([]byte, 8)
copy(r[i], cek[i*8:])
}
buffer := make([]byte, 16)
tBytes := make([]byte, 8)
copy(buffer, defaultIV)
for t := 0; t < 6*n; t++ {
copy(buffer[8:], r[t%n])
block.Encrypt(buffer, buffer)
binary.BigEndian.PutUint64(tBytes, uint64(t+1))
for i := 0; i < 8; i++ {
buffer[i] ^= tBytes[i]
}
copy(r[t%n], buffer[8:])
}
out := make([]byte, (n+1)*8)
copy(out, buffer[:8])
for i := range r {
copy(out[(i+1)*8:], r[i])
}
return out, nil
}
// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.
func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
if len(ciphertext)%8 != 0 {
return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
}
n := (len(ciphertext) / 8) - 1
r := make([][]byte, n)
for i := range r {
r[i] = make([]byte, 8)
copy(r[i], ciphertext[(i+1)*8:])
}
buffer := make([]byte, 16)
tBytes := make([]byte, 8)
copy(buffer[:8], ciphertext[:8])
for t := 6*n - 1; t >= 0; t-- {
binary.BigEndian.PutUint64(tBytes, uint64(t+1))
for i := 0; i < 8; i++ {
buffer[i] ^= tBytes[i]
}
copy(buffer[8:], r[t%n])
block.Decrypt(buffer, buffer)
copy(r[t%n], buffer[8:])
}
if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {
return nil, errors.New("go-jose/go-jose: failed to unwrap key")
}
out := make([]byte, n*8)
for i := range r {
copy(out[i*8:], r[i])
}
return out, nil
}

593
vendor/github.com/go-jose/go-jose/v3/crypter.go generated vendored Normal file
View File

@ -0,0 +1,593 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"crypto/ecdsa"
"crypto/rsa"
"errors"
"fmt"
"github.com/go-jose/go-jose/v3/json"
)
// Encrypter represents an encrypter which produces an encrypted JWE object.
type Encrypter interface {
Encrypt(plaintext []byte) (*JSONWebEncryption, error)
EncryptWithAuthData(plaintext []byte, aad []byte) (*JSONWebEncryption, error)
Options() EncrypterOptions
}
// A generic content cipher
type contentCipher interface {
keySize() int
encrypt(cek []byte, aad, plaintext []byte) (*aeadParts, error)
decrypt(cek []byte, aad []byte, parts *aeadParts) ([]byte, error)
}
// A key generator (for generating/getting a CEK)
type keyGenerator interface {
keySize() int
genKey() ([]byte, rawHeader, error)
}
// A generic key encrypter
type keyEncrypter interface {
encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) // Encrypt a key
}
// A generic key decrypter
type keyDecrypter interface {
decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) // Decrypt a key
}
// A generic encrypter based on the given key encrypter and content cipher.
type genericEncrypter struct {
contentAlg ContentEncryption
compressionAlg CompressionAlgorithm
cipher contentCipher
recipients []recipientKeyInfo
keyGenerator keyGenerator
extraHeaders map[HeaderKey]interface{}
}
type recipientKeyInfo struct {
keyID string
keyAlg KeyAlgorithm
keyEncrypter keyEncrypter
}
// EncrypterOptions represents options that can be set on new encrypters.
type EncrypterOptions struct {
Compression CompressionAlgorithm
// Optional map of name/value pairs to be inserted into the protected
// header of a JWS object. Some specifications which make use of
// JWS require additional values here.
//
// Values will be serialized by [json.Marshal] and must be valid inputs to
// that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
ExtraHeaders map[HeaderKey]interface{}
}
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
// if necessary, and returns the updated EncrypterOptions.
//
// The v parameter will be serialized by [json.Marshal] and must be a valid
// input to that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
func (eo *EncrypterOptions) WithHeader(k HeaderKey, v interface{}) *EncrypterOptions {
if eo.ExtraHeaders == nil {
eo.ExtraHeaders = map[HeaderKey]interface{}{}
}
eo.ExtraHeaders[k] = v
return eo
}
// WithContentType adds a content type ("cty") header and returns the updated
// EncrypterOptions.
func (eo *EncrypterOptions) WithContentType(contentType ContentType) *EncrypterOptions {
return eo.WithHeader(HeaderContentType, contentType)
}
// WithType adds a type ("typ") header and returns the updated EncrypterOptions.
func (eo *EncrypterOptions) WithType(typ ContentType) *EncrypterOptions {
return eo.WithHeader(HeaderType, typ)
}
// Recipient represents an algorithm/key to encrypt messages to.
//
// PBES2Count and PBES2Salt correspond with the "p2c" and "p2s" headers used
// on the password-based encryption algorithms PBES2-HS256+A128KW,
// PBES2-HS384+A192KW, and PBES2-HS512+A256KW. If they are not provided a safe
// default of 100000 will be used for the count and a 128-bit random salt will
// be generated.
type Recipient struct {
Algorithm KeyAlgorithm
// Key must have one of these types:
// - ed25519.PublicKey
// - *ecdsa.PublicKey
// - *rsa.PublicKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (a symmetric key)
// - Any type that satisfies the OpaqueKeyEncrypter interface
//
// The type of Key must match the value of Algorithm.
Key interface{}
KeyID string
PBES2Count int
PBES2Salt []byte
}
// NewEncrypter creates an appropriate encrypter based on the key type
func NewEncrypter(enc ContentEncryption, rcpt Recipient, opts *EncrypterOptions) (Encrypter, error) {
encrypter := &genericEncrypter{
contentAlg: enc,
recipients: []recipientKeyInfo{},
cipher: getContentCipher(enc),
}
if opts != nil {
encrypter.compressionAlg = opts.Compression
encrypter.extraHeaders = opts.ExtraHeaders
}
if encrypter.cipher == nil {
return nil, ErrUnsupportedAlgorithm
}
var keyID string
var rawKey interface{}
switch encryptionKey := rcpt.Key.(type) {
case JSONWebKey:
keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
case *JSONWebKey:
keyID, rawKey = encryptionKey.KeyID, encryptionKey.Key
case OpaqueKeyEncrypter:
keyID, rawKey = encryptionKey.KeyID(), encryptionKey
default:
rawKey = encryptionKey
}
switch rcpt.Algorithm {
case DIRECT:
// Direct encryption mode must be treated differently
keyBytes, ok := rawKey.([]byte)
if !ok {
return nil, ErrUnsupportedKeyType
}
if encrypter.cipher.keySize() != len(keyBytes) {
return nil, ErrInvalidKeySize
}
encrypter.keyGenerator = staticKeyGenerator{
key: keyBytes,
}
recipientInfo, _ := newSymmetricRecipient(rcpt.Algorithm, keyBytes)
recipientInfo.keyID = keyID
if rcpt.KeyID != "" {
recipientInfo.keyID = rcpt.KeyID
}
encrypter.recipients = []recipientKeyInfo{recipientInfo}
return encrypter, nil
case ECDH_ES:
// ECDH-ES (w/o key wrapping) is similar to DIRECT mode
keyDSA, ok := rawKey.(*ecdsa.PublicKey)
if !ok {
return nil, ErrUnsupportedKeyType
}
encrypter.keyGenerator = ecKeyGenerator{
size: encrypter.cipher.keySize(),
algID: string(enc),
publicKey: keyDSA,
}
recipientInfo, _ := newECDHRecipient(rcpt.Algorithm, keyDSA)
recipientInfo.keyID = keyID
if rcpt.KeyID != "" {
recipientInfo.keyID = rcpt.KeyID
}
encrypter.recipients = []recipientKeyInfo{recipientInfo}
return encrypter, nil
default:
// Can just add a standard recipient
encrypter.keyGenerator = randomKeyGenerator{
size: encrypter.cipher.keySize(),
}
err := encrypter.addRecipient(rcpt)
return encrypter, err
}
}
// NewMultiEncrypter creates a multi-encrypter based on the given parameters
func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *EncrypterOptions) (Encrypter, error) {
cipher := getContentCipher(enc)
if cipher == nil {
return nil, ErrUnsupportedAlgorithm
}
if len(rcpts) == 0 {
return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty")
}
encrypter := &genericEncrypter{
contentAlg: enc,
recipients: []recipientKeyInfo{},
cipher: cipher,
keyGenerator: randomKeyGenerator{
size: cipher.keySize(),
},
}
if opts != nil {
encrypter.compressionAlg = opts.Compression
encrypter.extraHeaders = opts.ExtraHeaders
}
for _, recipient := range rcpts {
err := encrypter.addRecipient(recipient)
if err != nil {
return nil, err
}
}
return encrypter, nil
}
func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) {
var recipientInfo recipientKeyInfo
switch recipient.Algorithm {
case DIRECT, ECDH_ES:
return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm)
}
recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key)
if recipient.KeyID != "" {
recipientInfo.keyID = recipient.KeyID
}
switch recipient.Algorithm {
case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
if sr, ok := recipientInfo.keyEncrypter.(*symmetricKeyCipher); ok {
sr.p2c = recipient.PBES2Count
sr.p2s = recipient.PBES2Salt
}
}
if err == nil {
ctx.recipients = append(ctx.recipients, recipientInfo)
}
return err
}
func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKeyInfo, error) {
switch encryptionKey := encryptionKey.(type) {
case *rsa.PublicKey:
return newRSARecipient(alg, encryptionKey)
case *ecdsa.PublicKey:
return newECDHRecipient(alg, encryptionKey)
case []byte:
return newSymmetricRecipient(alg, encryptionKey)
case string:
return newSymmetricRecipient(alg, []byte(encryptionKey))
case *JSONWebKey:
recipient, err := makeJWERecipient(alg, encryptionKey.Key)
recipient.keyID = encryptionKey.KeyID
return recipient, err
case OpaqueKeyEncrypter:
return newOpaqueKeyEncrypter(alg, encryptionKey)
}
return recipientKeyInfo{}, ErrUnsupportedKeyType
}
// newDecrypter creates an appropriate decrypter based on the key type
func newDecrypter(decryptionKey interface{}) (keyDecrypter, error) {
switch decryptionKey := decryptionKey.(type) {
case *rsa.PrivateKey:
return &rsaDecrypterSigner{
privateKey: decryptionKey,
}, nil
case *ecdsa.PrivateKey:
return &ecDecrypterSigner{
privateKey: decryptionKey,
}, nil
case []byte:
return &symmetricKeyCipher{
key: decryptionKey,
}, nil
case string:
return &symmetricKeyCipher{
key: []byte(decryptionKey),
}, nil
case JSONWebKey:
return newDecrypter(decryptionKey.Key)
case *JSONWebKey:
return newDecrypter(decryptionKey.Key)
case OpaqueKeyDecrypter:
return &opaqueKeyDecrypter{decrypter: decryptionKey}, nil
default:
return nil, ErrUnsupportedKeyType
}
}
// Implementation of encrypt method producing a JWE object.
func (ctx *genericEncrypter) Encrypt(plaintext []byte) (*JSONWebEncryption, error) {
return ctx.EncryptWithAuthData(plaintext, nil)
}
// Implementation of encrypt method producing a JWE object.
func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryption, error) {
obj := &JSONWebEncryption{}
obj.aad = aad
obj.protected = &rawHeader{}
err := obj.protected.set(headerEncryption, ctx.contentAlg)
if err != nil {
return nil, err
}
obj.recipients = make([]recipientInfo, len(ctx.recipients))
if len(ctx.recipients) == 0 {
return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to")
}
cek, headers, err := ctx.keyGenerator.genKey()
if err != nil {
return nil, err
}
obj.protected.merge(&headers)
for i, info := range ctx.recipients {
recipient, err := info.keyEncrypter.encryptKey(cek, info.keyAlg)
if err != nil {
return nil, err
}
err = recipient.header.set(headerAlgorithm, info.keyAlg)
if err != nil {
return nil, err
}
if info.keyID != "" {
err = recipient.header.set(headerKeyID, info.keyID)
if err != nil {
return nil, err
}
}
obj.recipients[i] = recipient
}
if len(ctx.recipients) == 1 {
// Move per-recipient headers into main protected header if there's
// only a single recipient.
obj.protected.merge(obj.recipients[0].header)
obj.recipients[0].header = nil
}
if ctx.compressionAlg != NONE {
plaintext, err = compress(ctx.compressionAlg, plaintext)
if err != nil {
return nil, err
}
err = obj.protected.set(headerCompression, ctx.compressionAlg)
if err != nil {
return nil, err
}
}
for k, v := range ctx.extraHeaders {
b, err := json.Marshal(v)
if err != nil {
return nil, err
}
(*obj.protected)[k] = makeRawMessage(b)
}
authData := obj.computeAuthData()
parts, err := ctx.cipher.encrypt(cek, authData, plaintext)
if err != nil {
return nil, err
}
obj.iv = parts.iv
obj.ciphertext = parts.ciphertext
obj.tag = parts.tag
return obj, nil
}
func (ctx *genericEncrypter) Options() EncrypterOptions {
return EncrypterOptions{
Compression: ctx.compressionAlg,
ExtraHeaders: ctx.extraHeaders,
}
}
// Decrypt and validate the object and return the plaintext. This
// function does not support multi-recipient. If you desire multi-recipient
// decryption use DecryptMulti instead.
//
// The decryptionKey argument must contain a private or symmetric key
// and must have one of these types:
// - *ecdsa.PrivateKey
// - *rsa.PrivateKey
// - *JSONWebKey
// - JSONWebKey
// - *JSONWebKeySet
// - JSONWebKeySet
// - []byte (a symmetric key)
// - string (a symmetric key)
// - Any type that satisfies the OpaqueKeyDecrypter interface.
//
// Note that ed25519 is only available for signatures, not encryption, so is
// not an option here.
//
// Automatically decompresses plaintext, but returns an error if the decompressed
// data would be >250kB or >10x the size of the compressed data, whichever is larger.
func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
headers := obj.mergedHeaders(nil)
if len(obj.recipients) > 1 {
return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one")
}
critical, err := headers.getCritical()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
}
if len(critical) > 0 {
return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
}
key := tryJWKS(decryptionKey, obj.Header)
decrypter, err := newDecrypter(key)
if err != nil {
return nil, err
}
cipher := getContentCipher(headers.getEncryption())
if cipher == nil {
return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption()))
}
generator := randomKeyGenerator{
size: cipher.keySize(),
}
parts := &aeadParts{
iv: obj.iv,
ciphertext: obj.ciphertext,
tag: obj.tag,
}
authData := obj.computeAuthData()
var plaintext []byte
recipient := obj.recipients[0]
recipientHeaders := obj.mergedHeaders(&recipient)
cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
if err == nil {
// Found a valid CEK -- let's try to decrypt.
plaintext, err = cipher.decrypt(cek, authData, parts)
}
if plaintext == nil {
return nil, ErrCryptoFailure
}
// The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" {
plaintext, err = decompress(comp, plaintext)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
}
return plaintext, nil
}
// DecryptMulti decrypts and validates the object and returns the plaintexts,
// with support for multiple recipients. It returns the index of the recipient
// for which the decryption was successful, the merged headers for that recipient,
// and the plaintext.
//
// The decryptionKey argument must have one of the types allowed for the
// decryptionKey argument of Decrypt().
//
// Automatically decompresses plaintext, but returns an error if the decompressed
// data would be >250kB or >3x the size of the compressed data, whichever is larger.
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
globalHeaders := obj.mergedHeaders(nil)
critical, err := globalHeaders.getCritical()
if err != nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
}
if len(critical) > 0 {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
}
key := tryJWKS(decryptionKey, obj.Header)
decrypter, err := newDecrypter(key)
if err != nil {
return -1, Header{}, nil, err
}
encryption := globalHeaders.getEncryption()
cipher := getContentCipher(encryption)
if cipher == nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption))
}
generator := randomKeyGenerator{
size: cipher.keySize(),
}
parts := &aeadParts{
iv: obj.iv,
ciphertext: obj.ciphertext,
tag: obj.tag,
}
authData := obj.computeAuthData()
index := -1
var plaintext []byte
var headers rawHeader
for i, recipient := range obj.recipients {
recipientHeaders := obj.mergedHeaders(&recipient)
cek, err := decrypter.decryptKey(recipientHeaders, &recipient, generator)
if err == nil {
// Found a valid CEK -- let's try to decrypt.
plaintext, err = cipher.decrypt(cek, authData, parts)
if err == nil {
index = i
headers = recipientHeaders
break
}
}
}
if plaintext == nil {
return -1, Header{}, nil, ErrCryptoFailure
}
// The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" {
plaintext, err = decompress(comp, plaintext)
if err != nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to decompress plaintext: %v", err)
}
}
sanitized, err := headers.sanitized()
if err != nil {
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err)
}
return index, sanitized, plaintext, err
}

25
vendor/github.com/go-jose/go-jose/v3/doc.go generated vendored Normal file
View File

@ -0,0 +1,25 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. It implements encryption and signing based on
the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
Token support available in a sub-package. The library supports both the compact
and JWS/JWE JSON Serialization formats, and has optional support for multiple
recipients.
*/
package jose

237
vendor/github.com/go-jose/go-jose/v3/encoding.go generated vendored Normal file
View File

@ -0,0 +1,237 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"bytes"
"compress/flate"
"encoding/base64"
"encoding/binary"
"fmt"
"io"
"math/big"
"strings"
"unicode"
"github.com/go-jose/go-jose/v3/json"
)
// Helper function to serialize known-good objects.
// Precondition: value is not a nil pointer.
func mustSerializeJSON(value interface{}) []byte {
out, err := json.Marshal(value)
if err != nil {
panic(err)
}
// We never want to serialize the top-level value "null," since it's not a
// valid JOSE message. But if a caller passes in a nil pointer to this method,
// MarshalJSON will happily serialize it as the top-level value "null". If
// that value is then embedded in another operation, for instance by being
// base64-encoded and fed as input to a signing algorithm
// (https://github.com/go-jose/go-jose/issues/22), the result will be
// incorrect. Because this method is intended for known-good objects, and a nil
// pointer is not a known-good object, we are free to panic in this case.
// Note: It's not possible to directly check whether the data pointed at by an
// interface is a nil pointer, so we do this hacky workaround.
// https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I
if string(out) == "null" {
panic("Tried to serialize a nil pointer.")
}
return out
}
// Strip all newlines and whitespace
func stripWhitespace(data string) string {
buf := strings.Builder{}
buf.Grow(len(data))
for _, r := range data {
if !unicode.IsSpace(r) {
buf.WriteRune(r)
}
}
return buf.String()
}
// Perform compression based on algorithm
func compress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
switch algorithm {
case DEFLATE:
return deflate(input)
default:
return nil, ErrUnsupportedAlgorithm
}
}
// Perform decompression based on algorithm
func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
switch algorithm {
case DEFLATE:
return inflate(input)
default:
return nil, ErrUnsupportedAlgorithm
}
}
// deflate compresses the input.
func deflate(input []byte) ([]byte, error) {
output := new(bytes.Buffer)
// Writing to byte buffer, err is always nil
writer, _ := flate.NewWriter(output, 1)
_, _ = io.Copy(writer, bytes.NewBuffer(input))
err := writer.Close()
return output.Bytes(), err
}
// inflate decompresses the input.
//
// Errors if the decompressed data would be >250kB or >10x the size of the
// compressed data, whichever is larger.
func inflate(input []byte) ([]byte, error) {
output := new(bytes.Buffer)
reader := flate.NewReader(bytes.NewBuffer(input))
maxCompressedSize := 10 * int64(len(input))
if maxCompressedSize < 250000 {
maxCompressedSize = 250000
}
limit := maxCompressedSize + 1
n, err := io.CopyN(output, reader, limit)
if err != nil && err != io.EOF {
return nil, err
}
if n == limit {
return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
}
err = reader.Close()
return output.Bytes(), err
}
// byteBuffer represents a slice of bytes that can be serialized to url-safe base64.
type byteBuffer struct {
data []byte
}
func newBuffer(data []byte) *byteBuffer {
if data == nil {
return nil
}
return &byteBuffer{
data: data,
}
}
func newFixedSizeBuffer(data []byte, length int) *byteBuffer {
if len(data) > length {
panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)")
}
pad := make([]byte, length-len(data))
return newBuffer(append(pad, data...))
}
func newBufferFromInt(num uint64) *byteBuffer {
data := make([]byte, 8)
binary.BigEndian.PutUint64(data, num)
return newBuffer(bytes.TrimLeft(data, "\x00"))
}
func (b *byteBuffer) MarshalJSON() ([]byte, error) {
return json.Marshal(b.base64())
}
func (b *byteBuffer) UnmarshalJSON(data []byte) error {
var encoded string
err := json.Unmarshal(data, &encoded)
if err != nil {
return err
}
if encoded == "" {
return nil
}
decoded, err := base64URLDecode(encoded)
if err != nil {
return err
}
*b = *newBuffer(decoded)
return nil
}
func (b *byteBuffer) base64() string {
return base64.RawURLEncoding.EncodeToString(b.data)
}
func (b *byteBuffer) bytes() []byte {
// Handling nil here allows us to transparently handle nil slices when serializing.
if b == nil {
return nil
}
return b.data
}
func (b byteBuffer) bigInt() *big.Int {
return new(big.Int).SetBytes(b.data)
}
func (b byteBuffer) toInt() int {
return int(b.bigInt().Int64())
}
// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C
func base64URLDecode(value string) ([]byte, error) {
value = strings.TrimRight(value, "=")
return base64.RawURLEncoding.DecodeString(value)
}
func base64EncodeLen(sl []byte) int {
return base64.RawURLEncoding.EncodedLen(len(sl))
}
func base64JoinWithDots(inputs ...[]byte) string {
if len(inputs) == 0 {
return ""
}
// Count of dots.
totalCount := len(inputs) - 1
for _, input := range inputs {
totalCount += base64EncodeLen(input)
}
out := make([]byte, totalCount)
startEncode := 0
for i, input := range inputs {
base64.RawURLEncoding.Encode(out[startEncode:], input)
if i == len(inputs)-1 {
continue
}
startEncode += base64EncodeLen(input)
out[startEncode] = '.'
startEncode++
}
return string(out)
}

27
vendor/github.com/go-jose/go-jose/v3/json/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2012 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

13
vendor/github.com/go-jose/go-jose/v3/json/README.md generated vendored Normal file
View File

@ -0,0 +1,13 @@
# Safe JSON
This repository contains a fork of the `encoding/json` package from Go 1.6.
The following changes were made:
* Object deserialization uses case-sensitive member name matching instead of
[case-insensitive matching](https://www.ietf.org/mail-archive/web/json/current/msg03763.html).
This is to avoid differences in the interpretation of JOSE messages between
go-jose and libraries written in other languages.
* When deserializing a JSON object, we check for duplicate keys and reject the
input whenever we detect a duplicate. Rather than trying to work with malformed
data, we prefer to reject it right away.

1216
vendor/github.com/go-jose/go-jose/v3/json/decode.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

1197
vendor/github.com/go-jose/go-jose/v3/json/encode.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

141
vendor/github.com/go-jose/go-jose/v3/json/indent.go generated vendored Normal file
View File

@ -0,0 +1,141 @@
// Copyright 2010 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 json
import "bytes"
// Compact appends to dst the JSON-encoded src with
// insignificant space characters elided.
func Compact(dst *bytes.Buffer, src []byte) error {
return compact(dst, src, false)
}
func compact(dst *bytes.Buffer, src []byte, escape bool) error {
origLen := dst.Len()
var scan scanner
scan.reset()
start := 0
for i, c := range src {
if escape && (c == '<' || c == '>' || c == '&') {
if start < i {
dst.Write(src[start:i])
}
dst.WriteString(`\u00`)
dst.WriteByte(hex[c>>4])
dst.WriteByte(hex[c&0xF])
start = i + 1
}
// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
if start < i {
dst.Write(src[start:i])
}
dst.WriteString(`\u202`)
dst.WriteByte(hex[src[i+2]&0xF])
start = i + 3
}
v := scan.step(&scan, c)
if v >= scanSkipSpace {
if v == scanError {
break
}
if start < i {
dst.Write(src[start:i])
}
start = i + 1
}
}
if scan.eof() == scanError {
dst.Truncate(origLen)
return scan.err
}
if start < len(src) {
dst.Write(src[start:])
}
return nil
}
func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
dst.WriteByte('\n')
dst.WriteString(prefix)
for i := 0; i < depth; i++ {
dst.WriteString(indent)
}
}
// Indent appends to dst an indented form of the JSON-encoded src.
// Each element in a JSON object or array begins on a new,
// indented line beginning with prefix followed by one or more
// copies of indent according to the indentation nesting.
// The data appended to dst does not begin with the prefix nor
// any indentation, to make it easier to embed inside other formatted JSON data.
// Although leading space characters (space, tab, carriage return, newline)
// at the beginning of src are dropped, trailing space characters
// at the end of src are preserved and copied to dst.
// For example, if src has no trailing spaces, neither will dst;
// if src ends in a trailing newline, so will dst.
func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
origLen := dst.Len()
var scan scanner
scan.reset()
needIndent := false
depth := 0
for _, c := range src {
scan.bytes++
v := scan.step(&scan, c)
if v == scanSkipSpace {
continue
}
if v == scanError {
break
}
if needIndent && v != scanEndObject && v != scanEndArray {
needIndent = false
depth++
newline(dst, prefix, indent, depth)
}
// Emit semantically uninteresting bytes
// (in particular, punctuation in strings) unmodified.
if v == scanContinue {
dst.WriteByte(c)
continue
}
// Add spacing around real punctuation.
switch c {
case '{', '[':
// delay indent so that empty object and array are formatted as {} and [].
needIndent = true
dst.WriteByte(c)
case ',':
dst.WriteByte(c)
newline(dst, prefix, indent, depth)
case ':':
dst.WriteByte(c)
dst.WriteByte(' ')
case '}', ']':
if needIndent {
// suppress indent in empty object/array
needIndent = false
} else {
depth--
newline(dst, prefix, indent, depth)
}
dst.WriteByte(c)
default:
dst.WriteByte(c)
}
}
if scan.eof() == scanError {
dst.Truncate(origLen)
return scan.err
}
return nil
}

623
vendor/github.com/go-jose/go-jose/v3/json/scanner.go generated vendored Normal file
View File

@ -0,0 +1,623 @@
// Copyright 2010 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 json
// JSON value parser state machine.
// Just about at the limit of what is reasonable to write by hand.
// Some parts are a bit tedious, but overall it nicely factors out the
// otherwise common code from the multiple scanning functions
// in this package (Compact, Indent, checkValid, nextValue, etc).
//
// This file starts with two simple examples using the scanner
// before diving into the scanner itself.
import "strconv"
// checkValid verifies that data is valid JSON-encoded data.
// scan is passed in for use by checkValid to avoid an allocation.
func checkValid(data []byte, scan *scanner) error {
scan.reset()
for _, c := range data {
scan.bytes++
if scan.step(scan, c) == scanError {
return scan.err
}
}
if scan.eof() == scanError {
return scan.err
}
return nil
}
// nextValue splits data after the next whole JSON value,
// returning that value and the bytes that follow it as separate slices.
// scan is passed in for use by nextValue to avoid an allocation.
func nextValue(data []byte, scan *scanner) (value, rest []byte, err error) {
scan.reset()
for i, c := range data {
v := scan.step(scan, c)
if v >= scanEndObject {
switch v {
// probe the scanner with a space to determine whether we will
// get scanEnd on the next character. Otherwise, if the next character
// is not a space, scanEndTop allocates a needless error.
case scanEndObject, scanEndArray:
if scan.step(scan, ' ') == scanEnd {
return data[:i+1], data[i+1:], nil
}
case scanError:
return nil, nil, scan.err
case scanEnd:
return data[:i], data[i:], nil
}
}
}
if scan.eof() == scanError {
return nil, nil, scan.err
}
return data, nil, nil
}
// A SyntaxError is a description of a JSON syntax error.
type SyntaxError struct {
msg string // description of error
Offset int64 // error occurred after reading Offset bytes
}
func (e *SyntaxError) Error() string { return e.msg }
// A scanner is a JSON scanning state machine.
// Callers call scan.reset() and then pass bytes in one at a time
// by calling scan.step(&scan, c) for each byte.
// The return value, referred to as an opcode, tells the
// caller about significant parsing events like beginning
// and ending literals, objects, and arrays, so that the
// caller can follow along if it wishes.
// The return value scanEnd indicates that a single top-level
// JSON value has been completed, *before* the byte that
// just got passed in. (The indication must be delayed in order
// to recognize the end of numbers: is 123 a whole value or
// the beginning of 12345e+6?).
type scanner struct {
// The step is a func to be called to execute the next transition.
// Also tried using an integer constant and a single func
// with a switch, but using the func directly was 10% faster
// on a 64-bit Mac Mini, and it's nicer to read.
step func(*scanner, byte) int
// Reached end of top-level value.
endTop bool
// Stack of what we're in the middle of - array values, object keys, object values.
parseState []int
// Error that happened, if any.
err error
// 1-byte redo (see undo method)
redo bool
redoCode int
redoState func(*scanner, byte) int
// total bytes consumed, updated by decoder.Decode
bytes int64
}
// These values are returned by the state transition functions
// assigned to scanner.state and the method scanner.eof.
// They give details about the current state of the scan that
// callers might be interested to know about.
// It is okay to ignore the return value of any particular
// call to scanner.state: if one call returns scanError,
// every subsequent call will return scanError too.
const (
// Continue.
scanContinue = iota // uninteresting byte
scanBeginLiteral // end implied by next result != scanContinue
scanBeginObject // begin object
scanObjectKey // just finished object key (string)
scanObjectValue // just finished non-last object value
scanEndObject // end object (implies scanObjectValue if possible)
scanBeginArray // begin array
scanArrayValue // just finished array value
scanEndArray // end array (implies scanArrayValue if possible)
scanSkipSpace // space byte; can skip; known to be last "continue" result
// Stop.
scanEnd // top-level value ended *before* this byte; known to be first "stop" result
scanError // hit an error, scanner.err.
)
// These values are stored in the parseState stack.
// They give the current state of a composite value
// being scanned. If the parser is inside a nested value
// the parseState describes the nested state, outermost at entry 0.
const (
parseObjectKey = iota // parsing object key (before colon)
parseObjectValue // parsing object value (after colon)
parseArrayValue // parsing array value
)
// reset prepares the scanner for use.
// It must be called before calling s.step.
func (s *scanner) reset() {
s.step = stateBeginValue
s.parseState = s.parseState[0:0]
s.err = nil
s.redo = false
s.endTop = false
}
// eof tells the scanner that the end of input has been reached.
// It returns a scan status just as s.step does.
func (s *scanner) eof() int {
if s.err != nil {
return scanError
}
if s.endTop {
return scanEnd
}
s.step(s, ' ')
if s.endTop {
return scanEnd
}
if s.err == nil {
s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
}
return scanError
}
// pushParseState pushes a new parse state p onto the parse stack.
func (s *scanner) pushParseState(p int) {
s.parseState = append(s.parseState, p)
}
// popParseState pops a parse state (already obtained) off the stack
// and updates s.step accordingly.
func (s *scanner) popParseState() {
n := len(s.parseState) - 1
s.parseState = s.parseState[0:n]
s.redo = false
if n == 0 {
s.step = stateEndTop
s.endTop = true
} else {
s.step = stateEndValue
}
}
func isSpace(c byte) bool {
return c == ' ' || c == '\t' || c == '\r' || c == '\n'
}
// stateBeginValueOrEmpty is the state after reading `[`.
func stateBeginValueOrEmpty(s *scanner, c byte) int {
if c <= ' ' && isSpace(c) {
return scanSkipSpace
}
if c == ']' {
return stateEndValue(s, c)
}
return stateBeginValue(s, c)
}
// stateBeginValue is the state at the beginning of the input.
func stateBeginValue(s *scanner, c byte) int {
if c <= ' ' && isSpace(c) {
return scanSkipSpace
}
switch c {
case '{':
s.step = stateBeginStringOrEmpty
s.pushParseState(parseObjectKey)
return scanBeginObject
case '[':
s.step = stateBeginValueOrEmpty
s.pushParseState(parseArrayValue)
return scanBeginArray
case '"':
s.step = stateInString
return scanBeginLiteral
case '-':
s.step = stateNeg
return scanBeginLiteral
case '0': // beginning of 0.123
s.step = state0
return scanBeginLiteral
case 't': // beginning of true
s.step = stateT
return scanBeginLiteral
case 'f': // beginning of false
s.step = stateF
return scanBeginLiteral
case 'n': // beginning of null
s.step = stateN
return scanBeginLiteral
}
if '1' <= c && c <= '9' { // beginning of 1234.5
s.step = state1
return scanBeginLiteral
}
return s.error(c, "looking for beginning of value")
}
// stateBeginStringOrEmpty is the state after reading `{`.
func stateBeginStringOrEmpty(s *scanner, c byte) int {
if c <= ' ' && isSpace(c) {
return scanSkipSpace
}
if c == '}' {
n := len(s.parseState)
s.parseState[n-1] = parseObjectValue
return stateEndValue(s, c)
}
return stateBeginString(s, c)
}
// stateBeginString is the state after reading `{"key": value,`.
func stateBeginString(s *scanner, c byte) int {
if c <= ' ' && isSpace(c) {
return scanSkipSpace
}
if c == '"' {
s.step = stateInString
return scanBeginLiteral
}
return s.error(c, "looking for beginning of object key string")
}
// stateEndValue is the state after completing a value,
// such as after reading `{}` or `true` or `["x"`.
func stateEndValue(s *scanner, c byte) int {
n := len(s.parseState)
if n == 0 {
// Completed top-level before the current byte.
s.step = stateEndTop
s.endTop = true
return stateEndTop(s, c)
}
if c <= ' ' && isSpace(c) {
s.step = stateEndValue
return scanSkipSpace
}
ps := s.parseState[n-1]
switch ps {
case parseObjectKey:
if c == ':' {
s.parseState[n-1] = parseObjectValue
s.step = stateBeginValue
return scanObjectKey
}
return s.error(c, "after object key")
case parseObjectValue:
if c == ',' {
s.parseState[n-1] = parseObjectKey
s.step = stateBeginString
return scanObjectValue
}
if c == '}' {
s.popParseState()
return scanEndObject
}
return s.error(c, "after object key:value pair")
case parseArrayValue:
if c == ',' {
s.step = stateBeginValue
return scanArrayValue
}
if c == ']' {
s.popParseState()
return scanEndArray
}
return s.error(c, "after array element")
}
return s.error(c, "")
}
// stateEndTop is the state after finishing the top-level value,
// such as after reading `{}` or `[1,2,3]`.
// Only space characters should be seen now.
func stateEndTop(s *scanner, c byte) int {
if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
// Complain about non-space byte on next call.
s.error(c, "after top-level value")
}
return scanEnd
}
// stateInString is the state after reading `"`.
func stateInString(s *scanner, c byte) int {
if c == '"' {
s.step = stateEndValue
return scanContinue
}
if c == '\\' {
s.step = stateInStringEsc
return scanContinue
}
if c < 0x20 {
return s.error(c, "in string literal")
}
return scanContinue
}
// stateInStringEsc is the state after reading `"\` during a quoted string.
func stateInStringEsc(s *scanner, c byte) int {
switch c {
case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
s.step = stateInString
return scanContinue
case 'u':
s.step = stateInStringEscU
return scanContinue
}
return s.error(c, "in string escape code")
}
// stateInStringEscU is the state after reading `"\u` during a quoted string.
func stateInStringEscU(s *scanner, c byte) int {
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
s.step = stateInStringEscU1
return scanContinue
}
// numbers
return s.error(c, "in \\u hexadecimal character escape")
}
// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
func stateInStringEscU1(s *scanner, c byte) int {
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
s.step = stateInStringEscU12
return scanContinue
}
// numbers
return s.error(c, "in \\u hexadecimal character escape")
}
// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
func stateInStringEscU12(s *scanner, c byte) int {
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
s.step = stateInStringEscU123
return scanContinue
}
// numbers
return s.error(c, "in \\u hexadecimal character escape")
}
// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
func stateInStringEscU123(s *scanner, c byte) int {
if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
s.step = stateInString
return scanContinue
}
// numbers
return s.error(c, "in \\u hexadecimal character escape")
}
// stateNeg is the state after reading `-` during a number.
func stateNeg(s *scanner, c byte) int {
if c == '0' {
s.step = state0
return scanContinue
}
if '1' <= c && c <= '9' {
s.step = state1
return scanContinue
}
return s.error(c, "in numeric literal")
}
// state1 is the state after reading a non-zero integer during a number,
// such as after reading `1` or `100` but not `0`.
func state1(s *scanner, c byte) int {
if '0' <= c && c <= '9' {
s.step = state1
return scanContinue
}
return state0(s, c)
}
// state0 is the state after reading `0` during a number.
func state0(s *scanner, c byte) int {
if c == '.' {
s.step = stateDot
return scanContinue
}
if c == 'e' || c == 'E' {
s.step = stateE
return scanContinue
}
return stateEndValue(s, c)
}
// stateDot is the state after reading the integer and decimal point in a number,
// such as after reading `1.`.
func stateDot(s *scanner, c byte) int {
if '0' <= c && c <= '9' {
s.step = stateDot0
return scanContinue
}
return s.error(c, "after decimal point in numeric literal")
}
// stateDot0 is the state after reading the integer, decimal point, and subsequent
// digits of a number, such as after reading `3.14`.
func stateDot0(s *scanner, c byte) int {
if '0' <= c && c <= '9' {
return scanContinue
}
if c == 'e' || c == 'E' {
s.step = stateE
return scanContinue
}
return stateEndValue(s, c)
}
// stateE is the state after reading the mantissa and e in a number,
// such as after reading `314e` or `0.314e`.
func stateE(s *scanner, c byte) int {
if c == '+' || c == '-' {
s.step = stateESign
return scanContinue
}
return stateESign(s, c)
}
// stateESign is the state after reading the mantissa, e, and sign in a number,
// such as after reading `314e-` or `0.314e+`.
func stateESign(s *scanner, c byte) int {
if '0' <= c && c <= '9' {
s.step = stateE0
return scanContinue
}
return s.error(c, "in exponent of numeric literal")
}
// stateE0 is the state after reading the mantissa, e, optional sign,
// and at least one digit of the exponent in a number,
// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
func stateE0(s *scanner, c byte) int {
if '0' <= c && c <= '9' {
return scanContinue
}
return stateEndValue(s, c)
}
// stateT is the state after reading `t`.
func stateT(s *scanner, c byte) int {
if c == 'r' {
s.step = stateTr
return scanContinue
}
return s.error(c, "in literal true (expecting 'r')")
}
// stateTr is the state after reading `tr`.
func stateTr(s *scanner, c byte) int {
if c == 'u' {
s.step = stateTru
return scanContinue
}
return s.error(c, "in literal true (expecting 'u')")
}
// stateTru is the state after reading `tru`.
func stateTru(s *scanner, c byte) int {
if c == 'e' {
s.step = stateEndValue
return scanContinue
}
return s.error(c, "in literal true (expecting 'e')")
}
// stateF is the state after reading `f`.
func stateF(s *scanner, c byte) int {
if c == 'a' {
s.step = stateFa
return scanContinue
}
return s.error(c, "in literal false (expecting 'a')")
}
// stateFa is the state after reading `fa`.
func stateFa(s *scanner, c byte) int {
if c == 'l' {
s.step = stateFal
return scanContinue
}
return s.error(c, "in literal false (expecting 'l')")
}
// stateFal is the state after reading `fal`.
func stateFal(s *scanner, c byte) int {
if c == 's' {
s.step = stateFals
return scanContinue
}
return s.error(c, "in literal false (expecting 's')")
}
// stateFals is the state after reading `fals`.
func stateFals(s *scanner, c byte) int {
if c == 'e' {
s.step = stateEndValue
return scanContinue
}
return s.error(c, "in literal false (expecting 'e')")
}
// stateN is the state after reading `n`.
func stateN(s *scanner, c byte) int {
if c == 'u' {
s.step = stateNu
return scanContinue
}
return s.error(c, "in literal null (expecting 'u')")
}
// stateNu is the state after reading `nu`.
func stateNu(s *scanner, c byte) int {
if c == 'l' {
s.step = stateNul
return scanContinue
}
return s.error(c, "in literal null (expecting 'l')")
}
// stateNul is the state after reading `nul`.
func stateNul(s *scanner, c byte) int {
if c == 'l' {
s.step = stateEndValue
return scanContinue
}
return s.error(c, "in literal null (expecting 'l')")
}
// stateError is the state after reaching a syntax error,
// such as after reading `[1}` or `5.1.2`.
func stateError(s *scanner, c byte) int {
return scanError
}
// error records an error and switches to the error state.
func (s *scanner) error(c byte, context string) int {
s.step = stateError
s.err = &SyntaxError{"invalid character " + quoteChar(c) + " " + context, s.bytes}
return scanError
}
// quoteChar formats c as a quoted character literal
func quoteChar(c byte) string {
// special cases - different from quoted strings
if c == '\'' {
return `'\''`
}
if c == '"' {
return `'"'`
}
// use quoted string with different quotation marks
s := strconv.Quote(string(c))
return "'" + s[1:len(s)-1] + "'"
}
// undo causes the scanner to return scanCode from the next state transition.
// This gives callers a simple 1-byte undo mechanism.
func (s *scanner) undo(scanCode int) {
if s.redo {
panic("json: invalid use of scanner")
}
s.redoCode = scanCode
s.redoState = s.step
s.step = stateRedo
s.redo = true
}
// stateRedo helps implement the scanner's 1-byte undo.
func stateRedo(s *scanner, c byte) int {
s.redo = false
s.step = s.redoState
return s.redoCode
}

484
vendor/github.com/go-jose/go-jose/v3/json/stream.go generated vendored Normal file
View File

@ -0,0 +1,484 @@
// Copyright 2010 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 json
import (
"bytes"
"errors"
"io"
)
// A Decoder reads and decodes JSON objects from an input stream.
type Decoder struct {
r io.Reader
buf []byte
d decodeState
scanp int // start of unread data in buf
scan scanner
err error
tokenState int
tokenStack []int
}
// NewDecoder returns a new decoder that reads from r.
//
// The decoder introduces its own buffering and may
// read data from r beyond the JSON values requested.
func NewDecoder(r io.Reader) *Decoder {
return &Decoder{r: r}
}
// Deprecated: Use `SetNumberType` instead
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
// Number instead of as a float64.
func (dec *Decoder) UseNumber() { dec.d.numberType = UnmarshalJSONNumber }
// SetNumberType causes the Decoder to unmarshal a number into an interface{} as a
// Number, float64 or int64 depending on `t` enum value.
func (dec *Decoder) SetNumberType(t NumberUnmarshalType) { dec.d.numberType = t }
// Decode reads the next JSON-encoded value from its
// input and stores it in the value pointed to by v.
//
// See the documentation for Unmarshal for details about
// the conversion of JSON into a Go value.
func (dec *Decoder) Decode(v interface{}) error {
if dec.err != nil {
return dec.err
}
if err := dec.tokenPrepareForDecode(); err != nil {
return err
}
if !dec.tokenValueAllowed() {
return &SyntaxError{msg: "not at beginning of value"}
}
// Read whole value into buffer.
n, err := dec.readValue()
if err != nil {
return err
}
dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
dec.scanp += n
// Don't save err from unmarshal into dec.err:
// the connection is still usable since we read a complete JSON
// object from it before the error happened.
err = dec.d.unmarshal(v)
// fixup token streaming state
dec.tokenValueEnd()
return err
}
// Buffered returns a reader of the data remaining in the Decoder's
// buffer. The reader is valid until the next call to Decode.
func (dec *Decoder) Buffered() io.Reader {
return bytes.NewReader(dec.buf[dec.scanp:])
}
// readValue reads a JSON value into dec.buf.
// It returns the length of the encoding.
func (dec *Decoder) readValue() (int, error) {
dec.scan.reset()
scanp := dec.scanp
var err error
Input:
for {
// Look in the buffer for a new value.
for i, c := range dec.buf[scanp:] {
dec.scan.bytes++
v := dec.scan.step(&dec.scan, c)
if v == scanEnd {
scanp += i
break Input
}
// scanEnd is delayed one byte.
// We might block trying to get that byte from src,
// so instead invent a space byte.
if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
scanp += i + 1
break Input
}
if v == scanError {
dec.err = dec.scan.err
return 0, dec.scan.err
}
}
scanp = len(dec.buf)
// Did the last read have an error?
// Delayed until now to allow buffer scan.
if err != nil {
if err == io.EOF {
if dec.scan.step(&dec.scan, ' ') == scanEnd {
break Input
}
if nonSpace(dec.buf) {
err = io.ErrUnexpectedEOF
}
}
dec.err = err
return 0, err
}
n := scanp - dec.scanp
err = dec.refill()
scanp = dec.scanp + n
}
return scanp - dec.scanp, nil
}
func (dec *Decoder) refill() error {
// Make room to read more into the buffer.
// First slide down data already consumed.
if dec.scanp > 0 {
n := copy(dec.buf, dec.buf[dec.scanp:])
dec.buf = dec.buf[:n]
dec.scanp = 0
}
// Grow buffer if not large enough.
const minRead = 512
if cap(dec.buf)-len(dec.buf) < minRead {
newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
copy(newBuf, dec.buf)
dec.buf = newBuf
}
// Read. Delay error for next iteration (after scan).
n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
dec.buf = dec.buf[0 : len(dec.buf)+n]
return err
}
func nonSpace(b []byte) bool {
for _, c := range b {
if !isSpace(c) {
return true
}
}
return false
}
// An Encoder writes JSON objects to an output stream.
type Encoder struct {
w io.Writer
err error
}
// NewEncoder returns a new encoder that writes to w.
func NewEncoder(w io.Writer) *Encoder {
return &Encoder{w: w}
}
// Encode writes the JSON encoding of v to the stream,
// followed by a newline character.
//
// See the documentation for Marshal for details about the
// conversion of Go values to JSON.
func (enc *Encoder) Encode(v interface{}) error {
if enc.err != nil {
return enc.err
}
e := newEncodeState()
err := e.marshal(v)
if err != nil {
return err
}
// Terminate each value with a newline.
// This makes the output look a little nicer
// when debugging, and some kind of space
// is required if the encoded value was a number,
// so that the reader knows there aren't more
// digits coming.
e.WriteByte('\n')
if _, err = enc.w.Write(e.Bytes()); err != nil {
enc.err = err
}
encodeStatePool.Put(e)
return err
}
// RawMessage is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawMessage []byte
// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawMessage) MarshalJSON() ([]byte, error) {
return *m, nil
}
// UnmarshalJSON sets *m to a copy of data.
func (m *RawMessage) UnmarshalJSON(data []byte) error {
if m == nil {
return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
}
*m = append((*m)[0:0], data...)
return nil
}
var _ Marshaler = (*RawMessage)(nil)
var _ Unmarshaler = (*RawMessage)(nil)
// A Token holds a value of one of these types:
//
// Delim, for the four JSON delimiters [ ] { }
// bool, for JSON booleans
// float64, for JSON numbers
// Number, for JSON numbers
// string, for JSON string literals
// nil, for JSON null
type Token interface{}
const (
tokenTopValue = iota
tokenArrayStart
tokenArrayValue
tokenArrayComma
tokenObjectStart
tokenObjectKey
tokenObjectColon
tokenObjectValue
tokenObjectComma
)
// advance tokenstate from a separator state to a value state
func (dec *Decoder) tokenPrepareForDecode() error {
// Note: Not calling peek before switch, to avoid
// putting peek into the standard Decode path.
// peek is only called when using the Token API.
switch dec.tokenState {
case tokenArrayComma:
c, err := dec.peek()
if err != nil {
return err
}
if c != ',' {
return &SyntaxError{"expected comma after array element", 0}
}
dec.scanp++
dec.tokenState = tokenArrayValue
case tokenObjectColon:
c, err := dec.peek()
if err != nil {
return err
}
if c != ':' {
return &SyntaxError{"expected colon after object key", 0}
}
dec.scanp++
dec.tokenState = tokenObjectValue
}
return nil
}
func (dec *Decoder) tokenValueAllowed() bool {
switch dec.tokenState {
case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
return true
}
return false
}
func (dec *Decoder) tokenValueEnd() {
switch dec.tokenState {
case tokenArrayStart, tokenArrayValue:
dec.tokenState = tokenArrayComma
case tokenObjectValue:
dec.tokenState = tokenObjectComma
}
}
// A Delim is a JSON array or object delimiter, one of [ ] { or }.
type Delim rune
func (d Delim) String() string {
return string(d)
}
// Token returns the next JSON token in the input stream.
// At the end of the input stream, Token returns nil, io.EOF.
//
// Token guarantees that the delimiters [ ] { } it returns are
// properly nested and matched: if Token encounters an unexpected
// delimiter in the input, it will return an error.
//
// The input stream consists of basic JSON values—bool, string,
// number, and null—along with delimiters [ ] { } of type Delim
// to mark the start and end of arrays and objects.
// Commas and colons are elided.
func (dec *Decoder) Token() (Token, error) {
for {
c, err := dec.peek()
if err != nil {
return nil, err
}
switch c {
case '[':
if !dec.tokenValueAllowed() {
return dec.tokenError(c)
}
dec.scanp++
dec.tokenStack = append(dec.tokenStack, dec.tokenState)
dec.tokenState = tokenArrayStart
return Delim('['), nil
case ']':
if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
return dec.tokenError(c)
}
dec.scanp++
dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
dec.tokenValueEnd()
return Delim(']'), nil
case '{':
if !dec.tokenValueAllowed() {
return dec.tokenError(c)
}
dec.scanp++
dec.tokenStack = append(dec.tokenStack, dec.tokenState)
dec.tokenState = tokenObjectStart
return Delim('{'), nil
case '}':
if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
return dec.tokenError(c)
}
dec.scanp++
dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
dec.tokenValueEnd()
return Delim('}'), nil
case ':':
if dec.tokenState != tokenObjectColon {
return dec.tokenError(c)
}
dec.scanp++
dec.tokenState = tokenObjectValue
continue
case ',':
if dec.tokenState == tokenArrayComma {
dec.scanp++
dec.tokenState = tokenArrayValue
continue
}
if dec.tokenState == tokenObjectComma {
dec.scanp++
dec.tokenState = tokenObjectKey
continue
}
return dec.tokenError(c)
case '"':
if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
var x string
old := dec.tokenState
dec.tokenState = tokenTopValue
err := dec.Decode(&x)
dec.tokenState = old
if err != nil {
clearOffset(err)
return nil, err
}
dec.tokenState = tokenObjectColon
return x, nil
}
fallthrough
default:
if !dec.tokenValueAllowed() {
return dec.tokenError(c)
}
var x interface{}
if err := dec.Decode(&x); err != nil {
clearOffset(err)
return nil, err
}
return x, nil
}
}
}
func clearOffset(err error) {
if s, ok := err.(*SyntaxError); ok {
s.Offset = 0
}
}
func (dec *Decoder) tokenError(c byte) (Token, error) {
var context string
switch dec.tokenState {
case tokenTopValue:
context = " looking for beginning of value"
case tokenArrayStart, tokenArrayValue, tokenObjectValue:
context = " looking for beginning of value"
case tokenArrayComma:
context = " after array element"
case tokenObjectKey:
context = " looking for beginning of object key string"
case tokenObjectColon:
context = " after object key"
case tokenObjectComma:
context = " after object key:value pair"
}
return nil, &SyntaxError{"invalid character " + quoteChar(c) + " " + context, 0}
}
// More reports whether there is another element in the
// current array or object being parsed.
func (dec *Decoder) More() bool {
c, err := dec.peek()
return err == nil && c != ']' && c != '}'
}
func (dec *Decoder) peek() (byte, error) {
var err error
for {
for i := dec.scanp; i < len(dec.buf); i++ {
c := dec.buf[i]
if isSpace(c) {
continue
}
dec.scanp = i
return c, nil
}
// buffer has been scanned, now report any error
if err != nil {
return 0, err
}
err = dec.refill()
}
}
/*
TODO
// EncodeToken writes the given JSON token to the stream.
// It returns an error if the delimiters [ ] { } are not properly used.
//
// EncodeToken does not call Flush, because usually it is part of
// a larger operation such as Encode, and those will call Flush when finished.
// Callers that create an Encoder and then invoke EncodeToken directly,
// without using Encode, need to call Flush when finished to ensure that
// the JSON is written to the underlying writer.
func (e *Encoder) EncodeToken(t Token) error {
...
}
*/

44
vendor/github.com/go-jose/go-jose/v3/json/tags.go generated vendored Normal file
View File

@ -0,0 +1,44 @@
// 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 json
import (
"strings"
)
// tagOptions is the string following a comma in a struct field's "json"
// tag, or the empty string. It does not include the leading comma.
type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
// Contains reports whether a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func (o tagOptions) Contains(optionName string) bool {
if len(o) == 0 {
return false
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
return true
}
s = next
}
return false
}

295
vendor/github.com/go-jose/go-jose/v3/jwe.go generated vendored Normal file
View File

@ -0,0 +1,295 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"encoding/base64"
"fmt"
"strings"
"github.com/go-jose/go-jose/v3/json"
)
// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
type rawJSONWebEncryption struct {
Protected *byteBuffer `json:"protected,omitempty"`
Unprotected *rawHeader `json:"unprotected,omitempty"`
Header *rawHeader `json:"header,omitempty"`
Recipients []rawRecipientInfo `json:"recipients,omitempty"`
Aad *byteBuffer `json:"aad,omitempty"`
EncryptedKey *byteBuffer `json:"encrypted_key,omitempty"`
Iv *byteBuffer `json:"iv,omitempty"`
Ciphertext *byteBuffer `json:"ciphertext,omitempty"`
Tag *byteBuffer `json:"tag,omitempty"`
}
// rawRecipientInfo represents a raw JWE Per-Recipient header JSON object. Used for parsing/serializing.
type rawRecipientInfo struct {
Header *rawHeader `json:"header,omitempty"`
EncryptedKey string `json:"encrypted_key,omitempty"`
}
// JSONWebEncryption represents an encrypted JWE object after parsing.
type JSONWebEncryption struct {
Header Header
protected, unprotected *rawHeader
recipients []recipientInfo
aad, iv, ciphertext, tag []byte
original *rawJSONWebEncryption
}
// recipientInfo represents a raw JWE Per-Recipient header JSON object after parsing.
type recipientInfo struct {
header *rawHeader
encryptedKey []byte
}
// GetAuthData retrieves the (optional) authenticated data attached to the object.
func (obj JSONWebEncryption) GetAuthData() []byte {
if obj.aad != nil {
out := make([]byte, len(obj.aad))
copy(out, obj.aad)
return out
}
return nil
}
// Get the merged header values
func (obj JSONWebEncryption) mergedHeaders(recipient *recipientInfo) rawHeader {
out := rawHeader{}
out.merge(obj.protected)
out.merge(obj.unprotected)
if recipient != nil {
out.merge(recipient.header)
}
return out
}
// Get the additional authenticated data from a JWE object.
func (obj JSONWebEncryption) computeAuthData() []byte {
var protected string
switch {
case obj.original != nil && obj.original.Protected != nil:
protected = obj.original.Protected.base64()
case obj.protected != nil:
protected = base64.RawURLEncoding.EncodeToString(mustSerializeJSON((obj.protected)))
default:
protected = ""
}
output := []byte(protected)
if obj.aad != nil {
output = append(output, '.')
output = append(output, []byte(base64.RawURLEncoding.EncodeToString(obj.aad))...)
}
return output
}
// ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format.
func ParseEncrypted(input string) (*JSONWebEncryption, error) {
input = stripWhitespace(input)
if strings.HasPrefix(input, "{") {
return parseEncryptedFull(input)
}
return parseEncryptedCompact(input)
}
// parseEncryptedFull parses a message in compact format.
func parseEncryptedFull(input string) (*JSONWebEncryption, error) {
var parsed rawJSONWebEncryption
err := json.Unmarshal([]byte(input), &parsed)
if err != nil {
return nil, err
}
return parsed.sanitized()
}
// sanitized produces a cleaned-up JWE object from the raw JSON.
func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
obj := &JSONWebEncryption{
original: parsed,
unprotected: parsed.Unprotected,
}
// Check that there is not a nonce in the unprotected headers
if parsed.Unprotected != nil {
if nonce := parsed.Unprotected.getNonce(); nonce != "" {
return nil, ErrUnprotectedNonce
}
}
if parsed.Header != nil {
if nonce := parsed.Header.getNonce(); nonce != "" {
return nil, ErrUnprotectedNonce
}
}
if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
err := json.Unmarshal(parsed.Protected.bytes(), &obj.protected)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid protected header: %s, %s", err, parsed.Protected.base64())
}
}
// Note: this must be called _after_ we parse the protected header,
// otherwise fields from the protected header will not get picked up.
var err error
mergedHeaders := obj.mergedHeaders(nil)
obj.Header, err = mergedHeaders.sanitized()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: cannot sanitize merged headers: %v (%v)", err, mergedHeaders)
}
if len(parsed.Recipients) == 0 {
obj.recipients = []recipientInfo{
{
header: parsed.Header,
encryptedKey: parsed.EncryptedKey.bytes(),
},
}
} else {
obj.recipients = make([]recipientInfo, len(parsed.Recipients))
for r := range parsed.Recipients {
encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey)
if err != nil {
return nil, err
}
// Check that there is not a nonce in the unprotected header
if parsed.Recipients[r].Header != nil && parsed.Recipients[r].Header.getNonce() != "" {
return nil, ErrUnprotectedNonce
}
obj.recipients[r].header = parsed.Recipients[r].Header
obj.recipients[r].encryptedKey = encryptedKey
}
}
for _, recipient := range obj.recipients {
headers := obj.mergedHeaders(&recipient)
if headers.getAlgorithm() == "" || headers.getEncryption() == "" {
return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers")
}
}
obj.iv = parsed.Iv.bytes()
obj.ciphertext = parsed.Ciphertext.bytes()
obj.tag = parsed.Tag.bytes()
obj.aad = parsed.Aad.bytes()
return obj, nil
}
// parseEncryptedCompact parses a message in compact format.
func parseEncryptedCompact(input string) (*JSONWebEncryption, error) {
parts := strings.Split(input, ".")
if len(parts) != 5 {
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
}
rawProtected, err := base64URLDecode(parts[0])
if err != nil {
return nil, err
}
encryptedKey, err := base64URLDecode(parts[1])
if err != nil {
return nil, err
}
iv, err := base64URLDecode(parts[2])
if err != nil {
return nil, err
}
ciphertext, err := base64URLDecode(parts[3])
if err != nil {
return nil, err
}
tag, err := base64URLDecode(parts[4])
if err != nil {
return nil, err
}
raw := &rawJSONWebEncryption{
Protected: newBuffer(rawProtected),
EncryptedKey: newBuffer(encryptedKey),
Iv: newBuffer(iv),
Ciphertext: newBuffer(ciphertext),
Tag: newBuffer(tag),
}
return raw.sanitized()
}
// CompactSerialize serializes an object using the compact serialization format.
func (obj JSONWebEncryption) CompactSerialize() (string, error) {
if len(obj.recipients) != 1 || obj.unprotected != nil ||
obj.protected == nil || obj.recipients[0].header != nil {
return "", ErrNotSupported
}
serializedProtected := mustSerializeJSON(obj.protected)
return base64JoinWithDots(
serializedProtected,
obj.recipients[0].encryptedKey,
obj.iv,
obj.ciphertext,
obj.tag,
), nil
}
// FullSerialize serializes an object using the full JSON serialization format.
func (obj JSONWebEncryption) FullSerialize() string {
raw := rawJSONWebEncryption{
Unprotected: obj.unprotected,
Iv: newBuffer(obj.iv),
Ciphertext: newBuffer(obj.ciphertext),
EncryptedKey: newBuffer(obj.recipients[0].encryptedKey),
Tag: newBuffer(obj.tag),
Aad: newBuffer(obj.aad),
Recipients: []rawRecipientInfo{},
}
if len(obj.recipients) > 1 {
for _, recipient := range obj.recipients {
info := rawRecipientInfo{
Header: recipient.header,
EncryptedKey: base64.RawURLEncoding.EncodeToString(recipient.encryptedKey),
}
raw.Recipients = append(raw.Recipients, info)
}
} else {
// Use flattened serialization
raw.Header = obj.recipients[0].header
raw.EncryptedKey = newBuffer(obj.recipients[0].encryptedKey)
}
if obj.protected != nil {
raw.Protected = newBuffer(mustSerializeJSON(obj.protected))
}
return string(mustSerializeJSON(raw))
}

812
vendor/github.com/go-jose/go-jose/v3/jwk.go generated vendored Normal file
View File

@ -0,0 +1,812 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"math/big"
"net/url"
"reflect"
"strings"
"github.com/go-jose/go-jose/v3/json"
)
// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.
type rawJSONWebKey struct {
Use string `json:"use,omitempty"`
Kty string `json:"kty,omitempty"`
Kid string `json:"kid,omitempty"`
Crv string `json:"crv,omitempty"`
Alg string `json:"alg,omitempty"`
K *byteBuffer `json:"k,omitempty"`
X *byteBuffer `json:"x,omitempty"`
Y *byteBuffer `json:"y,omitempty"`
N *byteBuffer `json:"n,omitempty"`
E *byteBuffer `json:"e,omitempty"`
// -- Following fields are only used for private keys --
// RSA uses D, P and Q, while ECDSA uses only D. Fields Dp, Dq, and Qi are
// completely optional. Therefore for RSA/ECDSA, D != nil is a contract that
// we have a private key whereas D == nil means we have only a public key.
D *byteBuffer `json:"d,omitempty"`
P *byteBuffer `json:"p,omitempty"`
Q *byteBuffer `json:"q,omitempty"`
Dp *byteBuffer `json:"dp,omitempty"`
Dq *byteBuffer `json:"dq,omitempty"`
Qi *byteBuffer `json:"qi,omitempty"`
// Certificates
X5c []string `json:"x5c,omitempty"`
X5u string `json:"x5u,omitempty"`
X5tSHA1 string `json:"x5t,omitempty"`
X5tSHA256 string `json:"x5t#S256,omitempty"`
}
// JSONWebKey represents a public or private key in JWK format. It can be
// marshaled into JSON and unmarshaled from JSON.
type JSONWebKey struct {
// Key is the Go in-memory representation of this key. It must have one
// of these types:
// - ed25519.PublicKey
// - ed25519.PrivateKey
// - *ecdsa.PublicKey
// - *ecdsa.PrivateKey
// - *rsa.PublicKey
// - *rsa.PrivateKey
// - []byte (a symmetric key)
//
// When marshaling this JSONWebKey into JSON, the "kty" header parameter
// will be automatically set based on the type of this field.
Key interface{}
// Key identifier, parsed from `kid` header.
KeyID string
// Key algorithm, parsed from `alg` header.
Algorithm string
// Key use, parsed from `use` header.
Use string
// X.509 certificate chain, parsed from `x5c` header.
Certificates []*x509.Certificate
// X.509 certificate URL, parsed from `x5u` header.
CertificatesURL *url.URL
// X.509 certificate thumbprint (SHA-1), parsed from `x5t` header.
CertificateThumbprintSHA1 []byte
// X.509 certificate thumbprint (SHA-256), parsed from `x5t#S256` header.
CertificateThumbprintSHA256 []byte
}
// MarshalJSON serializes the given key to its JSON representation.
func (k JSONWebKey) MarshalJSON() ([]byte, error) {
var raw *rawJSONWebKey
var err error
switch key := k.Key.(type) {
case ed25519.PublicKey:
raw = fromEdPublicKey(key)
case *ecdsa.PublicKey:
raw, err = fromEcPublicKey(key)
case *rsa.PublicKey:
raw = fromRsaPublicKey(key)
case ed25519.PrivateKey:
raw, err = fromEdPrivateKey(key)
case *ecdsa.PrivateKey:
raw, err = fromEcPrivateKey(key)
case *rsa.PrivateKey:
raw, err = fromRsaPrivateKey(key)
case []byte:
raw, err = fromSymmetricKey(key)
default:
return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
}
if err != nil {
return nil, err
}
raw.Kid = k.KeyID
raw.Alg = k.Algorithm
raw.Use = k.Use
for _, cert := range k.Certificates {
raw.X5c = append(raw.X5c, base64.StdEncoding.EncodeToString(cert.Raw))
}
x5tSHA1Len := len(k.CertificateThumbprintSHA1)
x5tSHA256Len := len(k.CertificateThumbprintSHA256)
if x5tSHA1Len > 0 {
if x5tSHA1Len != sha1.Size {
return nil, fmt.Errorf("go-jose/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)", sha1.Size, x5tSHA1Len)
}
raw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1)
}
if x5tSHA256Len > 0 {
if x5tSHA256Len != sha256.Size {
return nil, fmt.Errorf("go-jose/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)", sha256.Size, x5tSHA256Len)
}
raw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256)
}
// If cert chain is attached (as opposed to being behind a URL), check the
// keys thumbprints to make sure they match what is expected. This is to
// ensure we don't accidentally produce a JWK with semantically inconsistent
// data in the headers.
if len(k.Certificates) > 0 {
expectedSHA1 := sha1.Sum(k.Certificates[0].Raw)
expectedSHA256 := sha256.Sum256(k.Certificates[0].Raw)
if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) {
return nil, errors.New("go-jose/go-jose: invalid SHA-1 thumbprint, does not match cert chain")
}
if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) {
return nil, errors.New("go-jose/go-jose: invalid or SHA-256 thumbprint, does not match cert chain")
}
}
if k.CertificatesURL != nil {
raw.X5u = k.CertificatesURL.String()
}
return json.Marshal(raw)
}
// UnmarshalJSON reads a key from its JSON representation.
func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
var raw rawJSONWebKey
err = json.Unmarshal(data, &raw)
if err != nil {
return err
}
certs, err := parseCertificateChain(raw.X5c)
if err != nil {
return fmt.Errorf("go-jose/go-jose: failed to unmarshal x5c field: %s", err)
}
var key interface{}
var certPub interface{}
var keyPub interface{}
if len(certs) > 0 {
// We need to check that leaf public key matches the key embedded in this
// JWK, as required by the standard (see RFC 7517, Section 4.7). Otherwise
// the JWK parsed could be semantically invalid. Technically, should also
// check key usage fields and other extensions on the cert here, but the
// standard doesn't exactly explain how they're supposed to map from the
// JWK representation to the X.509 extensions.
certPub = certs[0].PublicKey
}
switch raw.Kty {
case "EC":
if raw.D != nil {
key, err = raw.ecPrivateKey()
if err == nil {
keyPub = key.(*ecdsa.PrivateKey).Public()
}
} else {
key, err = raw.ecPublicKey()
keyPub = key
}
case "RSA":
if raw.D != nil {
key, err = raw.rsaPrivateKey()
if err == nil {
keyPub = key.(*rsa.PrivateKey).Public()
}
} else {
key, err = raw.rsaPublicKey()
keyPub = key
}
case "oct":
if certPub != nil {
return errors.New("go-jose/go-jose: invalid JWK, found 'oct' (symmetric) key with cert chain")
}
key, err = raw.symmetricKey()
case "OKP":
if raw.Crv == "Ed25519" && raw.X != nil {
if raw.D != nil {
key, err = raw.edPrivateKey()
if err == nil {
keyPub = key.(ed25519.PrivateKey).Public()
}
} else {
key, err = raw.edPublicKey()
keyPub = key
}
} else {
err = fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv)
}
default:
err = fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty)
}
if err != nil {
return
}
if certPub != nil && keyPub != nil {
if !reflect.DeepEqual(certPub, keyPub) {
return errors.New("go-jose/go-jose: invalid JWK, public keys in key and x5c fields do not match")
}
}
*k = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use, Certificates: certs}
if raw.X5u != "" {
k.CertificatesURL, err = url.Parse(raw.X5u)
if err != nil {
return fmt.Errorf("go-jose/go-jose: invalid JWK, x5u header is invalid URL: %w", err)
}
}
// x5t parameters are base64url-encoded SHA thumbprints
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1)
if err != nil {
return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding")
}
// RFC 7517, Section 4.8 is ambiguous as to whether the digest output should be byte or hex,
// for this reason, after base64 decoding, if the size is sha1.Size it's likely that the value is a byte encoded
// checksum so we skip this. Otherwise if the checksum was hex encoded we expect a 40 byte sized array so we'll
// try to hex decode it. When Marshalling this value we'll always use a base64 encoded version of byte format checksum.
if len(x5tSHA1bytes) == 2*sha1.Size {
hx, err := hex.DecodeString(string(x5tSHA1bytes))
if err != nil {
return fmt.Errorf("go-jose/go-jose: invalid JWK, unable to hex decode x5t: %v", err)
}
x5tSHA1bytes = hx
}
k.CertificateThumbprintSHA1 = x5tSHA1bytes
x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256)
if err != nil {
return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
}
if len(x5tSHA256bytes) == 2*sha256.Size {
hx256, err := hex.DecodeString(string(x5tSHA256bytes))
if err != nil {
return fmt.Errorf("go-jose/go-jose: invalid JWK, unable to hex decode x5t#S256: %v", err)
}
x5tSHA256bytes = hx256
}
k.CertificateThumbprintSHA256 = x5tSHA256bytes
x5tSHA1Len := len(k.CertificateThumbprintSHA1)
x5tSHA256Len := len(k.CertificateThumbprintSHA256)
if x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size {
return errors.New("go-jose/go-jose: invalid JWK, x5t header is of incorrect size")
}
if x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size {
return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header is of incorrect size")
}
// If certificate chain *and* thumbprints are set, verify correctness.
if len(k.Certificates) > 0 {
leaf := k.Certificates[0]
sha1sum := sha1.Sum(leaf.Raw)
sha256sum := sha256.Sum256(leaf.Raw)
if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(sha1sum[:], k.CertificateThumbprintSHA1) {
return errors.New("go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t value")
}
if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(sha256sum[:], k.CertificateThumbprintSHA256) {
return errors.New("go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t#S256 value")
}
}
return
}
// JSONWebKeySet represents a JWK Set object.
type JSONWebKeySet struct {
Keys []JSONWebKey `json:"keys"`
}
// Key convenience method returns keys by key ID. Specification states
// that a JWK Set "SHOULD" use distinct key IDs, but allows for some
// cases where they are not distinct. Hence method returns a slice
// of JSONWebKeys.
func (s *JSONWebKeySet) Key(kid string) []JSONWebKey {
var keys []JSONWebKey
for _, key := range s.Keys {
if key.KeyID == kid {
keys = append(keys, key)
}
}
return keys
}
const rsaThumbprintTemplate = `{"e":"%s","kty":"RSA","n":"%s"}`
const ecThumbprintTemplate = `{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`
const edThumbprintTemplate = `{"crv":"%s","kty":"OKP","x":"%s"}`
func ecThumbprintInput(curve elliptic.Curve, x, y *big.Int) (string, error) {
coordLength := curveSize(curve)
crv, err := curveName(curve)
if err != nil {
return "", err
}
if len(x.Bytes()) > coordLength || len(y.Bytes()) > coordLength {
return "", errors.New("go-jose/go-jose: invalid elliptic key (too large)")
}
return fmt.Sprintf(ecThumbprintTemplate, crv,
newFixedSizeBuffer(x.Bytes(), coordLength).base64(),
newFixedSizeBuffer(y.Bytes(), coordLength).base64()), nil
}
func rsaThumbprintInput(n *big.Int, e int) (string, error) {
return fmt.Sprintf(rsaThumbprintTemplate,
newBufferFromInt(uint64(e)).base64(),
newBuffer(n.Bytes()).base64()), nil
}
func edThumbprintInput(ed ed25519.PublicKey) (string, error) {
crv := "Ed25519"
if len(ed) > 32 {
return "", errors.New("go-jose/go-jose: invalid elliptic key (too large)")
}
return fmt.Sprintf(edThumbprintTemplate, crv,
newFixedSizeBuffer(ed, 32).base64()), nil
}
// Thumbprint computes the JWK Thumbprint of a key using the
// indicated hash algorithm.
func (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
var input string
var err error
switch key := k.Key.(type) {
case ed25519.PublicKey:
input, err = edThumbprintInput(key)
case *ecdsa.PublicKey:
input, err = ecThumbprintInput(key.Curve, key.X, key.Y)
case *ecdsa.PrivateKey:
input, err = ecThumbprintInput(key.Curve, key.X, key.Y)
case *rsa.PublicKey:
input, err = rsaThumbprintInput(key.N, key.E)
case *rsa.PrivateKey:
input, err = rsaThumbprintInput(key.N, key.E)
case ed25519.PrivateKey:
input, err = edThumbprintInput(ed25519.PublicKey(key[32:]))
case OpaqueSigner:
return key.Public().Thumbprint(hash)
default:
return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
}
if err != nil {
return nil, err
}
h := hash.New()
_, _ = h.Write([]byte(input))
return h.Sum(nil), nil
}
// IsPublic returns true if the JWK represents a public key (not symmetric, not private).
func (k *JSONWebKey) IsPublic() bool {
switch k.Key.(type) {
case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
return true
default:
return false
}
}
// Public creates JSONWebKey with corresponding public key if JWK represents asymmetric private key.
func (k *JSONWebKey) Public() JSONWebKey {
if k.IsPublic() {
return *k
}
ret := *k
switch key := k.Key.(type) {
case *ecdsa.PrivateKey:
ret.Key = key.Public()
case *rsa.PrivateKey:
ret.Key = key.Public()
case ed25519.PrivateKey:
ret.Key = key.Public()
default:
return JSONWebKey{} // returning invalid key
}
return ret
}
// Valid checks that the key contains the expected parameters.
func (k *JSONWebKey) Valid() bool {
if k.Key == nil {
return false
}
switch key := k.Key.(type) {
case *ecdsa.PublicKey:
if key.Curve == nil || key.X == nil || key.Y == nil {
return false
}
case *ecdsa.PrivateKey:
if key.Curve == nil || key.X == nil || key.Y == nil || key.D == nil {
return false
}
case *rsa.PublicKey:
if key.N == nil || key.E == 0 {
return false
}
case *rsa.PrivateKey:
if key.N == nil || key.E == 0 || key.D == nil || len(key.Primes) < 2 {
return false
}
case ed25519.PublicKey:
if len(key) != 32 {
return false
}
case ed25519.PrivateKey:
if len(key) != 64 {
return false
}
default:
return false
}
return true
}
func (key rawJSONWebKey) rsaPublicKey() (*rsa.PublicKey, error) {
if key.N == nil || key.E == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid RSA key, missing n/e values")
}
return &rsa.PublicKey{
N: key.N.bigInt(),
E: key.E.toInt(),
}, nil
}
func fromEdPublicKey(pub ed25519.PublicKey) *rawJSONWebKey {
return &rawJSONWebKey{
Kty: "OKP",
Crv: "Ed25519",
X: newBuffer(pub),
}
}
func fromRsaPublicKey(pub *rsa.PublicKey) *rawJSONWebKey {
return &rawJSONWebKey{
Kty: "RSA",
N: newBuffer(pub.N.Bytes()),
E: newBufferFromInt(uint64(pub.E)),
}
}
func (key rawJSONWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
var curve elliptic.Curve
switch key.Crv {
case "P-256":
curve = elliptic.P256()
case "P-384":
curve = elliptic.P384()
case "P-521":
curve = elliptic.P521()
default:
return nil, fmt.Errorf("go-jose/go-jose: unsupported elliptic curve '%s'", key.Crv)
}
if key.X == nil || key.Y == nil {
return nil, errors.New("go-jose/go-jose: invalid EC key, missing x/y values")
}
// The length of this octet string MUST be the full size of a coordinate for
// the curve specified in the "crv" parameter.
// https://tools.ietf.org/html/rfc7518#section-6.2.1.2
if curveSize(curve) != len(key.X.data) {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC public key, wrong length for x")
}
if curveSize(curve) != len(key.Y.data) {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC public key, wrong length for y")
}
x := key.X.bigInt()
y := key.Y.bigInt()
if !curve.IsOnCurve(x, y) {
return nil, errors.New("go-jose/go-jose: invalid EC key, X/Y are not on declared curve")
}
return &ecdsa.PublicKey{
Curve: curve,
X: x,
Y: y,
}, nil
}
func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC key (nil, or X/Y missing)")
}
name, err := curveName(pub.Curve)
if err != nil {
return nil, err
}
size := curveSize(pub.Curve)
xBytes := pub.X.Bytes()
yBytes := pub.Y.Bytes()
if len(xBytes) > size || len(yBytes) > size {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC key (X/Y too large)")
}
key := &rawJSONWebKey{
Kty: "EC",
Crv: name,
X: newFixedSizeBuffer(xBytes, size),
Y: newFixedSizeBuffer(yBytes, size),
}
return key, nil
}
func (key rawJSONWebKey) edPrivateKey() (ed25519.PrivateKey, error) {
var missing []string
switch {
case key.D == nil:
missing = append(missing, "D")
case key.X == nil:
missing = append(missing, "X")
}
if len(missing) > 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid Ed25519 private key, missing %s value(s)", strings.Join(missing, ", "))
}
privateKey := make([]byte, ed25519.PrivateKeySize)
copy(privateKey[0:32], key.D.bytes())
copy(privateKey[32:], key.X.bytes())
rv := ed25519.PrivateKey(privateKey)
return rv, nil
}
func (key rawJSONWebKey) edPublicKey() (ed25519.PublicKey, error) {
if key.X == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid Ed key, missing x value")
}
publicKey := make([]byte, ed25519.PublicKeySize)
copy(publicKey[0:32], key.X.bytes())
rv := ed25519.PublicKey(publicKey)
return rv, nil
}
func (key rawJSONWebKey) rsaPrivateKey() (*rsa.PrivateKey, error) {
var missing []string
switch {
case key.N == nil:
missing = append(missing, "N")
case key.E == nil:
missing = append(missing, "E")
case key.D == nil:
missing = append(missing, "D")
case key.P == nil:
missing = append(missing, "P")
case key.Q == nil:
missing = append(missing, "Q")
}
if len(missing) > 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid RSA private key, missing %s value(s)", strings.Join(missing, ", "))
}
rv := &rsa.PrivateKey{
PublicKey: rsa.PublicKey{
N: key.N.bigInt(),
E: key.E.toInt(),
},
D: key.D.bigInt(),
Primes: []*big.Int{
key.P.bigInt(),
key.Q.bigInt(),
},
}
if key.Dp != nil {
rv.Precomputed.Dp = key.Dp.bigInt()
}
if key.Dq != nil {
rv.Precomputed.Dq = key.Dq.bigInt()
}
if key.Qi != nil {
rv.Precomputed.Qinv = key.Qi.bigInt()
}
err := rv.Validate()
return rv, err
}
func fromEdPrivateKey(ed ed25519.PrivateKey) (*rawJSONWebKey, error) {
raw := fromEdPublicKey(ed25519.PublicKey(ed[32:]))
raw.D = newBuffer(ed[0:32])
return raw, nil
}
func fromRsaPrivateKey(rsa *rsa.PrivateKey) (*rawJSONWebKey, error) {
if len(rsa.Primes) != 2 {
return nil, ErrUnsupportedKeyType
}
raw := fromRsaPublicKey(&rsa.PublicKey)
raw.D = newBuffer(rsa.D.Bytes())
raw.P = newBuffer(rsa.Primes[0].Bytes())
raw.Q = newBuffer(rsa.Primes[1].Bytes())
if rsa.Precomputed.Dp != nil {
raw.Dp = newBuffer(rsa.Precomputed.Dp.Bytes())
}
if rsa.Precomputed.Dq != nil {
raw.Dq = newBuffer(rsa.Precomputed.Dq.Bytes())
}
if rsa.Precomputed.Qinv != nil {
raw.Qi = newBuffer(rsa.Precomputed.Qinv.Bytes())
}
return raw, nil
}
func (key rawJSONWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {
var curve elliptic.Curve
switch key.Crv {
case "P-256":
curve = elliptic.P256()
case "P-384":
curve = elliptic.P384()
case "P-521":
curve = elliptic.P521()
default:
return nil, fmt.Errorf("go-jose/go-jose: unsupported elliptic curve '%s'", key.Crv)
}
if key.X == nil || key.Y == nil || key.D == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, missing x/y/d values")
}
// The length of this octet string MUST be the full size of a coordinate for
// the curve specified in the "crv" parameter.
// https://tools.ietf.org/html/rfc7518#section-6.2.1.2
if curveSize(curve) != len(key.X.data) {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for x")
}
if curveSize(curve) != len(key.Y.data) {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for y")
}
// https://tools.ietf.org/html/rfc7518#section-6.2.2.1
if dSize(curve) != len(key.D.data) {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for d")
}
x := key.X.bigInt()
y := key.Y.bigInt()
if !curve.IsOnCurve(x, y) {
return nil, errors.New("go-jose/go-jose: invalid EC key, X/Y are not on declared curve")
}
return &ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: curve,
X: x,
Y: y,
},
D: key.D.bigInt(),
}, nil
}
func fromEcPrivateKey(ec *ecdsa.PrivateKey) (*rawJSONWebKey, error) {
raw, err := fromEcPublicKey(&ec.PublicKey)
if err != nil {
return nil, err
}
if ec.D == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key")
}
raw.D = newFixedSizeBuffer(ec.D.Bytes(), dSize(ec.PublicKey.Curve))
return raw, nil
}
// dSize returns the size in octets for the "d" member of an elliptic curve
// private key.
// The length of this octet string MUST be ceiling(log-base-2(n)/8)
// octets (where n is the order of the curve).
// https://tools.ietf.org/html/rfc7518#section-6.2.2.1
func dSize(curve elliptic.Curve) int {
order := curve.Params().P
bitLen := order.BitLen()
size := bitLen / 8
if bitLen%8 != 0 {
size++
}
return size
}
func fromSymmetricKey(key []byte) (*rawJSONWebKey, error) {
return &rawJSONWebKey{
Kty: "oct",
K: newBuffer(key),
}, nil
}
func (key rawJSONWebKey) symmetricKey() ([]byte, error) {
if key.K == nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid OCT (symmetric) key, missing k value")
}
return key.K.bytes(), nil
}
func tryJWKS(key interface{}, headers ...Header) interface{} {
var jwks JSONWebKeySet
switch jwksType := key.(type) {
case *JSONWebKeySet:
jwks = *jwksType
case JSONWebKeySet:
jwks = jwksType
default:
return key
}
var kid string
for _, header := range headers {
if header.KeyID != "" {
kid = header.KeyID
break
}
}
if kid == "" {
return key
}
keys := jwks.Key(kid)
if len(keys) == 0 {
return key
}
return keys[0].Key
}

369
vendor/github.com/go-jose/go-jose/v3/jws.go generated vendored Normal file
View File

@ -0,0 +1,369 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"strings"
"github.com/go-jose/go-jose/v3/json"
)
// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
type rawJSONWebSignature struct {
Payload *byteBuffer `json:"payload,omitempty"`
Signatures []rawSignatureInfo `json:"signatures,omitempty"`
Protected *byteBuffer `json:"protected,omitempty"`
Header *rawHeader `json:"header,omitempty"`
Signature *byteBuffer `json:"signature,omitempty"`
}
// rawSignatureInfo represents a single JWS signature over the JWS payload and protected header.
type rawSignatureInfo struct {
Protected *byteBuffer `json:"protected,omitempty"`
Header *rawHeader `json:"header,omitempty"`
Signature *byteBuffer `json:"signature,omitempty"`
}
// JSONWebSignature represents a signed JWS object after parsing.
type JSONWebSignature struct {
payload []byte
// Signatures attached to this object (may be more than one for multi-sig).
// Be careful about accessing these directly, prefer to use Verify() or
// VerifyMulti() to ensure that the data you're getting is verified.
Signatures []Signature
}
// Signature represents a single signature over the JWS payload and protected header.
type Signature struct {
// Merged header fields. Contains both protected and unprotected header
// values. Prefer using Protected and Unprotected fields instead of this.
// Values in this header may or may not have been signed and in general
// should not be trusted.
Header Header
// Protected header. Values in this header were signed and
// will be verified as part of the signature verification process.
Protected Header
// Unprotected header. Values in this header were not signed
// and in general should not be trusted.
Unprotected Header
// The actual signature value
Signature []byte
protected *rawHeader
header *rawHeader
original *rawSignatureInfo
}
// ParseSigned parses a signed message in compact or JWS JSON Serialization format.
func ParseSigned(signature string) (*JSONWebSignature, error) {
signature = stripWhitespace(signature)
if strings.HasPrefix(signature, "{") {
return parseSignedFull(signature)
}
return parseSignedCompact(signature, nil)
}
// ParseDetached parses a signed message in compact serialization format with detached payload.
func ParseDetached(signature string, payload []byte) (*JSONWebSignature, error) {
if payload == nil {
return nil, errors.New("go-jose/go-jose: nil payload")
}
return parseSignedCompact(stripWhitespace(signature), payload)
}
// Get a header value
func (sig Signature) mergedHeaders() rawHeader {
out := rawHeader{}
out.merge(sig.protected)
out.merge(sig.header)
return out
}
// Compute data to be signed
func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature) ([]byte, error) {
var authData bytes.Buffer
protectedHeader := new(rawHeader)
if signature.original != nil && signature.original.Protected != nil {
if err := json.Unmarshal(signature.original.Protected.bytes(), protectedHeader); err != nil {
return nil, err
}
authData.WriteString(signature.original.Protected.base64())
} else if signature.protected != nil {
protectedHeader = signature.protected
authData.WriteString(base64.RawURLEncoding.EncodeToString(mustSerializeJSON(protectedHeader)))
}
needsBase64 := true
if protectedHeader != nil {
var err error
if needsBase64, err = protectedHeader.getB64(); err != nil {
needsBase64 = true
}
}
authData.WriteByte('.')
if needsBase64 {
authData.WriteString(base64.RawURLEncoding.EncodeToString(payload))
} else {
authData.Write(payload)
}
return authData.Bytes(), nil
}
// parseSignedFull parses a message in full format.
func parseSignedFull(input string) (*JSONWebSignature, error) {
var parsed rawJSONWebSignature
err := json.Unmarshal([]byte(input), &parsed)
if err != nil {
return nil, err
}
return parsed.sanitized()
}
// sanitized produces a cleaned-up JWS object from the raw JSON.
func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
if parsed.Payload == nil {
return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message")
}
obj := &JSONWebSignature{
payload: parsed.Payload.bytes(),
Signatures: make([]Signature, len(parsed.Signatures)),
}
if len(parsed.Signatures) == 0 {
// No signatures array, must be flattened serialization
signature := Signature{}
if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
signature.protected = &rawHeader{}
err := json.Unmarshal(parsed.Protected.bytes(), signature.protected)
if err != nil {
return nil, err
}
}
// Check that there is not a nonce in the unprotected header
if parsed.Header != nil && parsed.Header.getNonce() != "" {
return nil, ErrUnprotectedNonce
}
signature.header = parsed.Header
signature.Signature = parsed.Signature.bytes()
// Make a fake "original" rawSignatureInfo to store the unprocessed
// Protected header. This is necessary because the Protected header can
// contain arbitrary fields not registered as part of the spec. See
// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41#section-4
// If we unmarshal Protected into a rawHeader with its explicit list of fields,
// we cannot marshal losslessly. So we have to keep around the original bytes.
// This is used in computeAuthData, which will first attempt to use
// the original bytes of a protected header, and fall back on marshaling the
// header struct only if those bytes are not available.
signature.original = &rawSignatureInfo{
Protected: parsed.Protected,
Header: parsed.Header,
Signature: parsed.Signature,
}
var err error
signature.Header, err = signature.mergedHeaders().sanitized()
if err != nil {
return nil, err
}
if signature.header != nil {
signature.Unprotected, err = signature.header.sanitized()
if err != nil {
return nil, err
}
}
if signature.protected != nil {
signature.Protected, err = signature.protected.sanitized()
if err != nil {
return nil, err
}
}
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
jwk := signature.Header.JSONWebKey
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
return nil, errors.New("go-jose/go-jose: invalid embedded jwk, must be public key")
}
obj.Signatures = append(obj.Signatures, signature)
}
for i, sig := range parsed.Signatures {
if sig.Protected != nil && len(sig.Protected.bytes()) > 0 {
obj.Signatures[i].protected = &rawHeader{}
err := json.Unmarshal(sig.Protected.bytes(), obj.Signatures[i].protected)
if err != nil {
return nil, err
}
}
// Check that there is not a nonce in the unprotected header
if sig.Header != nil && sig.Header.getNonce() != "" {
return nil, ErrUnprotectedNonce
}
var err error
obj.Signatures[i].Header, err = obj.Signatures[i].mergedHeaders().sanitized()
if err != nil {
return nil, err
}
if obj.Signatures[i].header != nil {
obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized()
if err != nil {
return nil, err
}
}
if obj.Signatures[i].protected != nil {
obj.Signatures[i].Protected, err = obj.Signatures[i].protected.sanitized()
if err != nil {
return nil, err
}
}
obj.Signatures[i].Signature = sig.Signature.bytes()
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
jwk := obj.Signatures[i].Header.JSONWebKey
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
return nil, errors.New("go-jose/go-jose: invalid embedded jwk, must be public key")
}
// Copy value of sig
original := sig
obj.Signatures[i].header = sig.Header
obj.Signatures[i].original = &original
}
return obj, nil
}
// parseSignedCompact parses a message in compact format.
func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) {
parts := strings.Split(input, ".")
if len(parts) != 3 {
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
}
if parts[1] != "" && payload != nil {
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
}
rawProtected, err := base64URLDecode(parts[0])
if err != nil {
return nil, err
}
if payload == nil {
payload, err = base64URLDecode(parts[1])
if err != nil {
return nil, err
}
}
signature, err := base64URLDecode(parts[2])
if err != nil {
return nil, err
}
raw := &rawJSONWebSignature{
Payload: newBuffer(payload),
Protected: newBuffer(rawProtected),
Signature: newBuffer(signature),
}
return raw.sanitized()
}
func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) {
if len(obj.Signatures) != 1 || obj.Signatures[0].header != nil || obj.Signatures[0].protected == nil {
return "", ErrNotSupported
}
serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
var payload []byte
if !detached {
payload = obj.payload
}
return base64JoinWithDots(
serializedProtected,
payload,
obj.Signatures[0].Signature,
), nil
}
// CompactSerialize serializes an object using the compact serialization format.
func (obj JSONWebSignature) CompactSerialize() (string, error) {
return obj.compactSerialize(false)
}
// DetachedCompactSerialize serializes an object using the compact serialization format with detached payload.
func (obj JSONWebSignature) DetachedCompactSerialize() (string, error) {
return obj.compactSerialize(true)
}
// FullSerialize serializes an object using the full JSON serialization format.
func (obj JSONWebSignature) FullSerialize() string {
raw := rawJSONWebSignature{
Payload: newBuffer(obj.payload),
}
if len(obj.Signatures) == 1 {
if obj.Signatures[0].protected != nil {
serializedProtected := mustSerializeJSON(obj.Signatures[0].protected)
raw.Protected = newBuffer(serializedProtected)
}
raw.Header = obj.Signatures[0].header
raw.Signature = newBuffer(obj.Signatures[0].Signature)
} else {
raw.Signatures = make([]rawSignatureInfo, len(obj.Signatures))
for i, signature := range obj.Signatures {
raw.Signatures[i] = rawSignatureInfo{
Header: signature.header,
Signature: newBuffer(signature.Signature),
}
if signature.protected != nil {
raw.Signatures[i].Protected = newBuffer(mustSerializeJSON(signature.protected))
}
}
}
return string(mustSerializeJSON(raw))
}

144
vendor/github.com/go-jose/go-jose/v3/opaque.go generated vendored Normal file
View File

@ -0,0 +1,144 @@
/*-
* Copyright 2018 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
// OpaqueSigner is an interface that supports signing payloads with opaque
// private key(s). Private key operations performed by implementers may, for
// example, occur in a hardware module. An OpaqueSigner may rotate signing keys
// transparently to the user of this interface.
type OpaqueSigner interface {
// Public returns the public key of the current signing key.
Public() *JSONWebKey
// Algs returns a list of supported signing algorithms.
Algs() []SignatureAlgorithm
// SignPayload signs a payload with the current signing key using the given
// algorithm.
SignPayload(payload []byte, alg SignatureAlgorithm) ([]byte, error)
}
type opaqueSigner struct {
signer OpaqueSigner
}
func newOpaqueSigner(alg SignatureAlgorithm, signer OpaqueSigner) (recipientSigInfo, error) {
var algSupported bool
for _, salg := range signer.Algs() {
if alg == salg {
algSupported = true
break
}
}
if !algSupported {
return recipientSigInfo{}, ErrUnsupportedAlgorithm
}
return recipientSigInfo{
sigAlg: alg,
publicKey: signer.Public,
signer: &opaqueSigner{
signer: signer,
},
}, nil
}
func (o *opaqueSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
out, err := o.signer.SignPayload(payload, alg)
if err != nil {
return Signature{}, err
}
return Signature{
Signature: out,
protected: &rawHeader{},
}, nil
}
// OpaqueVerifier is an interface that supports verifying payloads with opaque
// public key(s). An OpaqueSigner may rotate signing keys transparently to the
// user of this interface.
type OpaqueVerifier interface {
VerifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
}
type opaqueVerifier struct {
verifier OpaqueVerifier
}
func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
return o.verifier.VerifyPayload(payload, signature, alg)
}
// OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key.
type OpaqueKeyEncrypter interface {
// KeyID returns the kid
KeyID() string
// Algs returns a list of supported key encryption algorithms.
Algs() []KeyAlgorithm
// encryptKey encrypts the CEK using the given algorithm.
encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error)
}
type opaqueKeyEncrypter struct {
encrypter OpaqueKeyEncrypter
}
func newOpaqueKeyEncrypter(alg KeyAlgorithm, encrypter OpaqueKeyEncrypter) (recipientKeyInfo, error) {
var algSupported bool
for _, salg := range encrypter.Algs() {
if alg == salg {
algSupported = true
break
}
}
if !algSupported {
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
}
return recipientKeyInfo{
keyID: encrypter.KeyID(),
keyAlg: alg,
keyEncrypter: &opaqueKeyEncrypter{
encrypter: encrypter,
},
}, nil
}
func (oke *opaqueKeyEncrypter) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
return oke.encrypter.encryptKey(cek, alg)
}
// OpaqueKeyDecrypter is an interface that supports decrypting keys with an opaque key.
type OpaqueKeyDecrypter interface {
DecryptKey(encryptedKey []byte, header Header) ([]byte, error)
}
type opaqueKeyDecrypter struct {
decrypter OpaqueKeyDecrypter
}
func (okd *opaqueKeyDecrypter) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
mergedHeaders := rawHeader{}
mergedHeaders.merge(&headers)
mergedHeaders.merge(recipient.header)
header, err := mergedHeaders.sanitized()
if err != nil {
return nil, err
}
return okd.decrypter.DecryptKey(recipient.encryptedKey, header)
}

525
vendor/github.com/go-jose/go-jose/v3/shared.go generated vendored Normal file
View File

@ -0,0 +1,525 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"crypto/elliptic"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"github.com/go-jose/go-jose/v3/json"
)
// KeyAlgorithm represents a key management algorithm.
type KeyAlgorithm string
// SignatureAlgorithm represents a signature (or MAC) algorithm.
type SignatureAlgorithm string
// ContentEncryption represents a content encryption algorithm.
type ContentEncryption string
// CompressionAlgorithm represents an algorithm used for plaintext compression.
type CompressionAlgorithm string
// ContentType represents type of the contained data.
type ContentType string
var (
// ErrCryptoFailure represents an error in cryptographic primitive. This
// occurs when, for example, a message had an invalid authentication tag or
// could not be decrypted.
ErrCryptoFailure = errors.New("go-jose/go-jose: error in cryptographic primitive")
// ErrUnsupportedAlgorithm indicates that a selected algorithm is not
// supported. This occurs when trying to instantiate an encrypter for an
// algorithm that is not yet implemented.
ErrUnsupportedAlgorithm = errors.New("go-jose/go-jose: unknown/unsupported algorithm")
// ErrUnsupportedKeyType indicates that the given key type/format is not
// supported. This occurs when trying to instantiate an encrypter and passing
// it a key of an unrecognized type or with unsupported parameters, such as
// an RSA private key with more than two primes.
ErrUnsupportedKeyType = errors.New("go-jose/go-jose: unsupported key type/format")
// ErrInvalidKeySize indicates that the given key is not the correct size
// for the selected algorithm. This can occur, for example, when trying to
// encrypt with AES-256 but passing only a 128-bit key as input.
ErrInvalidKeySize = errors.New("go-jose/go-jose: invalid key size for algorithm")
// ErrNotSupported serialization of object is not supported. This occurs when
// trying to compact-serialize an object which can't be represented in
// compact form.
ErrNotSupported = errors.New("go-jose/go-jose: compact serialization not supported for object")
// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
// nonce header parameter was included in an unprotected header object.
ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header")
)
// Key management algorithms
const (
ED25519 = KeyAlgorithm("ED25519")
RSA1_5 = KeyAlgorithm("RSA1_5") // RSA-PKCS1v1.5
RSA_OAEP = KeyAlgorithm("RSA-OAEP") // RSA-OAEP-SHA1
RSA_OAEP_256 = KeyAlgorithm("RSA-OAEP-256") // RSA-OAEP-SHA256
A128KW = KeyAlgorithm("A128KW") // AES key wrap (128)
A192KW = KeyAlgorithm("A192KW") // AES key wrap (192)
A256KW = KeyAlgorithm("A256KW") // AES key wrap (256)
DIRECT = KeyAlgorithm("dir") // Direct encryption
ECDH_ES = KeyAlgorithm("ECDH-ES") // ECDH-ES
ECDH_ES_A128KW = KeyAlgorithm("ECDH-ES+A128KW") // ECDH-ES + AES key wrap (128)
ECDH_ES_A192KW = KeyAlgorithm("ECDH-ES+A192KW") // ECDH-ES + AES key wrap (192)
ECDH_ES_A256KW = KeyAlgorithm("ECDH-ES+A256KW") // ECDH-ES + AES key wrap (256)
A128GCMKW = KeyAlgorithm("A128GCMKW") // AES-GCM key wrap (128)
A192GCMKW = KeyAlgorithm("A192GCMKW") // AES-GCM key wrap (192)
A256GCMKW = KeyAlgorithm("A256GCMKW") // AES-GCM key wrap (256)
PBES2_HS256_A128KW = KeyAlgorithm("PBES2-HS256+A128KW") // PBES2 + HMAC-SHA256 + AES key wrap (128)
PBES2_HS384_A192KW = KeyAlgorithm("PBES2-HS384+A192KW") // PBES2 + HMAC-SHA384 + AES key wrap (192)
PBES2_HS512_A256KW = KeyAlgorithm("PBES2-HS512+A256KW") // PBES2 + HMAC-SHA512 + AES key wrap (256)
)
// Signature algorithms
const (
EdDSA = SignatureAlgorithm("EdDSA")
HS256 = SignatureAlgorithm("HS256") // HMAC using SHA-256
HS384 = SignatureAlgorithm("HS384") // HMAC using SHA-384
HS512 = SignatureAlgorithm("HS512") // HMAC using SHA-512
RS256 = SignatureAlgorithm("RS256") // RSASSA-PKCS-v1.5 using SHA-256
RS384 = SignatureAlgorithm("RS384") // RSASSA-PKCS-v1.5 using SHA-384
RS512 = SignatureAlgorithm("RS512") // RSASSA-PKCS-v1.5 using SHA-512
ES256 = SignatureAlgorithm("ES256") // ECDSA using P-256 and SHA-256
ES384 = SignatureAlgorithm("ES384") // ECDSA using P-384 and SHA-384
ES512 = SignatureAlgorithm("ES512") // ECDSA using P-521 and SHA-512
PS256 = SignatureAlgorithm("PS256") // RSASSA-PSS using SHA256 and MGF1-SHA256
PS384 = SignatureAlgorithm("PS384") // RSASSA-PSS using SHA384 and MGF1-SHA384
PS512 = SignatureAlgorithm("PS512") // RSASSA-PSS using SHA512 and MGF1-SHA512
)
// Content encryption algorithms
const (
A128CBC_HS256 = ContentEncryption("A128CBC-HS256") // AES-CBC + HMAC-SHA256 (128)
A192CBC_HS384 = ContentEncryption("A192CBC-HS384") // AES-CBC + HMAC-SHA384 (192)
A256CBC_HS512 = ContentEncryption("A256CBC-HS512") // AES-CBC + HMAC-SHA512 (256)
A128GCM = ContentEncryption("A128GCM") // AES-GCM (128)
A192GCM = ContentEncryption("A192GCM") // AES-GCM (192)
A256GCM = ContentEncryption("A256GCM") // AES-GCM (256)
)
// Compression algorithms
const (
NONE = CompressionAlgorithm("") // No compression
DEFLATE = CompressionAlgorithm("DEF") // DEFLATE (RFC 1951)
)
// A key in the protected header of a JWS object. Use of the Header...
// constants is preferred to enhance type safety.
type HeaderKey string
const (
HeaderType = "typ" // string
HeaderContentType = "cty" // string
// These are set by go-jose and shouldn't need to be set by consumers of the
// library.
headerAlgorithm = "alg" // string
headerEncryption = "enc" // ContentEncryption
headerCompression = "zip" // CompressionAlgorithm
headerCritical = "crit" // []string
headerAPU = "apu" // *byteBuffer
headerAPV = "apv" // *byteBuffer
headerEPK = "epk" // *JSONWebKey
headerIV = "iv" // *byteBuffer
headerTag = "tag" // *byteBuffer
headerX5c = "x5c" // []*x509.Certificate
headerJWK = "jwk" // *JSONWebKey
headerKeyID = "kid" // string
headerNonce = "nonce" // string
headerB64 = "b64" // bool
headerP2C = "p2c" // *byteBuffer (int)
headerP2S = "p2s" // *byteBuffer ([]byte)
)
// supportedCritical is the set of supported extensions that are understood and processed.
var supportedCritical = map[string]bool{
headerB64: true,
}
// rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).
//
// The decoding of the constituent items is deferred because we want to marshal
// some members into particular structs rather than generic maps, but at the
// same time we need to receive any extra fields unhandled by this library to
// pass through to consuming code in case it wants to examine them.
type rawHeader map[HeaderKey]*json.RawMessage
// Header represents the read-only JOSE header for JWE/JWS objects.
type Header struct {
KeyID string
JSONWebKey *JSONWebKey
Algorithm string
Nonce string
// Unverified certificate chain parsed from x5c header.
certificates []*x509.Certificate
// At parse time, each header parameter with a name other than "kid",
// "jwk", "alg", "nonce", or "x5c" will have its value passed to
// [json.Unmarshal] to unmarshal it into an interface value.
// The resulting value will be stored in this map, with the header
// parameter name as the key.
//
// [json.Unmarshal]: https://pkg.go.dev/encoding/json#Unmarshal
ExtraHeaders map[HeaderKey]interface{}
}
// Certificates verifies & returns the certificate chain present
// in the x5c header field of a message, if one was present. Returns
// an error if there was no x5c header present or the chain could
// not be validated with the given verify options.
func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
if len(h.certificates) == 0 {
return nil, errors.New("go-jose/go-jose: no x5c header present in message")
}
leaf := h.certificates[0]
if opts.Intermediates == nil {
opts.Intermediates = x509.NewCertPool()
for _, intermediate := range h.certificates[1:] {
opts.Intermediates.AddCert(intermediate)
}
}
return leaf.Verify(opts)
}
func (parsed rawHeader) set(k HeaderKey, v interface{}) error {
b, err := json.Marshal(v)
if err != nil {
return err
}
parsed[k] = makeRawMessage(b)
return nil
}
// getString gets a string from the raw JSON, defaulting to "".
func (parsed rawHeader) getString(k HeaderKey) string {
v, ok := parsed[k]
if !ok || v == nil {
return ""
}
var s string
err := json.Unmarshal(*v, &s)
if err != nil {
return ""
}
return s
}
// getByteBuffer gets a byte buffer from the raw JSON. Returns (nil, nil) if
// not specified.
func (parsed rawHeader) getByteBuffer(k HeaderKey) (*byteBuffer, error) {
v := parsed[k]
if v == nil {
return nil, nil
}
var bb *byteBuffer
err := json.Unmarshal(*v, &bb)
if err != nil {
return nil, err
}
return bb, nil
}
// getAlgorithm extracts parsed "alg" from the raw JSON as a KeyAlgorithm.
func (parsed rawHeader) getAlgorithm() KeyAlgorithm {
return KeyAlgorithm(parsed.getString(headerAlgorithm))
}
// getSignatureAlgorithm extracts parsed "alg" from the raw JSON as a SignatureAlgorithm.
func (parsed rawHeader) getSignatureAlgorithm() SignatureAlgorithm {
return SignatureAlgorithm(parsed.getString(headerAlgorithm))
}
// getEncryption extracts parsed "enc" from the raw JSON.
func (parsed rawHeader) getEncryption() ContentEncryption {
return ContentEncryption(parsed.getString(headerEncryption))
}
// getCompression extracts parsed "zip" from the raw JSON.
func (parsed rawHeader) getCompression() CompressionAlgorithm {
return CompressionAlgorithm(parsed.getString(headerCompression))
}
func (parsed rawHeader) getNonce() string {
return parsed.getString(headerNonce)
}
// getEPK extracts parsed "epk" from the raw JSON.
func (parsed rawHeader) getEPK() (*JSONWebKey, error) {
v := parsed[headerEPK]
if v == nil {
return nil, nil
}
var epk *JSONWebKey
err := json.Unmarshal(*v, &epk)
if err != nil {
return nil, err
}
return epk, nil
}
// getAPU extracts parsed "apu" from the raw JSON.
func (parsed rawHeader) getAPU() (*byteBuffer, error) {
return parsed.getByteBuffer(headerAPU)
}
// getAPV extracts parsed "apv" from the raw JSON.
func (parsed rawHeader) getAPV() (*byteBuffer, error) {
return parsed.getByteBuffer(headerAPV)
}
// getIV extracts parsed "iv" from the raw JSON.
func (parsed rawHeader) getIV() (*byteBuffer, error) {
return parsed.getByteBuffer(headerIV)
}
// getTag extracts parsed "tag" from the raw JSON.
func (parsed rawHeader) getTag() (*byteBuffer, error) {
return parsed.getByteBuffer(headerTag)
}
// getJWK extracts parsed "jwk" from the raw JSON.
func (parsed rawHeader) getJWK() (*JSONWebKey, error) {
v := parsed[headerJWK]
if v == nil {
return nil, nil
}
var jwk *JSONWebKey
err := json.Unmarshal(*v, &jwk)
if err != nil {
return nil, err
}
return jwk, nil
}
// getCritical extracts parsed "crit" from the raw JSON. If omitted, it
// returns an empty slice.
func (parsed rawHeader) getCritical() ([]string, error) {
v := parsed[headerCritical]
if v == nil {
return nil, nil
}
var q []string
err := json.Unmarshal(*v, &q)
if err != nil {
return nil, err
}
return q, nil
}
// getS2C extracts parsed "p2c" from the raw JSON.
func (parsed rawHeader) getP2C() (int, error) {
v := parsed[headerP2C]
if v == nil {
return 0, nil
}
var p2c int
err := json.Unmarshal(*v, &p2c)
if err != nil {
return 0, err
}
return p2c, nil
}
// getS2S extracts parsed "p2s" from the raw JSON.
func (parsed rawHeader) getP2S() (*byteBuffer, error) {
return parsed.getByteBuffer(headerP2S)
}
// getB64 extracts parsed "b64" from the raw JSON, defaulting to true.
func (parsed rawHeader) getB64() (bool, error) {
v := parsed[headerB64]
if v == nil {
return true, nil
}
var b64 bool
err := json.Unmarshal(*v, &b64)
if err != nil {
return true, err
}
return b64, nil
}
// sanitized produces a cleaned-up header object from the raw JSON.
func (parsed rawHeader) sanitized() (h Header, err error) {
for k, v := range parsed {
if v == nil {
continue
}
switch k {
case headerJWK:
var jwk *JSONWebKey
err = json.Unmarshal(*v, &jwk)
if err != nil {
err = fmt.Errorf("failed to unmarshal JWK: %v: %#v", err, string(*v))
return
}
h.JSONWebKey = jwk
case headerKeyID:
var s string
err = json.Unmarshal(*v, &s)
if err != nil {
err = fmt.Errorf("failed to unmarshal key ID: %v: %#v", err, string(*v))
return
}
h.KeyID = s
case headerAlgorithm:
var s string
err = json.Unmarshal(*v, &s)
if err != nil {
err = fmt.Errorf("failed to unmarshal algorithm: %v: %#v", err, string(*v))
return
}
h.Algorithm = s
case headerNonce:
var s string
err = json.Unmarshal(*v, &s)
if err != nil {
err = fmt.Errorf("failed to unmarshal nonce: %v: %#v", err, string(*v))
return
}
h.Nonce = s
case headerX5c:
c := []string{}
err = json.Unmarshal(*v, &c)
if err != nil {
err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
return
}
h.certificates, err = parseCertificateChain(c)
if err != nil {
err = fmt.Errorf("failed to unmarshal x5c header: %v: %#v", err, string(*v))
return
}
default:
if h.ExtraHeaders == nil {
h.ExtraHeaders = map[HeaderKey]interface{}{}
}
var v2 interface{}
err = json.Unmarshal(*v, &v2)
if err != nil {
err = fmt.Errorf("failed to unmarshal value: %v: %#v", err, string(*v))
return
}
h.ExtraHeaders[k] = v2
}
}
return
}
func parseCertificateChain(chain []string) ([]*x509.Certificate, error) {
out := make([]*x509.Certificate, len(chain))
for i, cert := range chain {
raw, err := base64.StdEncoding.DecodeString(cert)
if err != nil {
return nil, err
}
out[i], err = x509.ParseCertificate(raw)
if err != nil {
return nil, err
}
}
return out, nil
}
func (parsed rawHeader) isSet(k HeaderKey) bool {
dvr := parsed[k]
if dvr == nil {
return false
}
var dv interface{}
err := json.Unmarshal(*dvr, &dv)
if err != nil {
return true
}
if dvStr, ok := dv.(string); ok {
return dvStr != ""
}
return true
}
// Merge headers from src into dst, giving precedence to headers from l.
func (parsed rawHeader) merge(src *rawHeader) {
if src == nil {
return
}
for k, v := range *src {
if parsed.isSet(k) {
continue
}
parsed[k] = v
}
}
// Get JOSE name of curve
func curveName(crv elliptic.Curve) (string, error) {
switch crv {
case elliptic.P256():
return "P-256", nil
case elliptic.P384():
return "P-384", nil
case elliptic.P521():
return "P-521", nil
default:
return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve")
}
}
// Get size of curve in bytes
func curveSize(crv elliptic.Curve) int {
bits := crv.Params().BitSize
div := bits / 8
mod := bits % 8
if mod == 0 {
return div
}
return div + 1
}
func makeRawMessage(b []byte) *json.RawMessage {
rm := json.RawMessage(b)
return &rm
}

487
vendor/github.com/go-jose/go-jose/v3/signing.go generated vendored Normal file
View File

@ -0,0 +1,487 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"bytes"
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"encoding/base64"
"errors"
"fmt"
"github.com/go-jose/go-jose/v3/json"
)
// NonceSource represents a source of random nonces to go into JWS objects
type NonceSource interface {
Nonce() (string, error)
}
// Signer represents a signer which takes a payload and produces a signed JWS object.
type Signer interface {
Sign(payload []byte) (*JSONWebSignature, error)
Options() SignerOptions
}
// SigningKey represents an algorithm/key used to sign a message.
//
// Key must have one of these types:
// - ed25519.PrivateKey
// - *ecdsa.PrivateKey
// - *rsa.PrivateKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (an HMAC key)
// - Any type that satisfies the OpaqueSigner interface
type SigningKey struct {
Algorithm SignatureAlgorithm
Key interface{}
}
// SignerOptions represents options that can be set when creating signers.
type SignerOptions struct {
NonceSource NonceSource
EmbedJWK bool
// Optional map of additional keys to be inserted into the protected header
// of a JWS object. Some specifications which make use of JWS like to insert
// additional values here.
//
// Values will be serialized by [json.Marshal] and must be valid inputs to
// that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
ExtraHeaders map[HeaderKey]interface{}
}
// WithHeader adds an arbitrary value to the ExtraHeaders map, initializing it
// if necessary, and returns the updated SignerOptions.
//
// The v argument will be serialized by [json.Marshal] and must be a valid
// input to that function.
//
// [json.Marshal]: https://pkg.go.dev/encoding/json#Marshal
func (so *SignerOptions) WithHeader(k HeaderKey, v interface{}) *SignerOptions {
if so.ExtraHeaders == nil {
so.ExtraHeaders = map[HeaderKey]interface{}{}
}
so.ExtraHeaders[k] = v
return so
}
// WithContentType adds a content type ("cty") header and returns the updated
// SignerOptions.
func (so *SignerOptions) WithContentType(contentType ContentType) *SignerOptions {
return so.WithHeader(HeaderContentType, contentType)
}
// WithType adds a type ("typ") header and returns the updated SignerOptions.
func (so *SignerOptions) WithType(typ ContentType) *SignerOptions {
return so.WithHeader(HeaderType, typ)
}
// WithCritical adds the given names to the critical ("crit") header and returns
// the updated SignerOptions.
func (so *SignerOptions) WithCritical(names ...string) *SignerOptions {
if so.ExtraHeaders[headerCritical] == nil {
so.WithHeader(headerCritical, make([]string, 0, len(names)))
}
crit := so.ExtraHeaders[headerCritical].([]string)
so.ExtraHeaders[headerCritical] = append(crit, names...)
return so
}
// WithBase64 adds a base64url-encode payload ("b64") header and returns the updated
// SignerOptions. When the "b64" value is "false", the payload is not base64 encoded.
func (so *SignerOptions) WithBase64(b64 bool) *SignerOptions {
if !b64 {
so.WithHeader(headerB64, b64)
so.WithCritical(headerB64)
}
return so
}
type payloadSigner interface {
signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error)
}
type payloadVerifier interface {
verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error
}
type genericSigner struct {
recipients []recipientSigInfo
nonceSource NonceSource
embedJWK bool
extraHeaders map[HeaderKey]interface{}
}
type recipientSigInfo struct {
sigAlg SignatureAlgorithm
publicKey func() *JSONWebKey
signer payloadSigner
}
func staticPublicKey(jwk *JSONWebKey) func() *JSONWebKey {
return func() *JSONWebKey {
return jwk
}
}
// NewSigner creates an appropriate signer based on the key type
func NewSigner(sig SigningKey, opts *SignerOptions) (Signer, error) {
return NewMultiSigner([]SigningKey{sig}, opts)
}
// NewMultiSigner creates a signer for multiple recipients
func NewMultiSigner(sigs []SigningKey, opts *SignerOptions) (Signer, error) {
signer := &genericSigner{recipients: []recipientSigInfo{}}
if opts != nil {
signer.nonceSource = opts.NonceSource
signer.embedJWK = opts.EmbedJWK
signer.extraHeaders = opts.ExtraHeaders
}
for _, sig := range sigs {
err := signer.addRecipient(sig.Algorithm, sig.Key)
if err != nil {
return nil, err
}
}
return signer, nil
}
// newVerifier creates a verifier based on the key type
func newVerifier(verificationKey interface{}) (payloadVerifier, error) {
switch verificationKey := verificationKey.(type) {
case ed25519.PublicKey:
return &edEncrypterVerifier{
publicKey: verificationKey,
}, nil
case *rsa.PublicKey:
return &rsaEncrypterVerifier{
publicKey: verificationKey,
}, nil
case *ecdsa.PublicKey:
return &ecEncrypterVerifier{
publicKey: verificationKey,
}, nil
case []byte:
return &symmetricMac{
key: verificationKey,
}, nil
case JSONWebKey:
return newVerifier(verificationKey.Key)
case *JSONWebKey:
return newVerifier(verificationKey.Key)
case OpaqueVerifier:
return &opaqueVerifier{verifier: verificationKey}, nil
default:
return nil, ErrUnsupportedKeyType
}
}
func (ctx *genericSigner) addRecipient(alg SignatureAlgorithm, signingKey interface{}) error {
recipient, err := makeJWSRecipient(alg, signingKey)
if err != nil {
return err
}
ctx.recipients = append(ctx.recipients, recipient)
return nil
}
func makeJWSRecipient(alg SignatureAlgorithm, signingKey interface{}) (recipientSigInfo, error) {
switch signingKey := signingKey.(type) {
case ed25519.PrivateKey:
return newEd25519Signer(alg, signingKey)
case *rsa.PrivateKey:
return newRSASigner(alg, signingKey)
case *ecdsa.PrivateKey:
return newECDSASigner(alg, signingKey)
case []byte:
return newSymmetricSigner(alg, signingKey)
case JSONWebKey:
return newJWKSigner(alg, signingKey)
case *JSONWebKey:
return newJWKSigner(alg, *signingKey)
case OpaqueSigner:
return newOpaqueSigner(alg, signingKey)
default:
return recipientSigInfo{}, ErrUnsupportedKeyType
}
}
func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigInfo, error) {
recipient, err := makeJWSRecipient(alg, signingKey.Key)
if err != nil {
return recipientSigInfo{}, err
}
if recipient.publicKey != nil && recipient.publicKey() != nil {
// recipient.publicKey is a JWK synthesized for embedding when recipientSigInfo
// was created for the inner key (such as a RSA or ECDSA public key). It contains
// the pub key for embedding, but doesn't have extra params like key id.
publicKey := signingKey
publicKey.Key = recipient.publicKey().Key
recipient.publicKey = staticPublicKey(&publicKey)
// This should be impossible, but let's check anyway.
if !recipient.publicKey().IsPublic() {
return recipientSigInfo{}, errors.New("go-jose/go-jose: public key was unexpectedly not public")
}
}
return recipient, nil
}
func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
obj := &JSONWebSignature{}
obj.payload = payload
obj.Signatures = make([]Signature, len(ctx.recipients))
for i, recipient := range ctx.recipients {
protected := map[HeaderKey]interface{}{
headerAlgorithm: string(recipient.sigAlg),
}
if recipient.publicKey != nil && recipient.publicKey() != nil {
// We want to embed the JWK or set the kid header, but not both. Having a protected
// header that contains an embedded JWK while also simultaneously containing the kid
// header is confusing, and at least in ACME the two are considered to be mutually
// exclusive. The fact that both can exist at the same time is a somewhat unfortunate
// result of the JOSE spec. We've decided that this library will only include one or
// the other to avoid this confusion.
//
// See https://github.com/go-jose/go-jose/issues/157 for more context.
if ctx.embedJWK {
protected[headerJWK] = recipient.publicKey()
} else {
keyID := recipient.publicKey().KeyID
if keyID != "" {
protected[headerKeyID] = keyID
}
}
}
if ctx.nonceSource != nil {
nonce, err := ctx.nonceSource.Nonce()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: Error generating nonce: %v", err)
}
protected[headerNonce] = nonce
}
for k, v := range ctx.extraHeaders {
protected[k] = v
}
serializedProtected := mustSerializeJSON(protected)
needsBase64 := true
if b64, ok := protected[headerB64]; ok {
if needsBase64, ok = b64.(bool); !ok {
return nil, errors.New("go-jose/go-jose: Invalid b64 header parameter")
}
}
var input bytes.Buffer
input.WriteString(base64.RawURLEncoding.EncodeToString(serializedProtected))
input.WriteByte('.')
if needsBase64 {
input.WriteString(base64.RawURLEncoding.EncodeToString(payload))
} else {
input.Write(payload)
}
signatureInfo, err := recipient.signer.signPayload(input.Bytes(), recipient.sigAlg)
if err != nil {
return nil, err
}
signatureInfo.protected = &rawHeader{}
for k, v := range protected {
b, err := json.Marshal(v)
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: Error marshalling item %#v: %v", k, err)
}
(*signatureInfo.protected)[k] = makeRawMessage(b)
}
obj.Signatures[i] = signatureInfo
}
return obj, nil
}
func (ctx *genericSigner) Options() SignerOptions {
return SignerOptions{
NonceSource: ctx.nonceSource,
EmbedJWK: ctx.embedJWK,
ExtraHeaders: ctx.extraHeaders,
}
}
// Verify validates the signature on the object and returns the payload.
// This function does not support multi-signature. If you desire multi-signature
// verification use VerifyMulti instead.
//
// Be careful when verifying signatures based on embedded JWKs inside the
// payload header. You cannot assume that the key received in a payload is
// trusted.
//
// The verificationKey argument must have one of these types:
// - ed25519.PublicKey
// - *ecdsa.PublicKey
// - *rsa.PublicKey
// - *JSONWebKey
// - JSONWebKey
// - []byte (an HMAC key)
// - Any type that implements the OpaqueVerifier interface.
func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) {
err := obj.DetachedVerify(obj.payload, verificationKey)
if err != nil {
return nil, err
}
return obj.payload, nil
}
// UnsafePayloadWithoutVerification returns the payload without
// verifying it. The content returned from this function cannot be
// trusted.
func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
return obj.payload
}
// DetachedVerify validates a detached signature on the given payload. In
// most cases, you will probably want to use Verify instead. DetachedVerify
// is only useful if you have a payload and signature that are separated from
// each other.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key)
if err != nil {
return err
}
if len(obj.Signatures) > 1 {
return errors.New("go-jose/go-jose: too many signatures in payload; expecting only one")
}
signature := obj.Signatures[0]
headers := signature.mergedHeaders()
critical, err := headers.getCritical()
if err != nil {
return err
}
for _, name := range critical {
if !supportedCritical[name] {
return ErrCryptoFailure
}
}
input, err := obj.computeAuthData(payload, &signature)
if err != nil {
return ErrCryptoFailure
}
alg := headers.getSignatureAlgorithm()
err = verifier.verifyPayload(input, signature.Signature, alg)
if err == nil {
return nil
}
return ErrCryptoFailure
}
// VerifyMulti validates (one of the multiple) signatures on the object and
// returns the index of the signature that was verified, along with the signature
// object and the payload. We return the signature and index to guarantee that
// callers are getting the verified value.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signature, []byte, error) {
idx, sig, err := obj.DetachedVerifyMulti(obj.payload, verificationKey)
if err != nil {
return -1, Signature{}, nil, err
}
return idx, sig, obj.payload, nil
}
// DetachedVerifyMulti validates a detached signature on the given payload with
// a signature/object that has potentially multiple signers. This returns the index
// of the signature that was verified, along with the signature object. We return
// the signature and index to guarantee that callers are getting the verified value.
//
// In most cases, you will probably want to use Verify or VerifyMulti instead.
// DetachedVerifyMulti is only useful if you have a payload and signature that are
// separated from each other, and the signature can have multiple signers at the
// same time.
//
// The verificationKey argument must have one of the types allowed for the
// verificationKey argument of JSONWebSignature.Verify().
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key)
if err != nil {
return -1, Signature{}, err
}
outer:
for i, signature := range obj.Signatures {
headers := signature.mergedHeaders()
critical, err := headers.getCritical()
if err != nil {
continue
}
for _, name := range critical {
if !supportedCritical[name] {
continue outer
}
}
input, err := obj.computeAuthData(payload, &signature)
if err != nil {
continue
}
alg := headers.getSignatureAlgorithm()
err = verifier.verifyPayload(input, signature.Signature, alg)
if err == nil {
return i, signature, nil
}
}
return -1, Signature{}, ErrCryptoFailure
}
func (obj JSONWebSignature) headers() []Header {
headers := make([]Header, len(obj.Signatures))
for i, sig := range obj.Signatures {
headers[i] = sig.Header
}
return headers
}

505
vendor/github.com/go-jose/go-jose/v3/symmetric.go generated vendored Normal file
View File

@ -0,0 +1,505 @@
/*-
* Copyright 2014 Square Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 jose
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"errors"
"fmt"
"hash"
"io"
"golang.org/x/crypto/pbkdf2"
josecipher "github.com/go-jose/go-jose/v3/cipher"
)
// RandReader is a cryptographically secure random number generator (stubbed out in tests).
var RandReader = rand.Reader
const (
// RFC7518 recommends a minimum of 1,000 iterations:
// - https://tools.ietf.org/html/rfc7518#section-4.8.1.2
//
// NIST recommends a minimum of 10,000:
// - https://pages.nist.gov/800-63-3/sp800-63b.html
//
// 1Password increased in 2023 from 100,000 to 650,000:
// - https://support.1password.com/pbkdf2/
//
// OWASP recommended 600,000 in Dec 2022:
// - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2
defaultP2C = 600000
// Default salt size: 128 bits
defaultP2SSize = 16
)
// Dummy key cipher for shared symmetric key mode
type symmetricKeyCipher struct {
key []byte // Pre-shared content-encryption key
p2c int // PBES2 Count
p2s []byte // PBES2 Salt Input
}
// Signer/verifier for MAC modes
type symmetricMac struct {
key []byte
}
// Input/output from an AEAD operation
type aeadParts struct {
iv, ciphertext, tag []byte
}
// A content cipher based on an AEAD construction
type aeadContentCipher struct {
keyBytes int
authtagBytes int
getAead func(key []byte) (cipher.AEAD, error)
}
// Random key generator
type randomKeyGenerator struct {
size int
}
// Static key generator
type staticKeyGenerator struct {
key []byte
}
// Create a new content cipher based on AES-GCM
func newAESGCM(keySize int) contentCipher {
return &aeadContentCipher{
keyBytes: keySize,
authtagBytes: 16,
getAead: func(key []byte) (cipher.AEAD, error) {
aes, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
return cipher.NewGCM(aes)
},
}
}
// Create a new content cipher based on AES-CBC+HMAC
func newAESCBC(keySize int) contentCipher {
return &aeadContentCipher{
keyBytes: keySize * 2,
authtagBytes: keySize,
getAead: func(key []byte) (cipher.AEAD, error) {
return josecipher.NewCBCHMAC(key, aes.NewCipher)
},
}
}
// Get an AEAD cipher object for the given content encryption algorithm
func getContentCipher(alg ContentEncryption) contentCipher {
switch alg {
case A128GCM:
return newAESGCM(16)
case A192GCM:
return newAESGCM(24)
case A256GCM:
return newAESGCM(32)
case A128CBC_HS256:
return newAESCBC(16)
case A192CBC_HS384:
return newAESCBC(24)
case A256CBC_HS512:
return newAESCBC(32)
default:
return nil
}
}
// getPbkdf2Params returns the key length and hash function used in
// pbkdf2.Key.
func getPbkdf2Params(alg KeyAlgorithm) (int, func() hash.Hash) {
switch alg {
case PBES2_HS256_A128KW:
return 16, sha256.New
case PBES2_HS384_A192KW:
return 24, sha512.New384
case PBES2_HS512_A256KW:
return 32, sha512.New
default:
panic("invalid algorithm")
}
}
// getRandomSalt generates a new salt of the given size.
func getRandomSalt(size int) ([]byte, error) {
salt := make([]byte, size)
_, err := io.ReadFull(RandReader, salt)
if err != nil {
return nil, err
}
return salt, nil
}
// newSymmetricRecipient creates a JWE encrypter based on AES-GCM key wrap.
func newSymmetricRecipient(keyAlg KeyAlgorithm, key []byte) (recipientKeyInfo, error) {
switch keyAlg {
case DIRECT, A128GCMKW, A192GCMKW, A256GCMKW, A128KW, A192KW, A256KW:
case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
default:
return recipientKeyInfo{}, ErrUnsupportedAlgorithm
}
return recipientKeyInfo{
keyAlg: keyAlg,
keyEncrypter: &symmetricKeyCipher{
key: key,
},
}, nil
}
// newSymmetricSigner creates a recipientSigInfo based on the given key.
func newSymmetricSigner(sigAlg SignatureAlgorithm, key []byte) (recipientSigInfo, error) {
// Verify that key management algorithm is supported by this encrypter
switch sigAlg {
case HS256, HS384, HS512:
default:
return recipientSigInfo{}, ErrUnsupportedAlgorithm
}
return recipientSigInfo{
sigAlg: sigAlg,
signer: &symmetricMac{
key: key,
},
}, nil
}
// Generate a random key for the given content cipher
func (ctx randomKeyGenerator) genKey() ([]byte, rawHeader, error) {
key := make([]byte, ctx.size)
_, err := io.ReadFull(RandReader, key)
if err != nil {
return nil, rawHeader{}, err
}
return key, rawHeader{}, nil
}
// Key size for random generator
func (ctx randomKeyGenerator) keySize() int {
return ctx.size
}
// Generate a static key (for direct mode)
func (ctx staticKeyGenerator) genKey() ([]byte, rawHeader, error) {
cek := make([]byte, len(ctx.key))
copy(cek, ctx.key)
return cek, rawHeader{}, nil
}
// Key size for static generator
func (ctx staticKeyGenerator) keySize() int {
return len(ctx.key)
}
// Get key size for this cipher
func (ctx aeadContentCipher) keySize() int {
return ctx.keyBytes
}
// Encrypt some data
func (ctx aeadContentCipher) encrypt(key, aad, pt []byte) (*aeadParts, error) {
// Get a new AEAD instance
aead, err := ctx.getAead(key)
if err != nil {
return nil, err
}
// Initialize a new nonce
iv := make([]byte, aead.NonceSize())
_, err = io.ReadFull(RandReader, iv)
if err != nil {
return nil, err
}
ciphertextAndTag := aead.Seal(nil, iv, pt, aad)
offset := len(ciphertextAndTag) - ctx.authtagBytes
return &aeadParts{
iv: iv,
ciphertext: ciphertextAndTag[:offset],
tag: ciphertextAndTag[offset:],
}, nil
}
// Decrypt some data
func (ctx aeadContentCipher) decrypt(key, aad []byte, parts *aeadParts) ([]byte, error) {
aead, err := ctx.getAead(key)
if err != nil {
return nil, err
}
if len(parts.iv) != aead.NonceSize() || len(parts.tag) < ctx.authtagBytes {
return nil, ErrCryptoFailure
}
return aead.Open(nil, parts.iv, append(parts.ciphertext, parts.tag...), aad)
}
// Encrypt the content encryption key.
func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipientInfo, error) {
switch alg {
case DIRECT:
return recipientInfo{
header: &rawHeader{},
}, nil
case A128GCMKW, A192GCMKW, A256GCMKW:
aead := newAESGCM(len(ctx.key))
parts, err := aead.encrypt(ctx.key, []byte{}, cek)
if err != nil {
return recipientInfo{}, err
}
header := &rawHeader{}
if err = header.set(headerIV, newBuffer(parts.iv)); err != nil {
return recipientInfo{}, err
}
if err = header.set(headerTag, newBuffer(parts.tag)); err != nil {
return recipientInfo{}, err
}
return recipientInfo{
header: header,
encryptedKey: parts.ciphertext,
}, nil
case A128KW, A192KW, A256KW:
block, err := aes.NewCipher(ctx.key)
if err != nil {
return recipientInfo{}, err
}
jek, err := josecipher.KeyWrap(block, cek)
if err != nil {
return recipientInfo{}, err
}
return recipientInfo{
encryptedKey: jek,
header: &rawHeader{},
}, nil
case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
if len(ctx.p2s) == 0 {
salt, err := getRandomSalt(defaultP2SSize)
if err != nil {
return recipientInfo{}, err
}
ctx.p2s = salt
}
if ctx.p2c <= 0 {
ctx.p2c = defaultP2C
}
// salt is UTF8(Alg) || 0x00 || Salt Input
salt := bytes.Join([][]byte{[]byte(alg), ctx.p2s}, []byte{0x00})
// derive key
keyLen, h := getPbkdf2Params(alg)
key := pbkdf2.Key(ctx.key, salt, ctx.p2c, keyLen, h)
// use AES cipher with derived key
block, err := aes.NewCipher(key)
if err != nil {
return recipientInfo{}, err
}
jek, err := josecipher.KeyWrap(block, cek)
if err != nil {
return recipientInfo{}, err
}
header := &rawHeader{}
if err = header.set(headerP2C, ctx.p2c); err != nil {
return recipientInfo{}, err
}
if err = header.set(headerP2S, newBuffer(ctx.p2s)); err != nil {
return recipientInfo{}, err
}
return recipientInfo{
encryptedKey: jek,
header: header,
}, nil
}
return recipientInfo{}, ErrUnsupportedAlgorithm
}
// Decrypt the content encryption key.
func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
switch headers.getAlgorithm() {
case DIRECT:
cek := make([]byte, len(ctx.key))
copy(cek, ctx.key)
return cek, nil
case A128GCMKW, A192GCMKW, A256GCMKW:
aead := newAESGCM(len(ctx.key))
iv, err := headers.getIV()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid IV: %v", err)
}
tag, err := headers.getTag()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid tag: %v", err)
}
parts := &aeadParts{
iv: iv.bytes(),
ciphertext: recipient.encryptedKey,
tag: tag.bytes(),
}
cek, err := aead.decrypt(ctx.key, []byte{}, parts)
if err != nil {
return nil, err
}
return cek, nil
case A128KW, A192KW, A256KW:
block, err := aes.NewCipher(ctx.key)
if err != nil {
return nil, err
}
cek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)
if err != nil {
return nil, err
}
return cek, nil
case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
p2s, err := headers.getP2S()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2S: %v", err)
}
if p2s == nil || len(p2s.data) == 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2S: must be present")
}
p2c, err := headers.getP2C()
if err != nil {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: %v", err)
}
if p2c <= 0 {
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
}
if p2c > 1000000 {
// An unauthenticated attacker can set a high P2C value. Set an upper limit to avoid
// DoS attacks.
return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: too high")
}
// salt is UTF8(Alg) || 0x00 || Salt Input
alg := headers.getAlgorithm()
salt := bytes.Join([][]byte{[]byte(alg), p2s.bytes()}, []byte{0x00})
// derive key
keyLen, h := getPbkdf2Params(alg)
key := pbkdf2.Key(ctx.key, salt, p2c, keyLen, h)
// use AES cipher with derived key
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
cek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)
if err != nil {
return nil, err
}
return cek, nil
}
return nil, ErrUnsupportedAlgorithm
}
// Sign the given payload
func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
mac, err := ctx.hmac(payload, alg)
if err != nil {
return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac")
}
return Signature{
Signature: mac,
protected: &rawHeader{},
}, nil
}
// Verify the given payload
func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureAlgorithm) error {
expected, err := ctx.hmac(payload, alg)
if err != nil {
return errors.New("go-jose/go-jose: failed to compute hmac")
}
if len(mac) != len(expected) {
return errors.New("go-jose/go-jose: invalid hmac")
}
match := subtle.ConstantTimeCompare(mac, expected)
if match != 1 {
return errors.New("go-jose/go-jose: invalid hmac")
}
return nil
}
// Compute the HMAC based on the given alg value
func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) {
var hash func() hash.Hash
switch alg {
case HS256:
hash = sha256.New
case HS384:
hash = sha512.New384
case HS512:
hash = sha512.New
default:
return nil, ErrUnsupportedAlgorithm
}
hmac := hmac.New(hash, ctx.key)
// According to documentation, Write() on hash never fails
_, _ = hmac.Write(payload)
return hmac.Sum(nil), nil
}

3
vendor/github.com/miekg/pkcs11/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
tags
test_db/*/generation
test_db/*/*.lock

27
vendor/github.com/miekg/pkcs11/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2013 Miek Gieben. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Miek Gieben nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

57
vendor/github.com/miekg/pkcs11/Makefile.release generated vendored Normal file
View File

@ -0,0 +1,57 @@
# Makefile for releasing.
#
# The release is controlled from version.go. The version found there is
# used to tag the git repo, we're not building any artifects so there is nothing
# to upload to github.
#
# * Up the version in version.go
# * Run: make -f Makefile.release release
# * will *commit* your change with 'Release $VERSION'
# * push to github
#
define GO
//+build ignore
package main
import (
"fmt"
"github.com/miekg/pkcs11"
)
func main() {
fmt.Println(pkcs11.Release.String())
}
endef
$(file > version_release.go,$(GO))
VERSION:=$(shell go run -tags release version_release.go)
TAG="v$(VERSION)"
all:
rm -f version_release.go
@echo Use the \'release\' target to start a release $(VERSION)
.PHONY: run
run:
rm -f version_release.go
@echo $(VERSION)
.PHONY: release
release: commit push
@echo Released $(VERSION)
.PHONY: commit
commit:
rm -f version_release.go
@echo Committing release $(VERSION)
git commit -am"Release $(VERSION)"
git tag $(TAG)
.PHONY: push
push:
@echo Pushing release $(VERSION) to master
git push --tags
git push

68
vendor/github.com/miekg/pkcs11/README.md generated vendored Normal file
View File

@ -0,0 +1,68 @@
# PKCS#11
This is a Go implementation of the PKCS#11 API. It wraps the library closely, but uses Go idiom where
it makes sense. It has been tested with SoftHSM.
## SoftHSM
* Make it use a custom configuration file `export SOFTHSM_CONF=$PWD/softhsm.conf`
* Then use `softhsm` to init it
~~~
softhsm --init-token --slot 0 --label test --pin 1234
~~~
* Then use `libsofthsm2.so` as the pkcs11 module:
~~~ go
p := pkcs11.New("/usr/lib/softhsm/libsofthsm2.so")
~~~
## Examples
A skeleton program would look somewhat like this (yes, pkcs#11 is verbose):
~~~ go
p := pkcs11.New("/usr/lib/softhsm/libsofthsm2.so")
err := p.Initialize()
if err != nil {
panic(err)
}
defer p.Destroy()
defer p.Finalize()
slots, err := p.GetSlotList(true)
if err != nil {
panic(err)
}
session, err := p.OpenSession(slots[0], pkcs11.CKF_SERIAL_SESSION|pkcs11.CKF_RW_SESSION)
if err != nil {
panic(err)
}
defer p.CloseSession(session)
err = p.Login(session, pkcs11.CKU_USER, "1234")
if err != nil {
panic(err)
}
defer p.Logout(session)
p.DigestInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_SHA_1, nil)})
hash, err := p.Digest(session, []byte("this is a string"))
if err != nil {
panic(err)
}
for _, d := range hash {
fmt.Printf("%x", d)
}
fmt.Println()
~~~
Further examples are included in the tests.
To expose PKCS#11 keys using the [crypto.Signer interface](https://golang.org/pkg/crypto/#Signer),
please see [github.com/thalesignite/crypto11](https://github.com/thalesignite/crypto11).

98
vendor/github.com/miekg/pkcs11/error.go generated vendored Normal file
View File

@ -0,0 +1,98 @@
// Copyright 2013 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs11
// awk '/#define CKR_/{ print $3":\""$2"\"," }' pkcs11t.h
var strerror = map[uint]string{
0x00000000: "CKR_OK",
0x00000001: "CKR_CANCEL",
0x00000002: "CKR_HOST_MEMORY",
0x00000003: "CKR_SLOT_ID_INVALID",
0x00000005: "CKR_GENERAL_ERROR",
0x00000006: "CKR_FUNCTION_FAILED",
0x00000007: "CKR_ARGUMENTS_BAD",
0x00000008: "CKR_NO_EVENT",
0x00000009: "CKR_NEED_TO_CREATE_THREADS",
0x0000000A: "CKR_CANT_LOCK",
0x00000010: "CKR_ATTRIBUTE_READ_ONLY",
0x00000011: "CKR_ATTRIBUTE_SENSITIVE",
0x00000012: "CKR_ATTRIBUTE_TYPE_INVALID",
0x00000013: "CKR_ATTRIBUTE_VALUE_INVALID",
0x00000020: "CKR_DATA_INVALID",
0x00000021: "CKR_DATA_LEN_RANGE",
0x00000030: "CKR_DEVICE_ERROR",
0x00000031: "CKR_DEVICE_MEMORY",
0x00000032: "CKR_DEVICE_REMOVED",
0x00000040: "CKR_ENCRYPTED_DATA_INVALID",
0x00000041: "CKR_ENCRYPTED_DATA_LEN_RANGE",
0x00000050: "CKR_FUNCTION_CANCELED",
0x00000051: "CKR_FUNCTION_NOT_PARALLEL",
0x00000054: "CKR_FUNCTION_NOT_SUPPORTED",
0x00000060: "CKR_KEY_HANDLE_INVALID",
0x00000062: "CKR_KEY_SIZE_RANGE",
0x00000063: "CKR_KEY_TYPE_INCONSISTENT",
0x00000064: "CKR_KEY_NOT_NEEDED",
0x00000065: "CKR_KEY_CHANGED",
0x00000066: "CKR_KEY_NEEDED",
0x00000067: "CKR_KEY_INDIGESTIBLE",
0x00000068: "CKR_KEY_FUNCTION_NOT_PERMITTED",
0x00000069: "CKR_KEY_NOT_WRAPPABLE",
0x0000006A: "CKR_KEY_UNEXTRACTABLE",
0x00000070: "CKR_MECHANISM_INVALID",
0x00000071: "CKR_MECHANISM_PARAM_INVALID",
0x00000082: "CKR_OBJECT_HANDLE_INVALID",
0x00000090: "CKR_OPERATION_ACTIVE",
0x00000091: "CKR_OPERATION_NOT_INITIALIZED",
0x000000A0: "CKR_PIN_INCORRECT",
0x000000A1: "CKR_PIN_INVALID",
0x000000A2: "CKR_PIN_LEN_RANGE",
0x000000A3: "CKR_PIN_EXPIRED",
0x000000A4: "CKR_PIN_LOCKED",
0x000000B0: "CKR_SESSION_CLOSED",
0x000000B1: "CKR_SESSION_COUNT",
0x000000B3: "CKR_SESSION_HANDLE_INVALID",
0x000000B4: "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
0x000000B5: "CKR_SESSION_READ_ONLY",
0x000000B6: "CKR_SESSION_EXISTS",
0x000000B7: "CKR_SESSION_READ_ONLY_EXISTS",
0x000000B8: "CKR_SESSION_READ_WRITE_SO_EXISTS",
0x000000C0: "CKR_SIGNATURE_INVALID",
0x000000C1: "CKR_SIGNATURE_LEN_RANGE",
0x000000D0: "CKR_TEMPLATE_INCOMPLETE",
0x000000D1: "CKR_TEMPLATE_INCONSISTENT",
0x000000E0: "CKR_TOKEN_NOT_PRESENT",
0x000000E1: "CKR_TOKEN_NOT_RECOGNIZED",
0x000000E2: "CKR_TOKEN_WRITE_PROTECTED",
0x000000F0: "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
0x000000F1: "CKR_UNWRAPPING_KEY_SIZE_RANGE",
0x000000F2: "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
0x00000100: "CKR_USER_ALREADY_LOGGED_IN",
0x00000101: "CKR_USER_NOT_LOGGED_IN",
0x00000102: "CKR_USER_PIN_NOT_INITIALIZED",
0x00000103: "CKR_USER_TYPE_INVALID",
0x00000104: "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
0x00000105: "CKR_USER_TOO_MANY_TYPES",
0x00000110: "CKR_WRAPPED_KEY_INVALID",
0x00000112: "CKR_WRAPPED_KEY_LEN_RANGE",
0x00000113: "CKR_WRAPPING_KEY_HANDLE_INVALID",
0x00000114: "CKR_WRAPPING_KEY_SIZE_RANGE",
0x00000115: "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
0x00000120: "CKR_RANDOM_SEED_NOT_SUPPORTED",
0x00000121: "CKR_RANDOM_NO_RNG",
0x00000130: "CKR_DOMAIN_PARAMS_INVALID",
0x00000150: "CKR_BUFFER_TOO_SMALL",
0x00000160: "CKR_SAVED_STATE_INVALID",
0x00000170: "CKR_INFORMATION_SENSITIVE",
0x00000180: "CKR_STATE_UNSAVEABLE",
0x00000190: "CKR_CRYPTOKI_NOT_INITIALIZED",
0x00000191: "CKR_CRYPTOKI_ALREADY_INITIALIZED",
0x000001A0: "CKR_MUTEX_BAD",
0x000001A1: "CKR_MUTEX_NOT_LOCKED",
0x000001B0: "CKR_NEW_PIN_MODE",
0x000001B1: "CKR_NEXT_OTP",
0x00000200: "CKR_FUNCTION_REJECTED",
0x80000000: "CKR_VENDOR_DEFINED",
}

BIN
vendor/github.com/miekg/pkcs11/hsm.db generated vendored Normal file

Binary file not shown.

190
vendor/github.com/miekg/pkcs11/params.go generated vendored Normal file
View File

@ -0,0 +1,190 @@
// Copyright 2013 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs11
/*
#include <stdlib.h>
#include <string.h>
#include "pkcs11go.h"
static inline void putOAEPParams(CK_RSA_PKCS_OAEP_PARAMS_PTR params, CK_VOID_PTR pSourceData, CK_ULONG ulSourceDataLen)
{
params->pSourceData = pSourceData;
params->ulSourceDataLen = ulSourceDataLen;
}
static inline void putECDH1SharedParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pSharedData, CK_ULONG ulSharedDataLen)
{
params->pSharedData = pSharedData;
params->ulSharedDataLen = ulSharedDataLen;
}
static inline void putECDH1PublicParams(CK_ECDH1_DERIVE_PARAMS_PTR params, CK_VOID_PTR pPublicData, CK_ULONG ulPublicDataLen)
{
params->pPublicData = pPublicData;
params->ulPublicDataLen = ulPublicDataLen;
}
*/
import "C"
import "unsafe"
// GCMParams represents the parameters for the AES-GCM mechanism.
type GCMParams struct {
arena
params *C.CK_GCM_PARAMS
iv []byte
aad []byte
tagSize int
}
// NewGCMParams returns a pointer to AES-GCM parameters that can be used with the CKM_AES_GCM mechanism.
// The Free() method must be called after the operation is complete.
//
// Note that some HSMs, like CloudHSM, will ignore the IV you pass in and write their
// own. As a result, to support all libraries, memory is not freed
// automatically, so that after the EncryptInit/Encrypt operation the HSM's IV
// can be read back out. It is up to the caller to ensure that Free() is called
// on the GCMParams object at an appropriate time, which is after
//
// Encrypt/Decrypt. As an example:
//
// gcmParams := pkcs11.NewGCMParams(make([]byte, 12), nil, 128)
// p.ctx.EncryptInit(session, []*pkcs11.Mechanism{pkcs11.NewMechanism(pkcs11.CKM_AES_GCM, gcmParams)},
// aesObjHandle)
// ct, _ := p.ctx.Encrypt(session, pt)
// iv := gcmParams.IV()
// gcmParams.Free()
//
func NewGCMParams(iv, aad []byte, tagSize int) *GCMParams {
return &GCMParams{
iv: iv,
aad: aad,
tagSize: tagSize,
}
}
func cGCMParams(p *GCMParams) []byte {
params := C.CK_GCM_PARAMS{
ulTagBits: C.CK_ULONG(p.tagSize),
}
var arena arena
if len(p.iv) > 0 {
iv, ivLen := arena.Allocate(p.iv)
params.pIv = C.CK_BYTE_PTR(iv)
params.ulIvLen = ivLen
params.ulIvBits = ivLen * 8
}
if len(p.aad) > 0 {
aad, aadLen := arena.Allocate(p.aad)
params.pAAD = C.CK_BYTE_PTR(aad)
params.ulAADLen = aadLen
}
p.Free()
p.arena = arena
p.params = &params
return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params)))
}
// IV returns a copy of the actual IV used for the operation.
//
// Some HSMs may ignore the user-specified IV and write their own at the end of
// the encryption operation; this method allows you to retrieve it.
func (p *GCMParams) IV() []byte {
if p == nil || p.params == nil {
return nil
}
newIv := C.GoBytes(unsafe.Pointer(p.params.pIv), C.int(p.params.ulIvLen))
iv := make([]byte, len(newIv))
copy(iv, newIv)
return iv
}
// Free deallocates the memory reserved for the HSM to write back the actual IV.
//
// This must be called after the entire operation is complete, i.e. after
// Encrypt or EncryptFinal. It is safe to call Free multiple times.
func (p *GCMParams) Free() {
if p == nil || p.arena == nil {
return
}
p.arena.Free()
p.params = nil
p.arena = nil
}
// NewPSSParams creates a CK_RSA_PKCS_PSS_PARAMS structure and returns it as a byte array for use with the CKM_RSA_PKCS_PSS mechanism.
func NewPSSParams(hashAlg, mgf, saltLength uint) []byte {
p := C.CK_RSA_PKCS_PSS_PARAMS{
hashAlg: C.CK_MECHANISM_TYPE(hashAlg),
mgf: C.CK_RSA_PKCS_MGF_TYPE(mgf),
sLen: C.CK_ULONG(saltLength),
}
return C.GoBytes(unsafe.Pointer(&p), C.int(unsafe.Sizeof(p)))
}
// OAEPParams can be passed to NewMechanism to implement CKM_RSA_PKCS_OAEP.
type OAEPParams struct {
HashAlg uint
MGF uint
SourceType uint
SourceData []byte
}
// NewOAEPParams creates a CK_RSA_PKCS_OAEP_PARAMS structure suitable for use with the CKM_RSA_PKCS_OAEP mechanism.
func NewOAEPParams(hashAlg, mgf, sourceType uint, sourceData []byte) *OAEPParams {
return &OAEPParams{
HashAlg: hashAlg,
MGF: mgf,
SourceType: sourceType,
SourceData: sourceData,
}
}
func cOAEPParams(p *OAEPParams, arena arena) ([]byte, arena) {
params := C.CK_RSA_PKCS_OAEP_PARAMS{
hashAlg: C.CK_MECHANISM_TYPE(p.HashAlg),
mgf: C.CK_RSA_PKCS_MGF_TYPE(p.MGF),
source: C.CK_RSA_PKCS_OAEP_SOURCE_TYPE(p.SourceType),
}
if len(p.SourceData) != 0 {
buf, len := arena.Allocate(p.SourceData)
// field is unaligned on windows so this has to call into C
C.putOAEPParams(&params, buf, len)
}
return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
}
// ECDH1DeriveParams can be passed to NewMechanism to implement CK_ECDH1_DERIVE_PARAMS.
type ECDH1DeriveParams struct {
KDF uint
SharedData []byte
PublicKeyData []byte
}
// NewECDH1DeriveParams creates a CK_ECDH1_DERIVE_PARAMS structure suitable for use with the CKM_ECDH1_DERIVE mechanism.
func NewECDH1DeriveParams(kdf uint, sharedData []byte, publicKeyData []byte) *ECDH1DeriveParams {
return &ECDH1DeriveParams{
KDF: kdf,
SharedData: sharedData,
PublicKeyData: publicKeyData,
}
}
func cECDH1DeriveParams(p *ECDH1DeriveParams, arena arena) ([]byte, arena) {
params := C.CK_ECDH1_DERIVE_PARAMS{
kdf: C.CK_EC_KDF_TYPE(p.KDF),
}
// SharedData MUST be null if key derivation function (KDF) is CKD_NULL
if len(p.SharedData) != 0 {
sharedData, sharedDataLen := arena.Allocate(p.SharedData)
C.putECDH1SharedParams(&params, sharedData, sharedDataLen)
}
publicKeyData, publicKeyDataLen := arena.Allocate(p.PublicKeyData)
C.putECDH1PublicParams(&params, publicKeyData, publicKeyDataLen)
return C.GoBytes(unsafe.Pointer(&params), C.int(unsafe.Sizeof(params))), arena
}

1609
vendor/github.com/miekg/pkcs11/pkcs11.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

265
vendor/github.com/miekg/pkcs11/pkcs11.h generated vendored Normal file
View File

@ -0,0 +1,265 @@
/* Copyright (c) OASIS Open 2016. All Rights Reserved./
* /Distributed under the terms of the OASIS IPR Policy,
* [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
* IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
*/
/* Latest version of the specification:
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Before including this file (pkcs11.h) (or pkcs11t.h by
* itself), 5 platform-specific macros must be defined. These
* macros are described below, and typical definitions for them
* are also given. Be advised that these definitions can depend
* on both the platform and the compiler used (and possibly also
* on whether a Cryptoki library is linked statically or
* dynamically).
*
* In addition to defining these 5 macros, the packing convention
* for Cryptoki structures should be set. The Cryptoki
* convention on packing is that structures should be 1-byte
* aligned.
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, this might be done by using the following
* preprocessor directive before including pkcs11.h or pkcs11t.h:
*
* #pragma pack(push, cryptoki, 1)
*
* and using the following preprocessor directive after including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(pop, cryptoki)
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, this might be done by using
* the following preprocessor directive before including
* pkcs11.h or pkcs11t.h:
*
* #pragma pack(1)
*
* In a UNIX environment, you're on your own for this. You might
* not need to do (or be able to do!) anything.
*
*
* Now for the macros:
*
*
* 1. CK_PTR: The indirection string for making a pointer to an
* object. It can be used like this:
*
* typedef CK_BYTE CK_PTR CK_BYTE_PTR;
*
* If you're using Microsoft Developer Studio 5.0 to produce
* Win32 stuff, it might be defined by:
*
* #define CK_PTR *
*
* If you're using an earlier version of Microsoft Developer
* Studio to produce Win16 stuff, it might be defined by:
*
* #define CK_PTR far *
*
* In a typical UNIX environment, it might be defined by:
*
* #define CK_PTR *
*
*
* 2. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
* an importable Cryptoki library function declaration out of a
* return type and a function name. It should be used in the
* following fashion:
*
* extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
* CK_VOID_PTR pReserved
* );
*
* If you're using Microsoft Developer Studio 5.0 to declare a
* function in a Win32 Cryptoki .dll, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __declspec(dllimport) name
*
* If you're using an earlier version of Microsoft Developer
* Studio to declare a function in a Win16 Cryptoki .dll, it
* might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType __export _far _pascal name
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION(returnType, name) \
* returnType name
*
*
* 3. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
* which makes a Cryptoki API function pointer declaration or
* function pointer type declaration out of a return type and a
* function name. It should be used in the following fashion:
*
* // Define funcPtr to be a pointer to a Cryptoki API function
* // taking arguments args and returning CK_RV.
* CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
*
* or
*
* // Define funcPtrType to be the type of a pointer to a
* // Cryptoki API function taking arguments args and returning
* // CK_RV, and then define funcPtr to be a variable of type
* // funcPtrType.
* typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
* funcPtrType funcPtr;
*
* If you're using Microsoft Developer Studio 5.0 to access
* functions in a Win32 Cryptoki .dll, in might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __declspec(dllimport) (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to access functions in a Win16 Cryptoki .dll, it might
* be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType __export _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
* returnType (* name)
*
*
* 4. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
* a function pointer type for an application callback out of
* a return type for the callback and a name for the callback.
* It should be used in the following fashion:
*
* CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
*
* to declare a function pointer, myCallback, to a callback
* which takes arguments args and returns a CK_RV. It can also
* be used like this:
*
* typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
* myCallbackType myCallback;
*
* If you're using Microsoft Developer Studio 5.0 to do Win32
* Cryptoki development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
* If you're using an earlier version of Microsoft Developer
* Studio to do Win16 development, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType _far _pascal (* name)
*
* In a UNIX environment, it might be defined by:
*
* #define CK_CALLBACK_FUNCTION(returnType, name) \
* returnType (* name)
*
*
* 5. NULL_PTR: This macro is the value of a NULL pointer.
*
* In any ANSI/ISO C environment (and in many others as well),
* this should best be defined by
*
* #ifndef NULL_PTR
* #define NULL_PTR 0
* #endif
*/
/* All the various Cryptoki types and #define'd values are in the
* file pkcs11t.h.
*/
#include "pkcs11t.h"
#define __PASTE(x,y) x##y
/* ==============================================================
* Define the "extern" form of all the entry points.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
extern CK_DECLARE_FUNCTION(CK_RV, name)
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define the typedef form of all the entry points. That is, for
* each Cryptoki function C_XXX, define a type CK_C_XXX which is
* a pointer to that kind of function.
* ==============================================================
*/
#define CK_NEED_ARG_LIST 1
#define CK_PKCS11_FUNCTION_INFO(name) \
typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
/* ==============================================================
* Define structed vector of entry points. A CK_FUNCTION_LIST
* contains a CK_VERSION indicating a library's Cryptoki version
* and then a whole slew of function pointers to the routines in
* the library. This type was declared, but not defined, in
* pkcs11t.h.
* ==============================================================
*/
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(CK_,name) name;
struct CK_FUNCTION_LIST {
CK_VERSION version; /* Cryptoki version */
/* Pile all the function pointers into the CK_FUNCTION_LIST. */
/* pkcs11f.h has all the information about the Cryptoki
* function prototypes.
*/
#include "pkcs11f.h"
};
#undef CK_PKCS11_FUNCTION_INFO
#undef __PASTE
#ifdef __cplusplus
}
#endif
#endif /* _PKCS11_H_ */

939
vendor/github.com/miekg/pkcs11/pkcs11f.h generated vendored Normal file
View File

@ -0,0 +1,939 @@
/* Copyright (c) OASIS Open 2016. All Rights Reserved./
* /Distributed under the terms of the OASIS IPR Policy,
* [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY
* IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others.
*/
/* Latest version of the specification:
* http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html
*/
/* This header file contains pretty much everything about all the
* Cryptoki function prototypes. Because this information is
* used for more than just declaring function prototypes, the
* order of the functions appearing herein is important, and
* should not be altered.
*/
/* General-purpose */
/* C_Initialize initializes the Cryptoki library. */
CK_PKCS11_FUNCTION_INFO(C_Initialize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
* cast to CK_C_INITIALIZE_ARGS_PTR
* and dereferenced
*/
);
#endif
/* C_Finalize indicates that an application is done with the
* Cryptoki library.
*/
CK_PKCS11_FUNCTION_INFO(C_Finalize)
#ifdef CK_NEED_ARG_LIST
(
CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
);
#endif
/* C_GetInfo returns general information about Cryptoki. */
CK_PKCS11_FUNCTION_INFO(C_GetInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_INFO_PTR pInfo /* location that receives information */
);
#endif
/* C_GetFunctionList returns the function list. */
CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
#ifdef CK_NEED_ARG_LIST
(
CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
* function list
*/
);
#endif
/* Slot and token management */
/* C_GetSlotList obtains a list of slots in the system. */
CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
#ifdef CK_NEED_ARG_LIST
(
CK_BBOOL tokenPresent, /* only slots with tokens */
CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
CK_ULONG_PTR pulCount /* receives number of slots */
);
#endif
/* C_GetSlotInfo obtains information about a particular slot in
* the system.
*/
CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the ID of the slot */
CK_SLOT_INFO_PTR pInfo /* receives the slot information */
);
#endif
/* C_GetTokenInfo obtains information about a particular token
* in the system.
*/
CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_TOKEN_INFO_PTR pInfo /* receives the token information */
);
#endif
/* C_GetMechanismList obtains a list of mechanism types
* supported by a token.
*/
CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of token's slot */
CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
CK_ULONG_PTR pulCount /* gets # of mechs. */
);
#endif
/* C_GetMechanismInfo obtains information about a particular
* mechanism possibly supported by a token.
*/
CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_MECHANISM_TYPE type, /* type of mechanism */
CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
);
#endif
/* C_InitToken initializes a token. */
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* ID of the token's slot */
CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
CK_ULONG ulPinLen, /* length in bytes of the PIN */
CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
/* C_InitPIN initializes the normal user's PIN. */
CK_PKCS11_FUNCTION_INFO(C_InitPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
CK_ULONG ulPinLen /* length in bytes of the PIN */
);
#endif
/* C_SetPIN modifies the PIN of the user who is logged in. */
CK_PKCS11_FUNCTION_INFO(C_SetPIN)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
CK_ULONG ulOldLen, /* length of the old PIN */
CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
CK_ULONG ulNewLen /* length of the new PIN */
);
#endif
/* Session management */
/* C_OpenSession opens a session between an application and a
* token.
*/
CK_PKCS11_FUNCTION_INFO(C_OpenSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID, /* the slot's ID */
CK_FLAGS flags, /* from CK_SESSION_INFO */
CK_VOID_PTR pApplication, /* passed to callback */
CK_NOTIFY Notify, /* callback function */
CK_SESSION_HANDLE_PTR phSession /* gets session handle */
);
#endif
/* C_CloseSession closes a session between an application and a
* token.
*/
CK_PKCS11_FUNCTION_INFO(C_CloseSession)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CloseAllSessions closes all sessions with a token. */
CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
#ifdef CK_NEED_ARG_LIST
(
CK_SLOT_ID slotID /* the token's slot */
);
#endif
/* C_GetSessionInfo obtains information about the session. */
CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_SESSION_INFO_PTR pInfo /* receives session info */
);
#endif
/* C_GetOperationState obtains the state of the cryptographic operation
* in a session.
*/
CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* gets state */
CK_ULONG_PTR pulOperationStateLen /* gets state length */
);
#endif
/* C_SetOperationState restores the state of the cryptographic
* operation in a session.
*/
CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pOperationState, /* holds state */
CK_ULONG ulOperationStateLen, /* holds state length */
CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
);
#endif
/* C_Login logs a user into a token. */
CK_PKCS11_FUNCTION_INFO(C_Login)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_USER_TYPE userType, /* the user type */
CK_UTF8CHAR_PTR pPin, /* the user's PIN */
CK_ULONG ulPinLen /* the length of the PIN */
);
#endif
/* C_Logout logs a user out from a token. */
CK_PKCS11_FUNCTION_INFO(C_Logout)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Object management */
/* C_CreateObject creates a new object. */
CK_PKCS11_FUNCTION_INFO(C_CreateObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
);
#endif
/* C_CopyObject copies an object, creating a new object for the
* copy.
*/
CK_PKCS11_FUNCTION_INFO(C_CopyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
);
#endif
/* C_DestroyObject destroys an object. */
CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject /* the object's handle */
);
#endif
/* C_GetObjectSize gets the size of an object in bytes. */
CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ULONG_PTR pulSize /* receives size of object */
);
#endif
/* C_GetAttributeValue obtains the value of one or more object
* attributes.
*/
CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_SetAttributeValue modifies the value of one or more object
* attributes.
*/
CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
CK_ULONG ulCount /* attributes in template */
);
#endif
/* C_FindObjectsInit initializes a search for token and session
* objects that match a template.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
CK_ULONG ulCount /* attrs in search template */
);
#endif
/* C_FindObjects continues a search for token and session
* objects that match a template, obtaining additional object
* handles.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjects)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
CK_ULONG ulMaxObjectCount, /* max handles to get */
CK_ULONG_PTR pulObjectCount /* actual # returned */
);
#endif
/* C_FindObjectsFinal finishes a search for token and session
* objects.
*/
CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* Encryption and decryption */
/* C_EncryptInit initializes an encryption operation. */
CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of encryption key */
);
#endif
/* C_Encrypt encrypts single-part data. */
CK_PKCS11_FUNCTION_INFO(C_Encrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pData, /* the plaintext data */
CK_ULONG ulDataLen, /* bytes of plaintext */
CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
);
#endif
/* C_EncryptUpdate continues a multiple-part encryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext data len */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
);
#endif
/* C_EncryptFinal finishes a multiple-part encryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
);
#endif
/* C_DecryptInit initializes a decryption operation. */
CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
CK_OBJECT_HANDLE hKey /* handle of decryption key */
);
#endif
/* C_Decrypt decrypts encrypted data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Decrypt)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedData, /* ciphertext */
CK_ULONG ulEncryptedDataLen, /* ciphertext length */
CK_BYTE_PTR pData, /* gets plaintext */
CK_ULONG_PTR pulDataLen /* gets p-text size */
);
#endif
/* C_DecryptUpdate continues a multiple-part decryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* encrypted data */
CK_ULONG ulEncryptedPartLen, /* input length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* p-text size */
);
#endif
/* C_DecryptFinal finishes a multiple-part decryption
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pLastPart, /* gets plaintext */
CK_ULONG_PTR pulLastPartLen /* p-text size */
);
#endif
/* Message digesting */
/* C_DigestInit initializes a message-digesting operation. */
CK_PKCS11_FUNCTION_INFO(C_DigestInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
);
#endif
/* C_Digest digests data in a single part. */
CK_PKCS11_FUNCTION_INFO(C_Digest)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* data to be digested */
CK_ULONG ulDataLen, /* bytes of data to digest */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets digest length */
);
#endif
/* C_DigestUpdate continues a multiple-part message-digesting
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* data to be digested */
CK_ULONG ulPartLen /* bytes of data to be digested */
);
#endif
/* C_DigestKey continues a multi-part message-digesting
* operation, by digesting the value of a secret key as part of
* the data already digested.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hKey /* secret key to digest */
);
#endif
/* C_DigestFinal finishes a multiple-part message-digesting
* operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pDigest, /* gets the message digest */
CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
);
#endif
/* Signing and MACing */
/* C_SignInit initializes a signature (private key encryption)
* operation, where the signature is (will be) an appendix to
* the data, and plaintext cannot be recovered from the
* signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of signature key */
);
#endif
/* C_Sign signs (encrypts with private key) data in a single
* part, where the signature is (will be) an appendix to the
* data, and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_Sign)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignUpdate continues a multiple-part signature operation,
* where the signature is (will be) an appendix to the data,
* and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* the data to sign */
CK_ULONG ulPartLen /* count of bytes to sign */
);
#endif
/* C_SignFinal finishes a multiple-part signature operation,
* returning the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* C_SignRecoverInit initializes a signature operation, where
* the data can be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
CK_OBJECT_HANDLE hKey /* handle of the signature key */
);
#endif
/* C_SignRecover signs data in a single operation, where the
* data can be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_SignRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* the data to sign */
CK_ULONG ulDataLen, /* count of bytes to sign */
CK_BYTE_PTR pSignature, /* gets the signature */
CK_ULONG_PTR pulSignatureLen /* gets signature length */
);
#endif
/* Verifying signatures and MACs */
/* C_VerifyInit initializes a verification operation, where the
* signature is an appendix to the data, and plaintext cannot
* cannot be recovered from the signature (e.g. DSA).
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_Verify verifies a signature in a single-part operation,
* where the signature is an appendix to the data, and plaintext
* cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_Verify)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pData, /* signed data */
CK_ULONG ulDataLen, /* length of signed data */
CK_BYTE_PTR pSignature, /* signature */
CK_ULONG ulSignatureLen /* signature length*/
);
#endif
/* C_VerifyUpdate continues a multiple-part verification
* operation, where the signature is an appendix to the data,
* and plaintext cannot be recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pPart, /* signed data */
CK_ULONG ulPartLen /* length of signed data */
);
#endif
/* C_VerifyFinal finishes a multiple-part verification
* operation, checking the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen /* signature length */
);
#endif
/* C_VerifyRecoverInit initializes a signature verification
* operation, where the data is recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
CK_OBJECT_HANDLE hKey /* verification key */
);
#endif
/* C_VerifyRecover verifies a signature in a single-part
* operation, where the data is recovered from the signature.
*/
CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSignature, /* signature to verify */
CK_ULONG ulSignatureLen, /* signature length */
CK_BYTE_PTR pData, /* gets signed data */
CK_ULONG_PTR pulDataLen /* gets signed data len */
);
#endif
/* Dual-function cryptographic operations */
/* C_DigestEncryptUpdate continues a multiple-part digesting
* and encryption operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptDigestUpdate continues a multiple-part decryption and
* digesting operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets plaintext len */
);
#endif
/* C_SignEncryptUpdate continues a multiple-part signing and
* encryption operation.
*/
CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pPart, /* the plaintext data */
CK_ULONG ulPartLen, /* plaintext length */
CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
);
#endif
/* C_DecryptVerifyUpdate continues a multiple-part decryption and
* verify operation.
*/
CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_BYTE_PTR pEncryptedPart, /* ciphertext */
CK_ULONG ulEncryptedPartLen, /* ciphertext length */
CK_BYTE_PTR pPart, /* gets plaintext */
CK_ULONG_PTR pulPartLen /* gets p-text length */
);
#endif
/* Key management */
/* C_GenerateKey generates a secret key, creating a new key
* object.
*/
CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* key generation mech. */
CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
CK_ULONG ulCount, /* # of attrs in template */
CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
);
#endif
/* C_GenerateKeyPair generates a public-key/private-key pair,
* creating new key objects.
*/
CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session handle */
CK_MECHANISM_PTR pMechanism, /* key-gen mech. */
CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template for pub. key */
CK_ULONG ulPublicKeyAttributeCount, /* # pub. attrs. */
CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template for priv. key */
CK_ULONG ulPrivateKeyAttributeCount, /* # priv. attrs. */
CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key handle */
CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key handle */
);
#endif
/* C_WrapKey wraps (i.e., encrypts) a key. */
CK_PKCS11_FUNCTION_INFO(C_WrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
CK_OBJECT_HANDLE hKey, /* key to be wrapped */
CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
);
#endif
/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
* key object.
*/
CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
CK_BYTE_PTR pWrappedKey, /* the wrapped key */
CK_ULONG ulWrappedKeyLen, /* wrapped key len */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* C_DeriveKey derives a key from a base key, creating a new key
* object.
*/
CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* session's handle */
CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
CK_OBJECT_HANDLE hBaseKey, /* base key */
CK_ATTRIBUTE_PTR pTemplate, /* new key template */
CK_ULONG ulAttributeCount, /* template length */
CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
);
#endif
/* Random number generation */
/* C_SeedRandom mixes additional seed material into the token's
* random number generator.
*/
CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR pSeed, /* the seed material */
CK_ULONG ulSeedLen /* length of seed material */
);
#endif
/* C_GenerateRandom generates random data. */
CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession, /* the session's handle */
CK_BYTE_PTR RandomData, /* receives the random data */
CK_ULONG ulRandomLen /* # of bytes to generate */
);
#endif
/* Parallel function management */
/* C_GetFunctionStatus is a legacy function; it obtains an
* updated status of a function running in parallel with an
* application.
*/
CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_CancelFunction is a legacy function; it cancels a function
* running in parallel.
*/
CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession /* the session's handle */
);
#endif
/* C_WaitForSlotEvent waits for a slot event (token insertion,
* removal, etc.) to occur.
*/
CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
#ifdef CK_NEED_ARG_LIST
(
CK_FLAGS flags, /* blocking/nonblocking flag */
CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
);
#endif

33
vendor/github.com/miekg/pkcs11/pkcs11go.h generated vendored Normal file
View File

@ -0,0 +1,33 @@
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
#define CK_PTR *
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
#include <unistd.h>
#ifdef PACKED_STRUCTURES
# pragma pack(push, 1)
# include "pkcs11.h"
# pragma pack(pop)
#else
# include "pkcs11.h"
#endif
// Copy of CK_INFO but with default alignment (not packed). Go hides unaligned
// struct fields so copying to an aligned struct is necessary to read CK_INFO
// from Go on Windows where packing is required.
typedef struct ckInfo {
CK_VERSION cryptokiVersion;
CK_UTF8CHAR manufacturerID[32];
CK_FLAGS flags;
CK_UTF8CHAR libraryDescription[32];
CK_VERSION libraryVersion;
} ckInfo, *ckInfoPtr;

2047
vendor/github.com/miekg/pkcs11/pkcs11t.h generated vendored Normal file

File diff suppressed because it is too large Load Diff

18
vendor/github.com/miekg/pkcs11/release.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
//go:build release
// +build release
package pkcs11
import "fmt"
// Release is current version of the pkcs11 library.
var Release = R{1, 1, 1}
// R holds the version of this library.
type R struct {
Major, Minor, Patch int
}
func (r R) String() string {
return fmt.Sprintf("%d.%d.%d", r.Major, r.Minor, r.Patch)
}

1
vendor/github.com/miekg/pkcs11/softhsm.conf generated vendored Normal file
View File

@ -0,0 +1 @@
0:hsm.db

4
vendor/github.com/miekg/pkcs11/softhsm2.conf generated vendored Normal file
View File

@ -0,0 +1,4 @@
log.level = INFO
objectstore.backend = file
directories.tokendir = test_data
slots.removable = false

315
vendor/github.com/miekg/pkcs11/types.go generated vendored Normal file
View File

@ -0,0 +1,315 @@
// Copyright 2013 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package pkcs11
/*
#include <stdlib.h>
#include <string.h>
#include "pkcs11go.h"
CK_ULONG Index(CK_ULONG_PTR array, CK_ULONG i)
{
return array[i];
}
static inline void putAttributePval(CK_ATTRIBUTE_PTR a, CK_VOID_PTR pValue)
{
a->pValue = pValue;
}
static inline void putMechanismParam(CK_MECHANISM_PTR m, CK_VOID_PTR pParameter)
{
m->pParameter = pParameter;
}
*/
import "C"
import (
"fmt"
"time"
"unsafe"
)
type arena []unsafe.Pointer
func (a *arena) Allocate(obj []byte) (C.CK_VOID_PTR, C.CK_ULONG) {
cobj := C.calloc(C.size_t(len(obj)), 1)
*a = append(*a, cobj)
C.memmove(cobj, unsafe.Pointer(&obj[0]), C.size_t(len(obj)))
return C.CK_VOID_PTR(cobj), C.CK_ULONG(len(obj))
}
func (a arena) Free() {
for _, p := range a {
C.free(p)
}
}
// toList converts from a C style array to a []uint.
func toList(clist C.CK_ULONG_PTR, size C.CK_ULONG) []uint {
l := make([]uint, int(size))
for i := 0; i < len(l); i++ {
l[i] = uint(C.Index(clist, C.CK_ULONG(i)))
}
defer C.free(unsafe.Pointer(clist))
return l
}
// cBBool converts a bool to a CK_BBOOL.
func cBBool(x bool) C.CK_BBOOL {
if x {
return C.CK_BBOOL(C.CK_TRUE)
}
return C.CK_BBOOL(C.CK_FALSE)
}
func uintToBytes(x uint64) []byte {
ul := C.CK_ULONG(x)
return C.GoBytes(unsafe.Pointer(&ul), C.int(unsafe.Sizeof(ul)))
}
// Error represents an PKCS#11 error.
type Error uint
func (e Error) Error() string {
return fmt.Sprintf("pkcs11: 0x%X: %s", uint(e), strerror[uint(e)])
}
func toError(e C.CK_RV) error {
if e == C.CKR_OK {
return nil
}
return Error(e)
}
// SessionHandle is a Cryptoki-assigned value that identifies a session.
type SessionHandle uint
// ObjectHandle is a token-specific identifier for an object.
type ObjectHandle uint
// Version represents any version information from the library.
type Version struct {
Major byte
Minor byte
}
func toVersion(version C.CK_VERSION) Version {
return Version{byte(version.major), byte(version.minor)}
}
// SlotEvent holds the SlotID which for which an slot event (token insertion,
// removal, etc.) occurred.
type SlotEvent struct {
SlotID uint
}
// Info provides information about the library and hardware used.
type Info struct {
CryptokiVersion Version
ManufacturerID string
Flags uint
LibraryDescription string
LibraryVersion Version
}
// SlotInfo provides information about a slot.
type SlotInfo struct {
SlotDescription string // 64 bytes.
ManufacturerID string // 32 bytes.
Flags uint
HardwareVersion Version
FirmwareVersion Version
}
// TokenInfo provides information about a token.
type TokenInfo struct {
Label string
ManufacturerID string
Model string
SerialNumber string
Flags uint
MaxSessionCount uint
SessionCount uint
MaxRwSessionCount uint
RwSessionCount uint
MaxPinLen uint
MinPinLen uint
TotalPublicMemory uint
FreePublicMemory uint
TotalPrivateMemory uint
FreePrivateMemory uint
HardwareVersion Version
FirmwareVersion Version
UTCTime string
}
// SessionInfo provides information about a session.
type SessionInfo struct {
SlotID uint
State uint
Flags uint
DeviceError uint
}
// Attribute holds an attribute type/value combination.
type Attribute struct {
Type uint
Value []byte
}
// NewAttribute allocates a Attribute and returns a pointer to it.
// Note that this is merely a convenience function, as values returned
// from the HSM are not converted back to Go values, those are just raw
// byte slices.
func NewAttribute(typ uint, x interface{}) *Attribute {
// This function nicely transforms *to* an attribute, but there is
// no corresponding function that transform back *from* an attribute,
// which in PKCS#11 is just an byte array.
a := new(Attribute)
a.Type = typ
if x == nil {
return a
}
switch v := x.(type) {
case bool:
if v {
a.Value = []byte{1}
} else {
a.Value = []byte{0}
}
case int:
a.Value = uintToBytes(uint64(v))
case int16:
a.Value = uintToBytes(uint64(v))
case int32:
a.Value = uintToBytes(uint64(v))
case int64:
a.Value = uintToBytes(uint64(v))
case uint:
a.Value = uintToBytes(uint64(v))
case uint16:
a.Value = uintToBytes(uint64(v))
case uint32:
a.Value = uintToBytes(uint64(v))
case uint64:
a.Value = uintToBytes(uint64(v))
case string:
a.Value = []byte(v)
case []byte:
a.Value = v
case time.Time: // for CKA_DATE
a.Value = cDate(v)
default:
panic("pkcs11: unhandled attribute type")
}
return a
}
// cAttribute returns the start address and the length of an attribute list.
func cAttributeList(a []*Attribute) (arena, C.CK_ATTRIBUTE_PTR, C.CK_ULONG) {
var arena arena
if len(a) == 0 {
return nil, nil, 0
}
pa := make([]C.CK_ATTRIBUTE, len(a))
for i, attr := range a {
pa[i]._type = C.CK_ATTRIBUTE_TYPE(attr.Type)
if len(attr.Value) != 0 {
buf, len := arena.Allocate(attr.Value)
// field is unaligned on windows so this has to call into C
C.putAttributePval(&pa[i], buf)
pa[i].ulValueLen = len
}
}
return arena, &pa[0], C.CK_ULONG(len(a))
}
func cDate(t time.Time) []byte {
b := make([]byte, 8)
year, month, day := t.Date()
y := fmt.Sprintf("%4d", year)
m := fmt.Sprintf("%02d", month)
d1 := fmt.Sprintf("%02d", day)
b[0], b[1], b[2], b[3] = y[0], y[1], y[2], y[3]
b[4], b[5] = m[0], m[1]
b[6], b[7] = d1[0], d1[1]
return b
}
// Mechanism holds an mechanism type/value combination.
type Mechanism struct {
Mechanism uint
Parameter []byte
generator interface{}
}
// NewMechanism returns a pointer to an initialized Mechanism.
func NewMechanism(mech uint, x interface{}) *Mechanism {
m := new(Mechanism)
m.Mechanism = mech
if x == nil {
return m
}
switch p := x.(type) {
case *GCMParams, *OAEPParams, *ECDH1DeriveParams:
// contains pointers; defer serialization until cMechanism
m.generator = p
case []byte:
m.Parameter = p
default:
panic("parameter must be one of type: []byte, *GCMParams, *OAEPParams, *ECDH1DeriveParams")
}
return m
}
func cMechanism(mechList []*Mechanism) (arena, *C.CK_MECHANISM) {
if len(mechList) != 1 {
panic("expected exactly one mechanism")
}
mech := mechList[0]
cmech := &C.CK_MECHANISM{mechanism: C.CK_MECHANISM_TYPE(mech.Mechanism)}
// params that contain pointers are allocated here
param := mech.Parameter
var arena arena
switch p := mech.generator.(type) {
case *GCMParams:
// uses its own arena because it has to outlive this function call (yuck)
param = cGCMParams(p)
case *OAEPParams:
param, arena = cOAEPParams(p, arena)
case *ECDH1DeriveParams:
param, arena = cECDH1DeriveParams(p, arena)
}
if len(param) != 0 {
buf, len := arena.Allocate(param)
// field is unaligned on windows so this has to call into C
C.putMechanismParam(cmech, buf)
cmech.ulParameterLen = len
}
return arena, cmech
}
// MechanismInfo provides information about a particular mechanism.
type MechanismInfo struct {
MinKeySize uint
MaxKeySize uint
Flags uint
}
// stubData is a persistent nonempty byte array used by cMessage.
var stubData = []byte{0}
// cMessage returns the pointer/length pair corresponding to data.
func cMessage(data []byte) (dataPtr C.CK_BYTE_PTR) {
l := len(data)
if l == 0 {
// &data[0] is forbidden in this case, so use a nontrivial array instead.
data = stubData
}
return C.CK_BYTE_PTR(unsafe.Pointer(&data[0]))
}

127
vendor/github.com/miekg/pkcs11/vendor.go generated vendored Normal file
View File

@ -0,0 +1,127 @@
package pkcs11
// Vendor specific range for Ncipher network HSM.
const (
NFCK_VENDOR_NCIPHER = 0xde436972
CKA_NCIPHER = NFCK_VENDOR_NCIPHER
CKM_NCIPHER = NFCK_VENDOR_NCIPHER
CKK_NCIPHER = NFCK_VENDOR_NCIPHER
)
// Vendor specific mechanisms for HMAC on Ncipher HSMs where Ncipher does not allow use of generic_secret keys.
const (
CKM_NC_SHA_1_HMAC_KEY_GEN = CKM_NCIPHER + 0x3 /* no params */
CKM_NC_MD5_HMAC_KEY_GEN = CKM_NCIPHER + 0x6 /* no params */
CKM_NC_SHA224_HMAC_KEY_GEN = CKM_NCIPHER + 0x24 /* no params */
CKM_NC_SHA256_HMAC_KEY_GEN = CKM_NCIPHER + 0x25 /* no params */
CKM_NC_SHA384_HMAC_KEY_GEN = CKM_NCIPHER + 0x26 /* no params */
CKM_NC_SHA512_HMAC_KEY_GEN = CKM_NCIPHER + 0x27 /* no params */
)
// Vendor specific range for Mozilla NSS.
const (
NSSCK_VENDOR_NSS = 0x4E534350
CKO_NSS = CKO_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKK_NSS = CKK_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKC_NSS = CKC_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKA_NSS = CKA_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKA_TRUST = CKA_NSS + 0x2000
CKM_NSS = CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKR_NSS = CKM_VENDOR_DEFINED | NSSCK_VENDOR_NSS
CKT_VENDOR_DEFINED = 0x80000000
CKT_NSS = CKT_VENDOR_DEFINED | NSSCK_VENDOR_NSS
)
// Vendor specific values for Mozilla NSS.
const (
CKO_NSS_CRL = CKO_NSS + 1
CKO_NSS_SMIME = CKO_NSS + 2
CKO_NSS_TRUST = CKO_NSS + 3
CKO_NSS_BUILTIN_ROOT_LIST = CKO_NSS + 4
CKO_NSS_NEWSLOT = CKO_NSS + 5
CKO_NSS_DELSLOT = CKO_NSS + 6
CKK_NSS_PKCS8 = CKK_NSS + 1
CKK_NSS_JPAKE_ROUND1 = CKK_NSS + 2
CKK_NSS_JPAKE_ROUND2 = CKK_NSS + 3
CKK_NSS_CHACHA20 = CKK_NSS + 4
CKA_NSS_URL = CKA_NSS + 1
CKA_NSS_EMAIL = CKA_NSS + 2
CKA_NSS_SMIME_INFO = CKA_NSS + 3
CKA_NSS_SMIME_TIMESTAMP = CKA_NSS + 4
CKA_NSS_PKCS8_SALT = CKA_NSS + 5
CKA_NSS_PASSWORD_CHECK = CKA_NSS + 6
CKA_NSS_EXPIRES = CKA_NSS + 7
CKA_NSS_KRL = CKA_NSS + 8
CKA_NSS_PQG_COUNTER = CKA_NSS + 20
CKA_NSS_PQG_SEED = CKA_NSS + 21
CKA_NSS_PQG_H = CKA_NSS + 22
CKA_NSS_PQG_SEED_BITS = CKA_NSS + 23
CKA_NSS_MODULE_SPEC = CKA_NSS + 24
CKA_NSS_OVERRIDE_EXTENSIONS = CKA_NSS + 25
CKA_NSS_JPAKE_SIGNERID = CKA_NSS + 26
CKA_NSS_JPAKE_PEERID = CKA_NSS + 27
CKA_NSS_JPAKE_GX1 = CKA_NSS + 28
CKA_NSS_JPAKE_GX2 = CKA_NSS + 29
CKA_NSS_JPAKE_GX3 = CKA_NSS + 30
CKA_NSS_JPAKE_GX4 = CKA_NSS + 31
CKA_NSS_JPAKE_X2 = CKA_NSS + 32
CKA_NSS_JPAKE_X2S = CKA_NSS + 33
CKA_NSS_MOZILLA_CA_POLICY = CKA_NSS + 34
CKA_TRUST_DIGITAL_SIGNATURE = CKA_TRUST + 1
CKA_TRUST_NON_REPUDIATION = CKA_TRUST + 2
CKA_TRUST_KEY_ENCIPHERMENT = CKA_TRUST + 3
CKA_TRUST_DATA_ENCIPHERMENT = CKA_TRUST + 4
CKA_TRUST_KEY_AGREEMENT = CKA_TRUST + 5
CKA_TRUST_KEY_CERT_SIGN = CKA_TRUST + 6
CKA_TRUST_CRL_SIGN = CKA_TRUST + 7
CKA_TRUST_SERVER_AUTH = CKA_TRUST + 8
CKA_TRUST_CLIENT_AUTH = CKA_TRUST + 9
CKA_TRUST_CODE_SIGNING = CKA_TRUST + 10
CKA_TRUST_EMAIL_PROTECTION = CKA_TRUST + 11
CKA_TRUST_IPSEC_END_SYSTEM = CKA_TRUST + 12
CKA_TRUST_IPSEC_TUNNEL = CKA_TRUST + 13
CKA_TRUST_IPSEC_USER = CKA_TRUST + 14
CKA_TRUST_TIME_STAMPING = CKA_TRUST + 15
CKA_TRUST_STEP_UP_APPROVED = CKA_TRUST + 16
CKA_CERT_SHA1_HASH = CKA_TRUST + 100
CKA_CERT_MD5_HASH = CKA_TRUST + 101
CKM_NSS_AES_KEY_WRAP = CKM_NSS + 1
CKM_NSS_AES_KEY_WRAP_PAD = CKM_NSS + 2
CKM_NSS_HKDF_SHA1 = CKM_NSS + 3
CKM_NSS_HKDF_SHA256 = CKM_NSS + 4
CKM_NSS_HKDF_SHA384 = CKM_NSS + 5
CKM_NSS_HKDF_SHA512 = CKM_NSS + 6
CKM_NSS_JPAKE_ROUND1_SHA1 = CKM_NSS + 7
CKM_NSS_JPAKE_ROUND1_SHA256 = CKM_NSS + 8
CKM_NSS_JPAKE_ROUND1_SHA384 = CKM_NSS + 9
CKM_NSS_JPAKE_ROUND1_SHA512 = CKM_NSS + 10
CKM_NSS_JPAKE_ROUND2_SHA1 = CKM_NSS + 11
CKM_NSS_JPAKE_ROUND2_SHA256 = CKM_NSS + 12
CKM_NSS_JPAKE_ROUND2_SHA384 = CKM_NSS + 13
CKM_NSS_JPAKE_ROUND2_SHA512 = CKM_NSS + 14
CKM_NSS_JPAKE_FINAL_SHA1 = CKM_NSS + 15
CKM_NSS_JPAKE_FINAL_SHA256 = CKM_NSS + 16
CKM_NSS_JPAKE_FINAL_SHA384 = CKM_NSS + 17
CKM_NSS_JPAKE_FINAL_SHA512 = CKM_NSS + 18
CKM_NSS_HMAC_CONSTANT_TIME = CKM_NSS + 19
CKM_NSS_SSL3_MAC_CONSTANT_TIME = CKM_NSS + 20
CKM_NSS_TLS_PRF_GENERAL_SHA256 = CKM_NSS + 21
CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256 = CKM_NSS + 22
CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256 = CKM_NSS + 23
CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 = CKM_NSS + 24
CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE = CKM_NSS + 25
CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH = CKM_NSS + 26
CKM_NSS_CHACHA20_KEY_GEN = CKM_NSS + 27
CKM_NSS_CHACHA20_POLY1305 = CKM_NSS + 28
CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN = CKM_NSS + 29
CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN = CKM_NSS + 30
CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN = CKM_NSS + 31
CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN = CKM_NSS + 32
CKR_NSS_CERTDB_FAILED = CKR_NSS + 1
CKR_NSS_KEYDB_FAILED = CKR_NSS + 2
CKT_NSS_TRUSTED = CKT_NSS + 1
CKT_NSS_TRUSTED_DELEGATOR = CKT_NSS + 2
CKT_NSS_MUST_VERIFY_TRUST = CKT_NSS + 3
CKT_NSS_NOT_TRUSTED = CKT_NSS + 10
CKT_NSS_TRUST_UNKNOWN = CKT_NSS + 5
)

766
vendor/github.com/miekg/pkcs11/zconst.go generated vendored Normal file
View File

@ -0,0 +1,766 @@
// Copyright 2013 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Code generated by "go run const_generate.go"; DO NOT EDIT.
package pkcs11
const (
CK_TRUE = 1
CK_FALSE = 0
CK_UNAVAILABLE_INFORMATION = ^uint(0)
CK_EFFECTIVELY_INFINITE = 0
CK_INVALID_HANDLE = 0
CKN_SURRENDER = 0
CKN_OTP_CHANGED = 1
CKF_TOKEN_PRESENT = 0x00000001
CKF_REMOVABLE_DEVICE = 0x00000002
CKF_HW_SLOT = 0x00000004
CKF_RNG = 0x00000001
CKF_WRITE_PROTECTED = 0x00000002
CKF_LOGIN_REQUIRED = 0x00000004
CKF_USER_PIN_INITIALIZED = 0x00000008
CKF_RESTORE_KEY_NOT_NEEDED = 0x00000020
CKF_CLOCK_ON_TOKEN = 0x00000040
CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100
CKF_DUAL_CRYPTO_OPERATIONS = 0x00000200
CKF_TOKEN_INITIALIZED = 0x00000400
CKF_SECONDARY_AUTHENTICATION = 0x00000800
CKF_USER_PIN_COUNT_LOW = 0x00010000
CKF_USER_PIN_FINAL_TRY = 0x00020000
CKF_USER_PIN_LOCKED = 0x00040000
CKF_USER_PIN_TO_BE_CHANGED = 0x00080000
CKF_SO_PIN_COUNT_LOW = 0x00100000
CKF_SO_PIN_FINAL_TRY = 0x00200000
CKF_SO_PIN_LOCKED = 0x00400000
CKF_SO_PIN_TO_BE_CHANGED = 0x00800000
CKF_ERROR_STATE = 0x01000000
CKU_SO = 0
CKU_USER = 1
CKU_CONTEXT_SPECIFIC = 2
CKS_RO_PUBLIC_SESSION = 0
CKS_RO_USER_FUNCTIONS = 1
CKS_RW_PUBLIC_SESSION = 2
CKS_RW_USER_FUNCTIONS = 3
CKS_RW_SO_FUNCTIONS = 4
CKF_RW_SESSION = 0x00000002
CKF_SERIAL_SESSION = 0x00000004
CKO_DATA = 0x00000000
CKO_CERTIFICATE = 0x00000001
CKO_PUBLIC_KEY = 0x00000002
CKO_PRIVATE_KEY = 0x00000003
CKO_SECRET_KEY = 0x00000004
CKO_HW_FEATURE = 0x00000005
CKO_DOMAIN_PARAMETERS = 0x00000006
CKO_MECHANISM = 0x00000007
CKO_OTP_KEY = 0x00000008
CKO_VENDOR_DEFINED = 0x80000000
CKH_MONOTONIC_COUNTER = 0x00000001
CKH_CLOCK = 0x00000002
CKH_USER_INTERFACE = 0x00000003
CKH_VENDOR_DEFINED = 0x80000000
CKK_RSA = 0x00000000
CKK_DSA = 0x00000001
CKK_DH = 0x00000002
CKK_ECDSA = 0x00000003 // Deprecated
CKK_EC = 0x00000003
CKK_X9_42_DH = 0x00000004
CKK_KEA = 0x00000005
CKK_GENERIC_SECRET = 0x00000010
CKK_RC2 = 0x00000011
CKK_RC4 = 0x00000012
CKK_DES = 0x00000013
CKK_DES2 = 0x00000014
CKK_DES3 = 0x00000015
CKK_CAST = 0x00000016
CKK_CAST3 = 0x00000017
CKK_CAST5 = 0x00000018 // Deprecated
CKK_CAST128 = 0x00000018
CKK_RC5 = 0x00000019
CKK_IDEA = 0x0000001A
CKK_SKIPJACK = 0x0000001B
CKK_BATON = 0x0000001C
CKK_JUNIPER = 0x0000001D
CKK_CDMF = 0x0000001E
CKK_AES = 0x0000001F
CKK_BLOWFISH = 0x00000020
CKK_TWOFISH = 0x00000021
CKK_SECURID = 0x00000022
CKK_HOTP = 0x00000023
CKK_ACTI = 0x00000024
CKK_CAMELLIA = 0x00000025
CKK_ARIA = 0x00000026
CKK_MD5_HMAC = 0x00000027
CKK_SHA_1_HMAC = 0x00000028
CKK_RIPEMD128_HMAC = 0x00000029
CKK_RIPEMD160_HMAC = 0x0000002A
CKK_SHA256_HMAC = 0x0000002B
CKK_SHA384_HMAC = 0x0000002C
CKK_SHA512_HMAC = 0x0000002D
CKK_SHA224_HMAC = 0x0000002E
CKK_SEED = 0x0000002F
CKK_GOSTR3410 = 0x00000030
CKK_GOSTR3411 = 0x00000031
CKK_GOST28147 = 0x00000032
CKK_SHA3_224_HMAC = 0x00000033
CKK_SHA3_256_HMAC = 0x00000034
CKK_SHA3_384_HMAC = 0x00000035
CKK_SHA3_512_HMAC = 0x00000036
CKK_VENDOR_DEFINED = 0x80000000
CK_CERTIFICATE_CATEGORY_UNSPECIFIED = 0
CK_CERTIFICATE_CATEGORY_TOKEN_USER = 1
CK_CERTIFICATE_CATEGORY_AUTHORITY = 2
CK_CERTIFICATE_CATEGORY_OTHER_ENTITY = 3
CK_SECURITY_DOMAIN_UNSPECIFIED = 0
CK_SECURITY_DOMAIN_MANUFACTURER = 1
CK_SECURITY_DOMAIN_OPERATOR = 2
CK_SECURITY_DOMAIN_THIRD_PARTY = 3
CKC_X_509 = 0x00000000
CKC_X_509_ATTR_CERT = 0x00000001
CKC_WTLS = 0x00000002
CKC_VENDOR_DEFINED = 0x80000000
CKF_ARRAY_ATTRIBUTE = 0x40000000
CK_OTP_FORMAT_DECIMAL = 0
CK_OTP_FORMAT_HEXADECIMAL = 1
CK_OTP_FORMAT_ALPHANUMERIC = 2
CK_OTP_FORMAT_BINARY = 3
CK_OTP_PARAM_IGNORED = 0
CK_OTP_PARAM_OPTIONAL = 1
CK_OTP_PARAM_MANDATORY = 2
CKA_CLASS = 0x00000000
CKA_TOKEN = 0x00000001
CKA_PRIVATE = 0x00000002
CKA_LABEL = 0x00000003
CKA_APPLICATION = 0x00000010
CKA_VALUE = 0x00000011
CKA_OBJECT_ID = 0x00000012
CKA_CERTIFICATE_TYPE = 0x00000080
CKA_ISSUER = 0x00000081
CKA_SERIAL_NUMBER = 0x00000082
CKA_AC_ISSUER = 0x00000083
CKA_OWNER = 0x00000084
CKA_ATTR_TYPES = 0x00000085
CKA_TRUSTED = 0x00000086
CKA_CERTIFICATE_CATEGORY = 0x00000087
CKA_JAVA_MIDP_SECURITY_DOMAIN = 0x00000088
CKA_URL = 0x00000089
CKA_HASH_OF_SUBJECT_PUBLIC_KEY = 0x0000008A
CKA_HASH_OF_ISSUER_PUBLIC_KEY = 0x0000008B
CKA_NAME_HASH_ALGORITHM = 0x0000008C
CKA_CHECK_VALUE = 0x00000090
CKA_KEY_TYPE = 0x00000100
CKA_SUBJECT = 0x00000101
CKA_ID = 0x00000102
CKA_SENSITIVE = 0x00000103
CKA_ENCRYPT = 0x00000104
CKA_DECRYPT = 0x00000105
CKA_WRAP = 0x00000106
CKA_UNWRAP = 0x00000107
CKA_SIGN = 0x00000108
CKA_SIGN_RECOVER = 0x00000109
CKA_VERIFY = 0x0000010A
CKA_VERIFY_RECOVER = 0x0000010B
CKA_DERIVE = 0x0000010C
CKA_START_DATE = 0x00000110
CKA_END_DATE = 0x00000111
CKA_MODULUS = 0x00000120
CKA_MODULUS_BITS = 0x00000121
CKA_PUBLIC_EXPONENT = 0x00000122
CKA_PRIVATE_EXPONENT = 0x00000123
CKA_PRIME_1 = 0x00000124
CKA_PRIME_2 = 0x00000125
CKA_EXPONENT_1 = 0x00000126
CKA_EXPONENT_2 = 0x00000127
CKA_COEFFICIENT = 0x00000128
CKA_PUBLIC_KEY_INFO = 0x00000129
CKA_PRIME = 0x00000130
CKA_SUBPRIME = 0x00000131
CKA_BASE = 0x00000132
CKA_PRIME_BITS = 0x00000133
CKA_SUBPRIME_BITS = 0x00000134
CKA_SUB_PRIME_BITS = CKA_SUBPRIME_BITS
CKA_VALUE_BITS = 0x00000160
CKA_VALUE_LEN = 0x00000161
CKA_EXTRACTABLE = 0x00000162
CKA_LOCAL = 0x00000163
CKA_NEVER_EXTRACTABLE = 0x00000164
CKA_ALWAYS_SENSITIVE = 0x00000165
CKA_KEY_GEN_MECHANISM = 0x00000166
CKA_MODIFIABLE = 0x00000170
CKA_COPYABLE = 0x00000171
CKA_DESTROYABLE = 0x00000172
CKA_ECDSA_PARAMS = 0x00000180 // Deprecated
CKA_EC_PARAMS = 0x00000180
CKA_EC_POINT = 0x00000181
CKA_SECONDARY_AUTH = 0x00000200 // Deprecated
CKA_AUTH_PIN_FLAGS = 0x00000201 // Deprecated
CKA_ALWAYS_AUTHENTICATE = 0x00000202
CKA_WRAP_WITH_TRUSTED = 0x00000210
CKA_WRAP_TEMPLATE = (CKF_ARRAY_ATTRIBUTE | 0x00000211)
CKA_UNWRAP_TEMPLATE = (CKF_ARRAY_ATTRIBUTE | 0x00000212)
CKA_DERIVE_TEMPLATE = (CKF_ARRAY_ATTRIBUTE | 0x00000213)
CKA_OTP_FORMAT = 0x00000220
CKA_OTP_LENGTH = 0x00000221
CKA_OTP_TIME_INTERVAL = 0x00000222
CKA_OTP_USER_FRIENDLY_MODE = 0x00000223
CKA_OTP_CHALLENGE_REQUIREMENT = 0x00000224
CKA_OTP_TIME_REQUIREMENT = 0x00000225
CKA_OTP_COUNTER_REQUIREMENT = 0x00000226
CKA_OTP_PIN_REQUIREMENT = 0x00000227
CKA_OTP_COUNTER = 0x0000022E
CKA_OTP_TIME = 0x0000022F
CKA_OTP_USER_IDENTIFIER = 0x0000022A
CKA_OTP_SERVICE_IDENTIFIER = 0x0000022B
CKA_OTP_SERVICE_LOGO = 0x0000022C
CKA_OTP_SERVICE_LOGO_TYPE = 0x0000022D
CKA_GOSTR3410_PARAMS = 0x00000250
CKA_GOSTR3411_PARAMS = 0x00000251
CKA_GOST28147_PARAMS = 0x00000252
CKA_HW_FEATURE_TYPE = 0x00000300
CKA_RESET_ON_INIT = 0x00000301
CKA_HAS_RESET = 0x00000302
CKA_PIXEL_X = 0x00000400
CKA_PIXEL_Y = 0x00000401
CKA_RESOLUTION = 0x00000402
CKA_CHAR_ROWS = 0x00000403
CKA_CHAR_COLUMNS = 0x00000404
CKA_COLOR = 0x00000405
CKA_BITS_PER_PIXEL = 0x00000406
CKA_CHAR_SETS = 0x00000480
CKA_ENCODING_METHODS = 0x00000481
CKA_MIME_TYPES = 0x00000482
CKA_MECHANISM_TYPE = 0x00000500
CKA_REQUIRED_CMS_ATTRIBUTES = 0x00000501
CKA_DEFAULT_CMS_ATTRIBUTES = 0x00000502
CKA_SUPPORTED_CMS_ATTRIBUTES = 0x00000503
CKA_ALLOWED_MECHANISMS = (CKF_ARRAY_ATTRIBUTE | 0x00000600)
CKA_VENDOR_DEFINED = 0x80000000
CKM_RSA_PKCS_KEY_PAIR_GEN = 0x00000000
CKM_RSA_PKCS = 0x00000001
CKM_RSA_9796 = 0x00000002
CKM_RSA_X_509 = 0x00000003
CKM_MD2_RSA_PKCS = 0x00000004
CKM_MD5_RSA_PKCS = 0x00000005
CKM_SHA1_RSA_PKCS = 0x00000006
CKM_RIPEMD128_RSA_PKCS = 0x00000007
CKM_RIPEMD160_RSA_PKCS = 0x00000008
CKM_RSA_PKCS_OAEP = 0x00000009
CKM_RSA_X9_31_KEY_PAIR_GEN = 0x0000000A
CKM_RSA_X9_31 = 0x0000000B
CKM_SHA1_RSA_X9_31 = 0x0000000C
CKM_RSA_PKCS_PSS = 0x0000000D
CKM_SHA1_RSA_PKCS_PSS = 0x0000000E
CKM_DSA_KEY_PAIR_GEN = 0x00000010
CKM_DSA = 0x00000011
CKM_DSA_SHA1 = 0x00000012
CKM_DSA_SHA224 = 0x00000013
CKM_DSA_SHA256 = 0x00000014
CKM_DSA_SHA384 = 0x00000015
CKM_DSA_SHA512 = 0x00000016
CKM_DSA_SHA3_224 = 0x00000018
CKM_DSA_SHA3_256 = 0x00000019
CKM_DSA_SHA3_384 = 0x0000001A
CKM_DSA_SHA3_512 = 0x0000001B
CKM_DH_PKCS_KEY_PAIR_GEN = 0x00000020
CKM_DH_PKCS_DERIVE = 0x00000021
CKM_X9_42_DH_KEY_PAIR_GEN = 0x00000030
CKM_X9_42_DH_DERIVE = 0x00000031
CKM_X9_42_DH_HYBRID_DERIVE = 0x00000032
CKM_X9_42_MQV_DERIVE = 0x00000033
CKM_SHA256_RSA_PKCS = 0x00000040
CKM_SHA384_RSA_PKCS = 0x00000041
CKM_SHA512_RSA_PKCS = 0x00000042
CKM_SHA256_RSA_PKCS_PSS = 0x00000043
CKM_SHA384_RSA_PKCS_PSS = 0x00000044
CKM_SHA512_RSA_PKCS_PSS = 0x00000045
CKM_SHA224_RSA_PKCS = 0x00000046
CKM_SHA224_RSA_PKCS_PSS = 0x00000047
CKM_SHA512_224 = 0x00000048
CKM_SHA512_224_HMAC = 0x00000049
CKM_SHA512_224_HMAC_GENERAL = 0x0000004A
CKM_SHA512_224_KEY_DERIVATION = 0x0000004B
CKM_SHA512_256 = 0x0000004C
CKM_SHA512_256_HMAC = 0x0000004D
CKM_SHA512_256_HMAC_GENERAL = 0x0000004E
CKM_SHA512_256_KEY_DERIVATION = 0x0000004F
CKM_SHA512_T = 0x00000050
CKM_SHA512_T_HMAC = 0x00000051
CKM_SHA512_T_HMAC_GENERAL = 0x00000052
CKM_SHA512_T_KEY_DERIVATION = 0x00000053
CKM_SHA3_256_RSA_PKCS = 0x00000060
CKM_SHA3_384_RSA_PKCS = 0x00000061
CKM_SHA3_512_RSA_PKCS = 0x00000062
CKM_SHA3_256_RSA_PKCS_PSS = 0x00000063
CKM_SHA3_384_RSA_PKCS_PSS = 0x00000064
CKM_SHA3_512_RSA_PKCS_PSS = 0x00000065
CKM_SHA3_224_RSA_PKCS = 0x00000066
CKM_SHA3_224_RSA_PKCS_PSS = 0x00000067
CKM_RC2_KEY_GEN = 0x00000100
CKM_RC2_ECB = 0x00000101
CKM_RC2_CBC = 0x00000102
CKM_RC2_MAC = 0x00000103
CKM_RC2_MAC_GENERAL = 0x00000104
CKM_RC2_CBC_PAD = 0x00000105
CKM_RC4_KEY_GEN = 0x00000110
CKM_RC4 = 0x00000111
CKM_DES_KEY_GEN = 0x00000120
CKM_DES_ECB = 0x00000121
CKM_DES_CBC = 0x00000122
CKM_DES_MAC = 0x00000123
CKM_DES_MAC_GENERAL = 0x00000124
CKM_DES_CBC_PAD = 0x00000125
CKM_DES2_KEY_GEN = 0x00000130
CKM_DES3_KEY_GEN = 0x00000131
CKM_DES3_ECB = 0x00000132
CKM_DES3_CBC = 0x00000133
CKM_DES3_MAC = 0x00000134
CKM_DES3_MAC_GENERAL = 0x00000135
CKM_DES3_CBC_PAD = 0x00000136
CKM_DES3_CMAC_GENERAL = 0x00000137
CKM_DES3_CMAC = 0x00000138
CKM_CDMF_KEY_GEN = 0x00000140
CKM_CDMF_ECB = 0x00000141
CKM_CDMF_CBC = 0x00000142
CKM_CDMF_MAC = 0x00000143
CKM_CDMF_MAC_GENERAL = 0x00000144
CKM_CDMF_CBC_PAD = 0x00000145
CKM_DES_OFB64 = 0x00000150
CKM_DES_OFB8 = 0x00000151
CKM_DES_CFB64 = 0x00000152
CKM_DES_CFB8 = 0x00000153
CKM_MD2 = 0x00000200
CKM_MD2_HMAC = 0x00000201
CKM_MD2_HMAC_GENERAL = 0x00000202
CKM_MD5 = 0x00000210
CKM_MD5_HMAC = 0x00000211
CKM_MD5_HMAC_GENERAL = 0x00000212
CKM_SHA_1 = 0x00000220
CKM_SHA_1_HMAC = 0x00000221
CKM_SHA_1_HMAC_GENERAL = 0x00000222
CKM_RIPEMD128 = 0x00000230
CKM_RIPEMD128_HMAC = 0x00000231
CKM_RIPEMD128_HMAC_GENERAL = 0x00000232
CKM_RIPEMD160 = 0x00000240
CKM_RIPEMD160_HMAC = 0x00000241
CKM_RIPEMD160_HMAC_GENERAL = 0x00000242
CKM_SHA256 = 0x00000250
CKM_SHA256_HMAC = 0x00000251
CKM_SHA256_HMAC_GENERAL = 0x00000252
CKM_SHA224 = 0x00000255
CKM_SHA224_HMAC = 0x00000256
CKM_SHA224_HMAC_GENERAL = 0x00000257
CKM_SHA384 = 0x00000260
CKM_SHA384_HMAC = 0x00000261
CKM_SHA384_HMAC_GENERAL = 0x00000262
CKM_SHA512 = 0x00000270
CKM_SHA512_HMAC = 0x00000271
CKM_SHA512_HMAC_GENERAL = 0x00000272
CKM_SECURID_KEY_GEN = 0x00000280
CKM_SECURID = 0x00000282
CKM_HOTP_KEY_GEN = 0x00000290
CKM_HOTP = 0x00000291
CKM_ACTI = 0x000002A0
CKM_ACTI_KEY_GEN = 0x000002A1
CKM_SHA3_256 = 0x000002B0
CKM_SHA3_256_HMAC = 0x000002B1
CKM_SHA3_256_HMAC_GENERAL = 0x000002B2
CKM_SHA3_256_KEY_GEN = 0x000002B3
CKM_SHA3_224 = 0x000002B5
CKM_SHA3_224_HMAC = 0x000002B6
CKM_SHA3_224_HMAC_GENERAL = 0x000002B7
CKM_SHA3_224_KEY_GEN = 0x000002B8
CKM_SHA3_384 = 0x000002C0
CKM_SHA3_384_HMAC = 0x000002C1
CKM_SHA3_384_HMAC_GENERAL = 0x000002C2
CKM_SHA3_384_KEY_GEN = 0x000002C3
CKM_SHA3_512 = 0x000002D0
CKM_SHA3_512_HMAC = 0x000002D1
CKM_SHA3_512_HMAC_GENERAL = 0x000002D2
CKM_SHA3_512_KEY_GEN = 0x000002D3
CKM_CAST_KEY_GEN = 0x00000300
CKM_CAST_ECB = 0x00000301
CKM_CAST_CBC = 0x00000302
CKM_CAST_MAC = 0x00000303
CKM_CAST_MAC_GENERAL = 0x00000304
CKM_CAST_CBC_PAD = 0x00000305
CKM_CAST3_KEY_GEN = 0x00000310
CKM_CAST3_ECB = 0x00000311
CKM_CAST3_CBC = 0x00000312
CKM_CAST3_MAC = 0x00000313
CKM_CAST3_MAC_GENERAL = 0x00000314
CKM_CAST3_CBC_PAD = 0x00000315
CKM_CAST5_KEY_GEN = 0x00000320
CKM_CAST128_KEY_GEN = 0x00000320
CKM_CAST5_ECB = 0x00000321
CKM_CAST128_ECB = 0x00000321
CKM_CAST5_CBC = 0x00000322 // Deprecated
CKM_CAST128_CBC = 0x00000322
CKM_CAST5_MAC = 0x00000323 // Deprecated
CKM_CAST128_MAC = 0x00000323
CKM_CAST5_MAC_GENERAL = 0x00000324 // Deprecated
CKM_CAST128_MAC_GENERAL = 0x00000324
CKM_CAST5_CBC_PAD = 0x00000325 // Deprecated
CKM_CAST128_CBC_PAD = 0x00000325
CKM_RC5_KEY_GEN = 0x00000330
CKM_RC5_ECB = 0x00000331
CKM_RC5_CBC = 0x00000332
CKM_RC5_MAC = 0x00000333
CKM_RC5_MAC_GENERAL = 0x00000334
CKM_RC5_CBC_PAD = 0x00000335
CKM_IDEA_KEY_GEN = 0x00000340
CKM_IDEA_ECB = 0x00000341
CKM_IDEA_CBC = 0x00000342
CKM_IDEA_MAC = 0x00000343
CKM_IDEA_MAC_GENERAL = 0x00000344
CKM_IDEA_CBC_PAD = 0x00000345
CKM_GENERIC_SECRET_KEY_GEN = 0x00000350
CKM_CONCATENATE_BASE_AND_KEY = 0x00000360
CKM_CONCATENATE_BASE_AND_DATA = 0x00000362
CKM_CONCATENATE_DATA_AND_BASE = 0x00000363
CKM_XOR_BASE_AND_DATA = 0x00000364
CKM_EXTRACT_KEY_FROM_KEY = 0x00000365
CKM_SSL3_PRE_MASTER_KEY_GEN = 0x00000370
CKM_SSL3_MASTER_KEY_DERIVE = 0x00000371
CKM_SSL3_KEY_AND_MAC_DERIVE = 0x00000372
CKM_SSL3_MASTER_KEY_DERIVE_DH = 0x00000373
CKM_TLS_PRE_MASTER_KEY_GEN = 0x00000374
CKM_TLS_MASTER_KEY_DERIVE = 0x00000375
CKM_TLS_KEY_AND_MAC_DERIVE = 0x00000376
CKM_TLS_MASTER_KEY_DERIVE_DH = 0x00000377
CKM_TLS_PRF = 0x00000378
CKM_SSL3_MD5_MAC = 0x00000380
CKM_SSL3_SHA1_MAC = 0x00000381
CKM_MD5_KEY_DERIVATION = 0x00000390
CKM_MD2_KEY_DERIVATION = 0x00000391
CKM_SHA1_KEY_DERIVATION = 0x00000392
CKM_SHA256_KEY_DERIVATION = 0x00000393
CKM_SHA384_KEY_DERIVATION = 0x00000394
CKM_SHA512_KEY_DERIVATION = 0x00000395
CKM_SHA224_KEY_DERIVATION = 0x00000396
CKM_SHA3_256_KEY_DERIVE = 0x00000397
CKM_SHA3_224_KEY_DERIVE = 0x00000398
CKM_SHA3_384_KEY_DERIVE = 0x00000399
CKM_SHA3_512_KEY_DERIVE = 0x0000039A
CKM_SHAKE_128_KEY_DERIVE = 0x0000039B
CKM_SHAKE_256_KEY_DERIVE = 0x0000039C
CKM_PBE_MD2_DES_CBC = 0x000003A0
CKM_PBE_MD5_DES_CBC = 0x000003A1
CKM_PBE_MD5_CAST_CBC = 0x000003A2
CKM_PBE_MD5_CAST3_CBC = 0x000003A3
CKM_PBE_MD5_CAST5_CBC = 0x000003A4 // Deprecated
CKM_PBE_MD5_CAST128_CBC = 0x000003A4
CKM_PBE_SHA1_CAST5_CBC = 0x000003A5 // Deprecated
CKM_PBE_SHA1_CAST128_CBC = 0x000003A5
CKM_PBE_SHA1_RC4_128 = 0x000003A6
CKM_PBE_SHA1_RC4_40 = 0x000003A7
CKM_PBE_SHA1_DES3_EDE_CBC = 0x000003A8
CKM_PBE_SHA1_DES2_EDE_CBC = 0x000003A9
CKM_PBE_SHA1_RC2_128_CBC = 0x000003AA
CKM_PBE_SHA1_RC2_40_CBC = 0x000003AB
CKM_PKCS5_PBKD2 = 0x000003B0
CKM_PBA_SHA1_WITH_SHA1_HMAC = 0x000003C0
CKM_WTLS_PRE_MASTER_KEY_GEN = 0x000003D0
CKM_WTLS_MASTER_KEY_DERIVE = 0x000003D1
CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC = 0x000003D2
CKM_WTLS_PRF = 0x000003D3
CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE = 0x000003D4
CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE = 0x000003D5
CKM_TLS10_MAC_SERVER = 0x000003D6
CKM_TLS10_MAC_CLIENT = 0x000003D7
CKM_TLS12_MAC = 0x000003D8
CKM_TLS12_KDF = 0x000003D9
CKM_TLS12_MASTER_KEY_DERIVE = 0x000003E0
CKM_TLS12_KEY_AND_MAC_DERIVE = 0x000003E1
CKM_TLS12_MASTER_KEY_DERIVE_DH = 0x000003E2
CKM_TLS12_KEY_SAFE_DERIVE = 0x000003E3
CKM_TLS_MAC = 0x000003E4
CKM_TLS_KDF = 0x000003E5
CKM_KEY_WRAP_LYNKS = 0x00000400
CKM_KEY_WRAP_SET_OAEP = 0x00000401
CKM_CMS_SIG = 0x00000500
CKM_KIP_DERIVE = 0x00000510
CKM_KIP_WRAP = 0x00000511
CKM_KIP_MAC = 0x00000512
CKM_CAMELLIA_KEY_GEN = 0x00000550
CKM_CAMELLIA_ECB = 0x00000551
CKM_CAMELLIA_CBC = 0x00000552
CKM_CAMELLIA_MAC = 0x00000553
CKM_CAMELLIA_MAC_GENERAL = 0x00000554
CKM_CAMELLIA_CBC_PAD = 0x00000555
CKM_CAMELLIA_ECB_ENCRYPT_DATA = 0x00000556
CKM_CAMELLIA_CBC_ENCRYPT_DATA = 0x00000557
CKM_CAMELLIA_CTR = 0x00000558
CKM_ARIA_KEY_GEN = 0x00000560
CKM_ARIA_ECB = 0x00000561
CKM_ARIA_CBC = 0x00000562
CKM_ARIA_MAC = 0x00000563
CKM_ARIA_MAC_GENERAL = 0x00000564
CKM_ARIA_CBC_PAD = 0x00000565
CKM_ARIA_ECB_ENCRYPT_DATA = 0x00000566
CKM_ARIA_CBC_ENCRYPT_DATA = 0x00000567
CKM_SEED_KEY_GEN = 0x00000650
CKM_SEED_ECB = 0x00000651
CKM_SEED_CBC = 0x00000652
CKM_SEED_MAC = 0x00000653
CKM_SEED_MAC_GENERAL = 0x00000654
CKM_SEED_CBC_PAD = 0x00000655
CKM_SEED_ECB_ENCRYPT_DATA = 0x00000656
CKM_SEED_CBC_ENCRYPT_DATA = 0x00000657
CKM_SKIPJACK_KEY_GEN = 0x00001000
CKM_SKIPJACK_ECB64 = 0x00001001
CKM_SKIPJACK_CBC64 = 0x00001002
CKM_SKIPJACK_OFB64 = 0x00001003
CKM_SKIPJACK_CFB64 = 0x00001004
CKM_SKIPJACK_CFB32 = 0x00001005
CKM_SKIPJACK_CFB16 = 0x00001006
CKM_SKIPJACK_CFB8 = 0x00001007
CKM_SKIPJACK_WRAP = 0x00001008
CKM_SKIPJACK_PRIVATE_WRAP = 0x00001009
CKM_SKIPJACK_RELAYX = 0x0000100a
CKM_KEA_KEY_PAIR_GEN = 0x00001010
CKM_KEA_KEY_DERIVE = 0x00001011
CKM_KEA_DERIVE = 0x00001012
CKM_FORTEZZA_TIMESTAMP = 0x00001020
CKM_BATON_KEY_GEN = 0x00001030
CKM_BATON_ECB128 = 0x00001031
CKM_BATON_ECB96 = 0x00001032
CKM_BATON_CBC128 = 0x00001033
CKM_BATON_COUNTER = 0x00001034
CKM_BATON_SHUFFLE = 0x00001035
CKM_BATON_WRAP = 0x00001036
CKM_ECDSA_KEY_PAIR_GEN = 0x00001040 // Deprecated
CKM_EC_KEY_PAIR_GEN = 0x00001040
CKM_ECDSA = 0x00001041
CKM_ECDSA_SHA1 = 0x00001042
CKM_ECDSA_SHA224 = 0x00001043
CKM_ECDSA_SHA256 = 0x00001044
CKM_ECDSA_SHA384 = 0x00001045
CKM_ECDSA_SHA512 = 0x00001046
CKM_ECDH1_DERIVE = 0x00001050
CKM_ECDH1_COFACTOR_DERIVE = 0x00001051
CKM_ECMQV_DERIVE = 0x00001052
CKM_ECDH_AES_KEY_WRAP = 0x00001053
CKM_RSA_AES_KEY_WRAP = 0x00001054
CKM_JUNIPER_KEY_GEN = 0x00001060
CKM_JUNIPER_ECB128 = 0x00001061
CKM_JUNIPER_CBC128 = 0x00001062
CKM_JUNIPER_COUNTER = 0x00001063
CKM_JUNIPER_SHUFFLE = 0x00001064
CKM_JUNIPER_WRAP = 0x00001065
CKM_FASTHASH = 0x00001070
CKM_AES_KEY_GEN = 0x00001080
CKM_AES_ECB = 0x00001081
CKM_AES_CBC = 0x00001082
CKM_AES_MAC = 0x00001083
CKM_AES_MAC_GENERAL = 0x00001084
CKM_AES_CBC_PAD = 0x00001085
CKM_AES_CTR = 0x00001086
CKM_AES_GCM = 0x00001087
CKM_AES_CCM = 0x00001088
CKM_AES_CTS = 0x00001089
CKM_AES_CMAC = 0x0000108A
CKM_AES_CMAC_GENERAL = 0x0000108B
CKM_AES_XCBC_MAC = 0x0000108C
CKM_AES_XCBC_MAC_96 = 0x0000108D
CKM_AES_GMAC = 0x0000108E
CKM_BLOWFISH_KEY_GEN = 0x00001090
CKM_BLOWFISH_CBC = 0x00001091
CKM_TWOFISH_KEY_GEN = 0x00001092
CKM_TWOFISH_CBC = 0x00001093
CKM_BLOWFISH_CBC_PAD = 0x00001094
CKM_TWOFISH_CBC_PAD = 0x00001095
CKM_DES_ECB_ENCRYPT_DATA = 0x00001100
CKM_DES_CBC_ENCRYPT_DATA = 0x00001101
CKM_DES3_ECB_ENCRYPT_DATA = 0x00001102
CKM_DES3_CBC_ENCRYPT_DATA = 0x00001103
CKM_AES_ECB_ENCRYPT_DATA = 0x00001104
CKM_AES_CBC_ENCRYPT_DATA = 0x00001105
CKM_GOSTR3410_KEY_PAIR_GEN = 0x00001200
CKM_GOSTR3410 = 0x00001201
CKM_GOSTR3410_WITH_GOSTR3411 = 0x00001202
CKM_GOSTR3410_KEY_WRAP = 0x00001203
CKM_GOSTR3410_DERIVE = 0x00001204
CKM_GOSTR3411 = 0x00001210
CKM_GOSTR3411_HMAC = 0x00001211
CKM_GOST28147_KEY_GEN = 0x00001220
CKM_GOST28147_ECB = 0x00001221
CKM_GOST28147 = 0x00001222
CKM_GOST28147_MAC = 0x00001223
CKM_GOST28147_KEY_WRAP = 0x00001224
CKM_DSA_PARAMETER_GEN = 0x00002000
CKM_DH_PKCS_PARAMETER_GEN = 0x00002001
CKM_X9_42_DH_PARAMETER_GEN = 0x00002002
CKM_DSA_PROBABLISTIC_PARAMETER_GEN = 0x00002003
CKM_DSA_SHAWE_TAYLOR_PARAMETER_GEN = 0x00002004
CKM_AES_OFB = 0x00002104
CKM_AES_CFB64 = 0x00002105
CKM_AES_CFB8 = 0x00002106
CKM_AES_CFB128 = 0x00002107
CKM_AES_CFB1 = 0x00002108
CKM_AES_KEY_WRAP = 0x00002109
CKM_AES_KEY_WRAP_PAD = 0x0000210A
CKM_RSA_PKCS_TPM_1_1 = 0x00004001
CKM_RSA_PKCS_OAEP_TPM_1_1 = 0x00004002
CKM_VENDOR_DEFINED = 0x80000000
CKF_HW = 0x00000001
CKF_ENCRYPT = 0x00000100
CKF_DECRYPT = 0x00000200
CKF_DIGEST = 0x00000400
CKF_SIGN = 0x00000800
CKF_SIGN_RECOVER = 0x00001000
CKF_VERIFY = 0x00002000
CKF_VERIFY_RECOVER = 0x00004000
CKF_GENERATE = 0x00008000
CKF_GENERATE_KEY_PAIR = 0x00010000
CKF_WRAP = 0x00020000
CKF_UNWRAP = 0x00040000
CKF_DERIVE = 0x00080000
CKF_EC_F_P = 0x00100000
CKF_EC_F_2M = 0x00200000
CKF_EC_ECPARAMETERS = 0x00400000
CKF_EC_NAMEDCURVE = 0x00800000
CKF_EC_UNCOMPRESS = 0x01000000
CKF_EC_COMPRESS = 0x02000000
CKF_EXTENSION = 0x80000000
CKR_OK = 0x00000000
CKR_CANCEL = 0x00000001
CKR_HOST_MEMORY = 0x00000002
CKR_SLOT_ID_INVALID = 0x00000003
CKR_GENERAL_ERROR = 0x00000005
CKR_FUNCTION_FAILED = 0x00000006
CKR_ARGUMENTS_BAD = 0x00000007
CKR_NO_EVENT = 0x00000008
CKR_NEED_TO_CREATE_THREADS = 0x00000009
CKR_CANT_LOCK = 0x0000000A
CKR_ATTRIBUTE_READ_ONLY = 0x00000010
CKR_ATTRIBUTE_SENSITIVE = 0x00000011
CKR_ATTRIBUTE_TYPE_INVALID = 0x00000012
CKR_ATTRIBUTE_VALUE_INVALID = 0x00000013
CKR_ACTION_PROHIBITED = 0x0000001B
CKR_DATA_INVALID = 0x00000020
CKR_DATA_LEN_RANGE = 0x00000021
CKR_DEVICE_ERROR = 0x00000030
CKR_DEVICE_MEMORY = 0x00000031
CKR_DEVICE_REMOVED = 0x00000032
CKR_ENCRYPTED_DATA_INVALID = 0x00000040
CKR_ENCRYPTED_DATA_LEN_RANGE = 0x00000041
CKR_FUNCTION_CANCELED = 0x00000050
CKR_FUNCTION_NOT_PARALLEL = 0x00000051
CKR_FUNCTION_NOT_SUPPORTED = 0x00000054
CKR_KEY_HANDLE_INVALID = 0x00000060
CKR_KEY_SIZE_RANGE = 0x00000062
CKR_KEY_TYPE_INCONSISTENT = 0x00000063
CKR_KEY_NOT_NEEDED = 0x00000064
CKR_KEY_CHANGED = 0x00000065
CKR_KEY_NEEDED = 0x00000066
CKR_KEY_INDIGESTIBLE = 0x00000067
CKR_KEY_FUNCTION_NOT_PERMITTED = 0x00000068
CKR_KEY_NOT_WRAPPABLE = 0x00000069
CKR_KEY_UNEXTRACTABLE = 0x0000006A
CKR_MECHANISM_INVALID = 0x00000070
CKR_MECHANISM_PARAM_INVALID = 0x00000071
CKR_OBJECT_HANDLE_INVALID = 0x00000082
CKR_OPERATION_ACTIVE = 0x00000090
CKR_OPERATION_NOT_INITIALIZED = 0x00000091
CKR_PIN_INCORRECT = 0x000000A0
CKR_PIN_INVALID = 0x000000A1
CKR_PIN_LEN_RANGE = 0x000000A2
CKR_PIN_EXPIRED = 0x000000A3
CKR_PIN_LOCKED = 0x000000A4
CKR_SESSION_CLOSED = 0x000000B0
CKR_SESSION_COUNT = 0x000000B1
CKR_SESSION_HANDLE_INVALID = 0x000000B3
CKR_SESSION_PARALLEL_NOT_SUPPORTED = 0x000000B4
CKR_SESSION_READ_ONLY = 0x000000B5
CKR_SESSION_EXISTS = 0x000000B6
CKR_SESSION_READ_ONLY_EXISTS = 0x000000B7
CKR_SESSION_READ_WRITE_SO_EXISTS = 0x000000B8
CKR_SIGNATURE_INVALID = 0x000000C0
CKR_SIGNATURE_LEN_RANGE = 0x000000C1
CKR_TEMPLATE_INCOMPLETE = 0x000000D0
CKR_TEMPLATE_INCONSISTENT = 0x000000D1
CKR_TOKEN_NOT_PRESENT = 0x000000E0
CKR_TOKEN_NOT_RECOGNIZED = 0x000000E1
CKR_TOKEN_WRITE_PROTECTED = 0x000000E2
CKR_UNWRAPPING_KEY_HANDLE_INVALID = 0x000000F0
CKR_UNWRAPPING_KEY_SIZE_RANGE = 0x000000F1
CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT = 0x000000F2
CKR_USER_ALREADY_LOGGED_IN = 0x00000100
CKR_USER_NOT_LOGGED_IN = 0x00000101
CKR_USER_PIN_NOT_INITIALIZED = 0x00000102
CKR_USER_TYPE_INVALID = 0x00000103
CKR_USER_ANOTHER_ALREADY_LOGGED_IN = 0x00000104
CKR_USER_TOO_MANY_TYPES = 0x00000105
CKR_WRAPPED_KEY_INVALID = 0x00000110
CKR_WRAPPED_KEY_LEN_RANGE = 0x00000112
CKR_WRAPPING_KEY_HANDLE_INVALID = 0x00000113
CKR_WRAPPING_KEY_SIZE_RANGE = 0x00000114
CKR_WRAPPING_KEY_TYPE_INCONSISTENT = 0x00000115
CKR_RANDOM_SEED_NOT_SUPPORTED = 0x00000120
CKR_RANDOM_NO_RNG = 0x00000121
CKR_DOMAIN_PARAMS_INVALID = 0x00000130
CKR_CURVE_NOT_SUPPORTED = 0x00000140
CKR_BUFFER_TOO_SMALL = 0x00000150
CKR_SAVED_STATE_INVALID = 0x00000160
CKR_INFORMATION_SENSITIVE = 0x00000170
CKR_STATE_UNSAVEABLE = 0x00000180
CKR_CRYPTOKI_NOT_INITIALIZED = 0x00000190
CKR_CRYPTOKI_ALREADY_INITIALIZED = 0x00000191
CKR_MUTEX_BAD = 0x000001A0
CKR_MUTEX_NOT_LOCKED = 0x000001A1
CKR_NEW_PIN_MODE = 0x000001B0
CKR_NEXT_OTP = 0x000001B1
CKR_EXCEEDED_MAX_ITERATIONS = 0x000001B5
CKR_FIPS_SELF_TEST_FAILED = 0x000001B6
CKR_LIBRARY_LOAD_FAILED = 0x000001B7
CKR_PIN_TOO_WEAK = 0x000001B8
CKR_PUBLIC_KEY_INVALID = 0x000001B9
CKR_FUNCTION_REJECTED = 0x00000200
CKR_VENDOR_DEFINED = 0x80000000
CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001
CKF_OS_LOCKING_OK = 0x00000002
CKF_DONT_BLOCK = 1
CKG_MGF1_SHA1 = 0x00000001
CKG_MGF1_SHA256 = 0x00000002
CKG_MGF1_SHA384 = 0x00000003
CKG_MGF1_SHA512 = 0x00000004
CKG_MGF1_SHA224 = 0x00000005
CKZ_DATA_SPECIFIED = 0x00000001
CKD_NULL = 0x00000001
CKD_SHA1_KDF = 0x00000002
CKD_SHA1_KDF_ASN1 = 0x00000003
CKD_SHA1_KDF_CONCATENATE = 0x00000004
CKD_SHA224_KDF = 0x00000005
CKD_SHA256_KDF = 0x00000006
CKD_SHA384_KDF = 0x00000007
CKD_SHA512_KDF = 0x00000008
CKD_CPDIVERSIFY_KDF = 0x00000009
CKD_SHA3_224_KDF = 0x0000000A
CKD_SHA3_256_KDF = 0x0000000B
CKD_SHA3_384_KDF = 0x0000000C
CKD_SHA3_512_KDF = 0x0000000D
CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001
CKP_PKCS5_PBKD2_HMAC_GOSTR3411 = 0x00000002
CKP_PKCS5_PBKD2_HMAC_SHA224 = 0x00000003
CKP_PKCS5_PBKD2_HMAC_SHA256 = 0x00000004
CKP_PKCS5_PBKD2_HMAC_SHA384 = 0x00000005
CKP_PKCS5_PBKD2_HMAC_SHA512 = 0x00000006
CKP_PKCS5_PBKD2_HMAC_SHA512_224 = 0x00000007
CKP_PKCS5_PBKD2_HMAC_SHA512_256 = 0x00000008
CKZ_SALT_SPECIFIED = 0x00000001
CK_OTP_VALUE = 0
CK_OTP_PIN = 1
CK_OTP_CHALLENGE = 2
CK_OTP_TIME = 3
CK_OTP_COUNTER = 4
CK_OTP_FLAGS = 5
CK_OTP_OUTPUT_LENGTH = 6
CK_OTP_OUTPUT_FORMAT = 7
CKF_NEXT_OTP = 0x00000001
CKF_EXCLUDE_TIME = 0x00000002
CKF_EXCLUDE_COUNTER = 0x00000004
CKF_EXCLUDE_CHALLENGE = 0x00000008
CKF_EXCLUDE_PIN = 0x00000010
CKF_USER_FRIENDLY_OTP = 0x00000020
)

View File

@ -0,0 +1,2 @@
*~
pkcs11uri

View File

@ -0,0 +1,25 @@
dist: bionic
language: go
os:
- linux
go:
- "1.13.x"
matrix:
include:
- os: linux
addons:
apt:
packages:
- softhsm2
install:
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
script:
- make
- make check
- make test

177
vendor/github.com/stefanberger/go-pkcs11uri/LICENSE generated vendored Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
https://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

28
vendor/github.com/stefanberger/go-pkcs11uri/Makefile generated vendored Normal file
View File

@ -0,0 +1,28 @@
# Copyright IBM Corporation, 2020
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
.PHONY: check build test
all: build
FORCE:
check:
golangci-lint run
build:
go build ./...
test:
go test ./... -test.v

Some files were not shown because too many files have changed in this diff Show More