Compare commits
285 Commits
Author | SHA1 | Date |
---|---|---|
|
9d2b3b3592 | |
|
a3ebbb6878 | |
|
38c802d61e | |
|
a9cfc88ce5 | |
|
c655a2fb48 | |
|
069eda7f83 | |
|
07dd138fc6 | |
|
faeb70b097 | |
|
c27db79e24 | |
|
887a007da8 | |
|
a989bdecfd | |
|
e9f8c2beaf | |
|
b3e6a77402 | |
|
74ee191c21 | |
|
8417915c6d | |
|
3d93cca010 | |
|
b55ecf723a | |
|
40969cc321 | |
|
2b32324e1d | |
|
4373c53823 | |
|
3a154c02f9 | |
|
bc25fff254 | |
|
d105bb6bf7 | |
|
364ef28d14 | |
|
0154426cb2 | |
|
efc35b0269 | |
|
3d03977f78 | |
|
edd4687056 | |
|
e9fca7516c | |
|
8fa7c9dc16 | |
|
d7305613db | |
|
ac7a57ea32 | |
|
c7ef1f8b7f | |
|
d4c03255dc | |
|
b836bd2ef1 | |
|
dbfc28b258 | |
|
6813224799 | |
|
ca09502329 | |
|
1062e481ef | |
|
6bdf75dbf3 | |
|
30f6ae3516 | |
|
b4052ae1de | |
|
1fa20718ac | |
|
95f8189a02 | |
|
890bf09862 | |
|
3c880aa64a | |
|
177297005e | |
|
a3132057d6 | |
|
25cc887695 | |
|
15a8749937 | |
|
3c0380a766 | |
|
bf96a202a0 | |
|
ffef2eb4fd | |
|
9128ef7ff7 | |
|
e67be953a1 | |
|
e0c45aafea | |
|
d0a1b94e2a | |
|
7a29d7aa94 | |
|
ee88cdc854 | |
|
f3a90e76d3 | |
|
5f1f4a34f4 | |
|
fbe4d89819 | |
|
1035d0e3b4 | |
|
dad2e848d3 | |
|
0b658b9cde | |
|
eb558f6a96 | |
|
9432c7ae06 | |
|
201c44e74c | |
|
4f7d5ba4df | |
|
c2455293af | |
|
01328d9792 | |
|
b253f41ab6 | |
|
b0b6bfdd49 | |
|
9cc2894e17 | |
|
b16ce92233 | |
|
d84213a499 | |
|
6ff3461def | |
|
f30214a98a | |
|
32c98b3b3b | |
|
525677bec9 | |
|
f801cedf0a | |
|
20ad3ae1a8 | |
|
40c5d03159 | |
|
126144b855 | |
|
84287fd8df | |
|
cba3657f09 | |
|
c312d8211c | |
|
14e4c9cc44 | |
|
c7f057264a | |
|
76f72252a4 | |
|
dc18d79970 | |
|
0c5511a196 | |
|
d2bf83b47d | |
|
645fcf329b | |
|
ab558ed62e | |
|
7585b5de2a | |
|
c8a9108574 | |
|
4729376cf9 | |
|
600b1ee242 | |
|
04902bd097 | |
|
f4b5918a07 | |
|
6c96e3b1a6 | |
|
a3e24e9b44 | |
|
df3c9856d2 | |
|
38c931cdf4 | |
|
6f7e2df243 | |
|
73ce46a125 | |
|
527a24dc22 | |
|
4d9d7ac015 | |
|
1da673b542 | |
|
b8a8e90f31 | |
|
98a5d2cecb | |
|
7d38d26cd3 | |
|
f255ae7790 | |
|
a6dea75a04 | |
|
5b8946ccb2 | |
|
48b3e34459 | |
|
83d5a312e7 | |
|
006963f1de | |
|
92dde95766 | |
|
219bf8fbc0 | |
|
4f9d594683 | |
|
6c3a239665 | |
|
90a6a4b52f | |
|
ef3c42b607 | |
|
66d40e4be1 | |
|
868ccd54e1 | |
|
1826beae44 | |
|
e5d77f164d | |
|
b6b9f01bec | |
|
5f9bd7689d | |
|
49188000cc | |
|
5d939572d7 | |
|
bd18eb9ad5 | |
|
db73f40025 | |
|
62258bc0be | |
|
effff75960 | |
|
59fd8aea02 | |
|
fcbd20f781 | |
|
7a54e13597 | |
|
8f87c6ce74 | |
|
6908106258 | |
|
121a0c1df0 | |
|
3c01e95579 | |
|
73b87bbecf | |
|
69eddfb69f | |
|
82e8ab5389 | |
|
46586c76c7 | |
|
388845e6ae | |
|
6c41fad7e0 | |
|
d30e429b63 | |
|
f7ad44b699 | |
|
7c97147d5e | |
|
57bc074432 | |
|
3f2951a526 | |
|
3e28204a46 | |
|
4549425e2b | |
|
f638789a78 | |
|
02d9e3444a | |
|
12f2d08fe0 | |
|
e3e40aa04b | |
|
a09c05a6a7 | |
|
f22b5b1bd8 | |
|
8ff3ca06ec | |
|
c3f97e6fc7 | |
|
19454b59a0 | |
|
205ae30448 | |
|
f71fd67b8f | |
|
05358d7abf | |
|
7e330fa39b | |
|
d636d02a88 | |
|
69f95d5c94 | |
|
5d266f5f44 | |
|
698539ce00 | |
|
e9412a4cd3 | |
|
1479c20bc2 | |
|
5603551830 | |
|
168c38249d | |
|
7d2d929401 | |
|
28e8e6d5c2 | |
|
f2554a3e07 | |
|
7ecf1e816a | |
|
7c033c23e1 | |
|
35b618a201 | |
|
36339a2dbf | |
|
ad4b39e661 | |
|
6e8cc6e54b | |
|
7f75b17001 | |
|
7d8c9d0b61 | |
|
84b5a13f30 | |
|
b753ebb05c | |
|
fb795b0bc8 | |
|
c6360bf1e0 | |
|
53ddae0667 | |
|
119618fc37 | |
|
babfe774e3 | |
|
373a225c99 | |
|
d484e78a67 | |
|
1fa103e334 | |
|
864a32d06c | |
|
ecb791c663 | |
|
8766263955 | |
|
3c6153e5b8 | |
|
ce99e3cc56 | |
|
6a9a5148d6 | |
|
e8e8f45bc7 | |
|
981bd3110f | |
|
650884a263 | |
|
de0f3e6fc6 | |
|
becaeca295 | |
|
8cf2868cf7 | |
|
47f6dd1de9 | |
|
59017307a5 | |
|
1741fbfa56 | |
|
5eea3f449d | |
|
e06c1b4df3 | |
|
1460ad8949 | |
|
730f3ead3f | |
|
44e46bae70 | |
|
2d34de3b8e | |
|
c7397d3f8b | |
|
665e8ef164 | |
|
2b39e81caa | |
|
dcd2d1c677 | |
|
63d4cf6050 | |
|
38c31d44bf | |
|
1cd76bb06e | |
|
1354537f96 | |
|
7c942175df | |
|
3493006a4b | |
|
d8c0c06259 | |
|
0ec845d448 | |
|
d4f8e4a98e | |
|
b557227777 | |
|
ad694ddfe7 | |
|
01ad63d6af | |
|
ddda745454 | |
|
562492eaf0 | |
|
029f6d9bfe | |
|
4044a5cb36 | |
|
8bbfdd28f4 | |
|
d6e1431feb | |
|
629c7097e6 | |
|
76c5c9a706 | |
|
e55effe1b0 | |
|
de8cd4684e | |
|
93111de040 | |
|
39e32b3257 | |
|
60cce6ef67 | |
|
ad29c141fc | |
|
a57c5a797a | |
|
ad8b0a720f | |
|
a341bc4029 | |
|
927d9b858b | |
|
5ec7f60e03 | |
|
20a1f243b1 | |
|
ca096f12dc | |
|
c30d5e3753 | |
|
5ab4dc99d1 | |
|
961602fd2e | |
|
9554d4ab8c | |
|
1efd3bc6c4 | |
|
a4f12fd812 | |
|
55dbe1d62f | |
|
e8bf8cea21 | |
|
107dd1e329 | |
|
01bb4c0f87 | |
|
ab322b6652 | |
|
171017817d | |
|
30aebf8ec2 | |
|
6466a2a7c1 | |
|
a9af5f6ed1 | |
|
0b704b7455 | |
|
a079b57c81 | |
|
21ae80925b | |
|
80641bcf8e | |
|
4d660a7471 | |
|
c3fe777019 | |
|
5c15eba75b | |
|
53c05e2d88 | |
|
a0a5904898 | |
|
c47452afe2 | |
|
2ce4c2627d | |
|
57c5bbda28 | |
|
a95746f931 |
|
@ -0,0 +1,140 @@
|
|||
version: 2
|
||||
jobs:
|
||||
job_01:
|
||||
machine:
|
||||
image: ubuntu-2204:2022.04.1
|
||||
# not supported in the free plan
|
||||
# docker_layer_caching: true
|
||||
working_directory: ~/go/src/github.com/theupdateframework/notary
|
||||
environment:
|
||||
NOTARY_BUILDTAGS: pkcs11
|
||||
DOCKER_BUILDKIT: 1
|
||||
steps:
|
||||
- add_ssh_keys
|
||||
- checkout
|
||||
- run:
|
||||
name: "Docker Info"
|
||||
command: |
|
||||
docker version
|
||||
docker info
|
||||
docker-compose version
|
||||
- run:
|
||||
name: Check vendor modules
|
||||
command: ./buildscripts/circle-validate-vendor.sh
|
||||
- run:
|
||||
name: "Build image"
|
||||
command: docker build --progress=plain -t notary_client .
|
||||
- run:
|
||||
name: "ci"
|
||||
command: docker run --rm -e NOTARY_BUILDTAGS --env-file buildscripts/env.list --user notary notary_client bash -c "make ci && codecov"
|
||||
- run:
|
||||
name: "Teardown"
|
||||
command: docker-compose -f docker-compose.yml down -v && docker-compose -f docker-compose.rethink.yml down -v
|
||||
|
||||
job_02:
|
||||
machine:
|
||||
image: ubuntu-2204:2022.04.1
|
||||
working_directory: ~/go/src/github.com/theupdateframework/notary
|
||||
environment:
|
||||
NOTARY_BUILDTAGS: none
|
||||
DOCKER_BUILDKIT: 1
|
||||
steps:
|
||||
- add_ssh_keys
|
||||
- checkout
|
||||
- run:
|
||||
name: "Docker Info"
|
||||
command: |
|
||||
docker version
|
||||
docker info
|
||||
docker-compose version
|
||||
- run:
|
||||
name: "Build image"
|
||||
command: docker build --progress=plain -t notary_client .
|
||||
- run:
|
||||
name: "Build static binaries"
|
||||
command: docker run --rm -e NOTARY_BUILDTAGS --env-file buildscripts/env.list --user notary notary_client bash -c "make static"
|
||||
- run:
|
||||
name: "ci"
|
||||
command: docker run --rm -e NOTARY_BUILDTAGS --env-file buildscripts/env.list --user notary notary_client bash -c "make ci && codecov"
|
||||
- run:
|
||||
name: "Teardown"
|
||||
command: docker-compose -f docker-compose.yml down -v && docker-compose -f docker-compose.rethink.yml down -v
|
||||
|
||||
job_03:
|
||||
machine:
|
||||
image: ubuntu-2204:2022.04.1
|
||||
working_directory: ~/go/src/github.com/theupdateframework/notary
|
||||
environment:
|
||||
SKIPENVCHECK: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
steps:
|
||||
- add_ssh_keys
|
||||
- checkout
|
||||
- run:
|
||||
name: "Docker Info"
|
||||
command: |
|
||||
docker version
|
||||
docker info
|
||||
docker-compose version
|
||||
- run:
|
||||
name: "Build image"
|
||||
command: docker build --progress=plain -t notary_client .
|
||||
- run:
|
||||
name: "Lint"
|
||||
command: docker run --rm -e NOTARY_BUILDTAGS=pkcs11 notary_client make lint
|
||||
- run:
|
||||
name: "MySQL testdb"
|
||||
command: make TESTDB=mysql testdb
|
||||
- run:
|
||||
name: "MySQL integration"
|
||||
command: make TESTDB=mysql integration
|
||||
- run:
|
||||
name: "Cross"
|
||||
command: make cross # just trying not to exceed 4 builders
|
||||
- run:
|
||||
name: "Teardown"
|
||||
command: docker-compose -f docker-compose.yml down -v && docker-compose -f docker-compose.rethink.yml down -v
|
||||
|
||||
job_04:
|
||||
machine:
|
||||
image: ubuntu-2204:2022.04.1
|
||||
working_directory: ~/go/src/github.com/theupdateframework/notary
|
||||
environment:
|
||||
SKIPENVCHECK: 1
|
||||
DOCKER_BUILDKIT: 1
|
||||
steps:
|
||||
- add_ssh_keys
|
||||
- checkout
|
||||
- run:
|
||||
name: "Docker Info"
|
||||
command: |
|
||||
docker version
|
||||
docker info
|
||||
docker-compose version
|
||||
- run:
|
||||
name: "Build image"
|
||||
command: docker build --progress=plain -t notary_client .
|
||||
- run:
|
||||
name: "RethinkDB testdb"
|
||||
command: make TESTDB=rethink testdb
|
||||
- run:
|
||||
name: "RethinkDB integration"
|
||||
command: make TESTDB=rethink integration
|
||||
- run:
|
||||
name: "PostgreSQL testdb"
|
||||
command: make TESTDB=postgresql testdb
|
||||
- run:
|
||||
name: "PostgreSQL integration"
|
||||
command: make TESTDB=postgresql integration
|
||||
- run:
|
||||
name: "Teardown"
|
||||
command: docker-compose -f docker-compose.yml down -v && docker-compose -f docker-compose.rethink.yml down -v
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
ci:
|
||||
jobs:
|
||||
- job_01
|
||||
- job_02
|
||||
- job_03
|
||||
- job_04
|
|
@ -14,3 +14,4 @@ cross
|
|||
*.iml
|
||||
*.test
|
||||
coverage*.txt
|
||||
gosec_output.csv
|
||||
|
|
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,5 +1,20 @@
|
|||
# Changelog
|
||||
|
||||
## [v0.7.0](https://github.com/docker/notary/releases/tag/v0.7.0) 12/01/2021
|
||||
+ Switch to Go modules [#1523](https://github.com/theupdateframework/notary/pull/1523)
|
||||
+ Use golang/x/crypto for ed25519 [#1344](https://github.com/theupdateframework/notary/pull/1344)
|
||||
+ Update Go version
|
||||
+ Update dependency versions
|
||||
+ Fixes from using Gosec for source analysis
|
||||
|
||||
## [v0.6.1](https://github.com/docker/notary/releases/tag/v0.6.0) 04/10/2018
|
||||
+ Fixed bug where CLI requested admin privileges for all metadata operations, including listing targets on a repo [#1315](https://github.com/theupdateframework/notary/pull/1315)
|
||||
+ Prevented notary signer from being dumpable or being ptraced in Linux, except in debug mode [#1327](https://github.com/theupdateframework/notary/pull/1327)
|
||||
+ Bumped JWT dependency to fix potential Invalid Curve Attack on NIST curves within ECDH key management [#1334](https://github.com/theupdateframework/notary/pull/1334)
|
||||
+ If the home directory cannot be found, log a warning instead of erroring out [#1318](https://github.com/theupdateframework/notary/pull/1318)
|
||||
+ Bumped go version and various dependencies [#1323](https://github.com/theupdateframework/notary/pull/1323) [#1332](https://github.com/theupdateframework/notary/pull/1332) [#1335](https://github.com/theupdateframework/notary/pull/1335) [#1336](https://github.com/theupdateframework/notary/pull/1336)
|
||||
+ Various internal and documentation fixes [#1312](https://github.com/theupdateframework/notary/pull/1312) [#1313](https://github.com/theupdateframework/notary/pull/1313) [#1319](https://github.com/theupdateframework/notary/pull/1319) [#1320](https://github.com/theupdateframework/notary/pull/1320) [#1324](https://github.com/theupdateframework/notary/pull/1324) [#1326](https://github.com/theupdateframework/notary/pull/1326) [#1328](https://github.com/theupdateframework/notary/pull/1328) [#1329](https://github.com/theupdateframework/notary/pull/1329) [#1333](https://github.com/theupdateframework/notary/pull/1333)
|
||||
|
||||
## [v0.6.0](https://github.com/docker/notary/releases/tag/v0.6.0) 02/28/2018
|
||||
+ **The project has been moved from https://github.com/docker/notary to https://github.com/theupdateframework/notary, as it has been accepted into the CNCF. Downstream users should update their go imports.**
|
||||
+ Removed support for RSA-key exchange ciphers supported by the server and signer and require TLS >= 1.2 for the server and signer. [#1307](https://github.com/theupdateframework/notary/pull/1307)
|
||||
|
@ -19,7 +34,7 @@
|
|||
+ Custom metadata can now be provided and read on a target when using the notary client as a library (not yet exposed on the CLI). [#1146](https://github.com/theupdateframework/notary/pull/1146)
|
||||
+ `notary init` now accepts a `--root-cert` and `--root-key` flag for use with privately generated certificates and keys. [#1144](https://github.com/theupdateframework/notary/pull/1144)
|
||||
+ `notary key generate` now accepts a `--role` flag as well as a `--output` flag. This means it can generate new targets or delegation keys, and it can also output keys to a file instead of storing it in the default notary key store. [#1134](https://github.com/theupdateframework/notary/pull/1134)
|
||||
+ Newly generated keys are now stored encrypted and encoded in PKCS#8 format. *This is not forwards-compatible against notary <0.6.0*. [#1130](https://github.com/theupdateframework/notary/pull/1130) [#1201](https://github.com/theupdateframework/notary/pull/1201)
|
||||
+ Newly generated keys are now stored encrypted and encoded in PKCS#8 format. **This is not forwards-compatible against notary<0.6.0 and docker<17.12.x. Also please note that docker>=17.12.x is not forwards compatible with notary<0.6.0.**. [#1130](https://github.com/theupdateframework/notary/pull/1130) [#1201](https://github.com/theupdateframework/notary/pull/1201)
|
||||
+ Added support for wildcarded certificate IDs in the trustpinning configuration [#1126](https://github.com/theupdateframework/notary/pull/1126)
|
||||
+ Added support using the client against notary servers which are hosted as subpath under another server (e.g. https://domain.com/notary instead of https://notary.com) [#1108](https://github.com/theupdateframework/notary/pull/1108)
|
||||
+ If no changes were made to the targets file, you are no longer required to sign the target [#1104](https://github.com/theupdateframework/notary/pull/1104)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Owners (in alphabetical order)
|
||||
# Note: This is only for the notaryproject/notary repo and includes the Org level maintainers
|
||||
* @hukeping @jonnystoten @niazfk @priteshbandi @shizhMSFT @toddysm @vaninrao10 @yizha1
|
|
@ -0,0 +1,43 @@
|
|||
## CNCF Community Code of Conduct v1.0
|
||||
|
||||
### Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering
|
||||
an open and welcoming community, we pledge to respect all people who contribute
|
||||
through reporting issues, posting feature requests, updating documentation,
|
||||
submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for
|
||||
everyone, regardless of level of experience, gender, gender identity and expression,
|
||||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses,
|
||||
without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are not
|
||||
aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers
|
||||
commit themselves to fairly and consistently applying these principles to every aspect
|
||||
of managing this project. Project maintainers who do not follow or enforce the Code of
|
||||
Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a CNCF project maintainer, Sarah Novotny <sarahnovotny@google.com>, and/or Dan Kohn <dan@linuxfoundation.org>.
|
||||
|
||||
This Code of Conduct is adapted from the Contributor Covenant
|
||||
(https://contributor-covenant.org), version 1.2.0, available at
|
||||
https://contributor-covenant.org/version/1/2/0/
|
||||
|
||||
### CNCF Events Code of Conduct
|
||||
|
||||
CNCF events are governed by the Linux Foundation [Code of Conduct](https://events.linuxfoundation.org/events/cloudnativecon/attend/code-of-conduct) available on the event page. This is designed to be compatible with the above policy and also includes more details on responding to incidents.
|
19
Dockerfile
19
Dockerfile
|
@ -1,24 +1,31 @@
|
|||
FROM golang:1.9.4
|
||||
FROM golang:1.17.13
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
clang \
|
||||
libltdl-dev \
|
||||
libsqlite3-dev \
|
||||
patch \
|
||||
tar \
|
||||
xz-utils \
|
||||
python \
|
||||
python-pip \
|
||||
python3-pip \
|
||||
python-setuptools \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN useradd -ms /bin/bash notary \
|
||||
&& pip install codecov \
|
||||
&& go get github.com/golang/lint/golint github.com/fzipp/gocyclo github.com/client9/misspell/cmd/misspell github.com/gordonklaus/ineffassign github.com/HewlettPackard/gas
|
||||
&& pip install codecov
|
||||
|
||||
ENV NOTARYDIR /go/src/github.com/theupdateframework/notary
|
||||
ENV GO111MODULE=on
|
||||
|
||||
RUN go get golang.org/x/lint/golint \
|
||||
github.com/client9/misspell/cmd/misspell \
|
||||
github.com/gordonklaus/ineffassign \
|
||||
github.com/securego/gosec/cmd/gosec/... \
|
||||
github.com/fzipp/gocyclo/cmd/gocyclo
|
||||
|
||||
ENV GOFLAGS=-mod=vendor \
|
||||
NOTARYDIR=/go/src/github.com/theupdateframework/notary
|
||||
|
||||
COPY . ${NOTARYDIR}
|
||||
RUN chmod -R a+rw /go && chmod 0600 ${NOTARYDIR}/fixtures/database/*
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
# Notary Governance
|
||||
|
||||
The following document outlines Notary project governance.
|
||||
|
||||
## The Notary Project
|
||||
|
||||
The Notary project consists of several repositories known as subprojects that enable community cohorts to experiment and implement solutions across the scope of the project.
|
||||
|
||||
## Maintainers Structure
|
||||
|
||||
There are two types of maintainers in the Notary project organized hierarchically. Notary org maintainers oversee the overall project and its health. Subproject maintainers focus on a single codebase or a group of related codebases.
|
||||
|
||||
Changes in maintainership have to be announced via an [issue](https://github.com/notaryproject/notaryproject/issues/new).
|
||||
|
||||
### Maintainer Responsibility
|
||||
Notary maintainers adhere to the requirements and responsibilities set forth in the respective [Notary Org Maintainers](#notary-org-maintainers) and [Subproject Maintainers](#subproject-maintainers). They further pledge the following:
|
||||
* To act in the best interest of the project and subprojects at all times.
|
||||
* To ensure that project and subproject development and direction is a function of community needs.
|
||||
* To never take any action while hesitant that it is the right action to take.
|
||||
* To fulfill the responsibilities outlined in this document and its dependents.
|
||||
|
||||
### Notary Org Maintainers
|
||||
|
||||
The [Notary Org maintainers](MAINTAINERS) are responsible for:
|
||||
|
||||
* Maintaining the mission, vision, values, and scope of the project
|
||||
* Refining the governance and charter as needed
|
||||
* Making project level decisions
|
||||
* Resolving escalated project decisions when the subproject maintainers responsible are blocked
|
||||
* Managing the Notary brand
|
||||
* Controlling access to Notary assets such as source repositories, hosting, project calendars
|
||||
* Deciding what subprojects are part of the Notary project
|
||||
* Deciding on the creation of new subprojects
|
||||
* Overseeing the resolution and disclosure of security issues
|
||||
* Managing financial decisions related to the project
|
||||
|
||||
Changes to org maintainers use the following:
|
||||
|
||||
* Any subproject maintainer is eligible for a position as an org maintainer
|
||||
* No one company or organization can employ a simple majority of the org maintainers
|
||||
* An org maintainer may step down by submitting an [issue](https://github.com/notaryproject/notaryproject/issues/new) stating their intent and they will be moved to emeritus.
|
||||
* Org maintainers MUST remain active on the project. If they are unresponsive for > 3 months they will lose org maintainership unless a [super-majority](https://en.wikipedia.org/wiki/Supermajority#Two-thirds_vote) of the other org maintainers agrees to extend the period to be greater than 3 months
|
||||
* Any eligible person may stand as an org maintainer by opening a [PR](https://github.com/notaryproject/notaryproject/pulls).
|
||||
* When a PR is opened the project maintainers may vote
|
||||
* The voting period will be open for a minimum of three business days and will remain open until a super-majority of project maintainers has voted
|
||||
* Only current org maintainers are eligible to vote via casting a single vote each via a -1/+1 comment on the nomination issue or approving in GitHub.
|
||||
* Once a [super-majority](https://en.wikipedia.org/wiki/Supermajority#Two-thirds_vote) has been reached the maintainer elect must complete [onboarding](#onboarding-a-new-maintainer) prior to becoming an official Notary maintainer.
|
||||
* Once the maintainer onboarding has been completed a pull request is made on the repo adding the new maintainer to the [MAINTAINERS](MAINTAINERS) file.
|
||||
* When an org maintainer steps down, they become an emeritus maintainer
|
||||
|
||||
### Subproject Maintainers
|
||||
|
||||
Subproject maintainers are responsible for activities surrounding the development and release of content (eg. code, specifications, documentation) or the tasks needed to execute their subproject (e.g., community management) within the designated repository, or repositories associated with the subproject (e.g., community management). Technical decisions for code resides with the subproject maintainers unless there is a decision related to cross maintainer groups that cannot be resolved by those groups. Those cases can be escalated to the org maintainers.
|
||||
|
||||
Subprojects may be responsible for one or many repositories.
|
||||
|
||||
Subproject maintainers do not need to be software developers. No explicit role is placed upon them and they can be anyone appropriate for the work being produced. For example, if a repository is for documentation it would be appropriate for maintainers to be technical writers.
|
||||
|
||||
Changes to maintainers use the following:
|
||||
|
||||
* A subproject maintainer may step down by submitting an [issue](https://github.com/notaryproject/notaryproject/issues/new) stating their intent and they will be moved to emeritus.
|
||||
* Maintainers MUST remain active. If they are unresponsive for > 6 months they will be automatically removed unless a [super-majority](https://en.wikipedia.org/wiki/Supermajority#Two-thirds_vote) of the other subproject maintainers agrees to extend the period to be greater than 6 months
|
||||
* Potential new maintainers should be ongoing active participants in the project
|
||||
* New maintainers can be added to a subproject by a [super-majority](https://en.wikipedia.org/wiki/Supermajority#Two-thirds_vote) vote of the existing subproject maintainers
|
||||
* When a subproject has no maintainers the Notary org maintainers become responsible for it and may archive the subproject or find new maintainers
|
||||
|
||||
### Onboarding a New Maintainer
|
||||
New Notary maintainers participate in an onboarding period during which they fulfill all code review and issue management responsibilities that are required for their role. The length of this onboarding period is variable, and is considered complete once both the existing maintainers and the candidate maintainer are comfortable with the candidate's competency in the responsibilities of maintainership. This process MUST be completed prior to the candidate being named an official Notary maintainer.
|
||||
|
||||
The onboarding period is intended to ensure that the to-be-appointed maintainer is able/willing to take on the time requirements, familiar with core logic and concepts, understands the overall system architecture and interactions that comprise it, and is able to work well with both the existing maintainers and the community.
|
||||
|
||||
## Decision Making at the Notary org level
|
||||
|
||||
When maintainers need to make decisions there are two ways decisions are made, unless described elsewhere.
|
||||
|
||||
The default decision making process is [lazy-consensus](http://communitymgt.wikia.com/wiki/Lazy_consensus). This means that any decision is considered supported by the team making it as long as no one objects. Silence on any consensus decision is implicit agreement and equivalent to explicit agreement. Explicit agreement may be stated at will. In the case of security critical decisions more explicit consensus may be needed.
|
||||
|
||||
When a consensus cannot be found a maintainer can call for a [majority](https://en.wikipedia.org/wiki/Majority) vote on a decision.
|
||||
|
||||
Many of the day-to-day project maintenance can be done by a lazy consensus model. But the following items must be called to vote:
|
||||
|
||||
* Removing a maintainer for any reason other than inactivity (super majority)
|
||||
* Changing the governance rules (this document) (super majority)
|
||||
* Licensing and intellectual property changes (including new logos, wordmarks) (simple majority)
|
||||
* Adding, archiving, or removing subprojects (simple majority)
|
||||
* Utilizing Notary/CNCF money for anything CNCF deems "not cheap and easy" (simple majority)
|
||||
|
||||
New subprojects should be created (or added) with a well defined mission and goals, and significant changes should be voted on by both the subproject maintainers and the org maintainers.
|
||||
|
||||
Other decisions may, but do not need to be, called out and put up for decision via creating an [issue](https://github.com/notaryproject/notaryproject/issues/new) at any time and by anyone. By default, any decisions called to a vote will be for a _simple majority_ vote.
|
||||
|
||||
Meetings should be publically documented (Slack, CNCF calendar etc), and recorded and notes kept. Meetings should have a chair, this is a rotating role not restricted to maintainers.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This Notary project has adopted the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
|
||||
## Attributions
|
||||
|
||||
* This governance model was created using both the [SPIFFE](https://github.com/spiffe/spire/blob/main/MAINTAINERS.md) and [Helm](https://github.com/helm/community/blob/main/governance/governance.md) governance documents.
|
||||
|
||||
## DCO and Licenses
|
||||
|
||||
The following licenses and contributor agreements will be used for Notary projects:
|
||||
|
||||
* [Apache 2.0](https://opensource.org/licenses/Apache-2.0) for code
|
||||
* [Developer Certificate of Origin](https://developercertificate.org/) for new contributions
|
89
MAINTAINERS
89
MAINTAINERS
|
@ -6,20 +6,23 @@
|
|||
# It is structured to be consumable by both humans and programs.
|
||||
# To extract its contents programmatically, use any TOML-compliant parser.
|
||||
#
|
||||
# This file is compiled into the MAINTAINERS file in docker/opensource.
|
||||
#
|
||||
[Org]
|
||||
[Org."Core maintainers"]
|
||||
[Org."Org maintainers"]
|
||||
people = [
|
||||
"cyli",
|
||||
"diogomonica",
|
||||
"endophage",
|
||||
"ecordell",
|
||||
"hukeping",
|
||||
"nathanmccauley",
|
||||
"riyazdf",
|
||||
"niazfk",
|
||||
"priteshbandi",
|
||||
"shiweizhang",
|
||||
"toddymladenov",
|
||||
"vaninrao",
|
||||
"yizha"
|
||||
]
|
||||
|
||||
[Org."Notary maintainers"]
|
||||
people = [
|
||||
"hukeping",
|
||||
"justincormack",
|
||||
"jonnystoten"
|
||||
]
|
||||
[people]
|
||||
|
||||
# A reference list of all people associated with the project.
|
||||
|
@ -28,37 +31,47 @@
|
|||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
|
||||
[people.cyli]
|
||||
Name = "Ying Li"
|
||||
Email = "ying.li@docker.com"
|
||||
GitHub = "cyli"
|
||||
|
||||
[people.diogomonica]
|
||||
Name = "Diogo Monica"
|
||||
Email = "diogo@docker.com"
|
||||
GitHub = "diogomonica"
|
||||
|
||||
[people.endophage]
|
||||
Name = "David Lawrence"
|
||||
Email = "david.lawrence@docker.com"
|
||||
GitHub = "endophage"
|
||||
|
||||
[people.ecordell]
|
||||
Name = "Evan Cordell"
|
||||
Email = "evan.cordell@coreos.com"
|
||||
GitHub = "ecordell"
|
||||
|
||||
[people.hukeping]
|
||||
Name = "Hu Keping"
|
||||
Email = "hukeping@huawei.com"
|
||||
GitHub = "hukeping"
|
||||
|
||||
[people.nathanmccauley]
|
||||
Name = "Nathan McCauley"
|
||||
Email = "nathan.mccauley@docker.com"
|
||||
GitHub = "nathanmccauley"
|
||||
[people.mnm678]
|
||||
Name = "Marina Moore"
|
||||
Email = "mm9693@nyu.edu"
|
||||
GitHub = "mnm678"
|
||||
|
||||
[people.riyazdf]
|
||||
Name = "Riyaz Faizullabhoy"
|
||||
Email = "riyaz@docker.com"
|
||||
GitHub = "riyazdf"
|
||||
[people.niazfk]
|
||||
Name = "Niaz Khan"
|
||||
Email = "niazfk@amazon.com"
|
||||
GitHub = "niazfk"
|
||||
|
||||
[people.jonnystoten]
|
||||
Name = "Jonny Stoten"
|
||||
Email = "jonny.stoten@docker.com"
|
||||
GitHub = "jonnystoten"
|
||||
|
||||
[people.priteshbandi]
|
||||
Name = "Pritesh Bandi"
|
||||
Email = "priteshbandi@gmail.com"
|
||||
GitHub = "priteshbandi"
|
||||
|
||||
[people.shiweizhang]
|
||||
Name = "Shiwei Zhang"
|
||||
Email = "shizh@microsoft.com"
|
||||
GitHub = "shizhMSFT"
|
||||
|
||||
[people.toddymladenov]
|
||||
Name = "Toddy Mladenov"
|
||||
Email = "toddysm@gmail.com"
|
||||
GitHub = "toddysm"
|
||||
|
||||
[people.vaninrao]
|
||||
Name = "Vani Rao"
|
||||
Email = "vaninrao@amazon.com"
|
||||
GitHub = "vaninrao10"
|
||||
|
||||
[people.vaninrao]
|
||||
Name = "Vani Rao"
|
||||
Email = "vaninrao@amazon.com"
|
||||
GitHub = "vaninrao10"
|
||||
|
|
|
@ -9,14 +9,62 @@
|
|||
[Org]
|
||||
[Org."Notary Alumni"]
|
||||
people = [
|
||||
"cyli",
|
||||
"diogomonica",
|
||||
"dmcgowan",
|
||||
"endophage",
|
||||
"ecordell",
|
||||
"justincormack"
|
||||
"nathanmccauley",
|
||||
"riyazdf",
|
||||
"stevelasker"
|
||||
]
|
||||
|
||||
[people]
|
||||
|
||||
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
|
||||
|
||||
[people.cyli]
|
||||
Name = "Ying Li"
|
||||
Email = "ying.li@docker.com"
|
||||
GitHub = "cyli"
|
||||
|
||||
[people.diogomonica]
|
||||
Name = "Diogo Monica"
|
||||
Email = "diogo@docker.com"
|
||||
GitHub = "diogomonica"
|
||||
|
||||
[people.dmcgowan]
|
||||
Name = "Derek McGowan"
|
||||
Email = "derek@docker.com"
|
||||
GitHub = "dmcgowan"
|
||||
|
||||
[people.endophage]
|
||||
Name = "David Lawrence"
|
||||
Email = "david.lawrence@docker.com"
|
||||
GitHub = "endophage"
|
||||
|
||||
[people.ecordell]
|
||||
Name = "Evan Cordell"
|
||||
Email = "evan.cordell@coreos.com"
|
||||
GitHub = "ecordell"
|
||||
|
||||
[people.justincormack]
|
||||
Name = "Justin Cormack"
|
||||
Email = "justin.cormack@docker.com"
|
||||
GitHub = "justincormack"
|
||||
|
||||
[people.nathanmccauley]
|
||||
Name = "Nathan McCauley"
|
||||
Email = "nathan.mccauley@docker.com"
|
||||
GitHub = "nathanmccauley"
|
||||
|
||||
[people.riyazdf]
|
||||
Name = "Riyaz Faizullabhoy"
|
||||
Email = "riyazdf@berkeley.edu"
|
||||
GitHub = "riyazdf"
|
||||
|
||||
[people.stevelasker]
|
||||
Name = "Steve Lasker"
|
||||
Email = "Steve.Lasker@microsoft.com"
|
||||
GitHub = "stevelasker"
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
# Maintainers Rules
|
||||
|
||||
This document lays out some basic rules and guidelines all maintainers are expected to follow.
|
||||
Changes to the [Acceptance Criteria](#hard-acceptance-criteria-for-merging-a-pr) for merging PRs require a ceiling(two-thirds) supermajority from the maintainers.
|
||||
Changes to the [Repo Guidelines](#repo-guidelines) require a simple majority.
|
||||
|
||||
## Hard Acceptance Criteria for merging a PR:
|
||||
|
||||
- 2 LGTMs are required when merging a PR
|
||||
- If there is obviously still discussion going on in the PR, even with 2 LGTMs, let the discussion resolve before merging. If you’re not sure, reach out to the maintainers involved in the discussion.
|
||||
- All checks must be green
|
||||
- There are limited mitigating circumstances for this, like if the docs builds are just broken and that’s the only test failing.
|
||||
- Adding or removing a check requires simple majority approval from the maintainers.
|
||||
|
||||
## Repo Guidelines:
|
||||
|
||||
- Consistency is vital to keep complexity low and understandable.
|
||||
- Automate as much as possible (we don’t have guidelines about coding style for example because we’ve automated fmt, vet, lint, etc…).
|
||||
- Try to keep PRs small and focussed (this is not always possible, i.e. builder refactor, storage refactor, etc… but a good target).
|
||||
|
||||
## Process for becoming a maintainer:
|
||||
|
||||
- Invitation is proposed by an existing maintainer.
|
||||
- Ceiling(two-thirds) supermajority approval from existing maintainers (including vote of proposing maintainer) required to accept proposal.
|
||||
- Newly approved maintainer submits PR adding themselves to the MAINTAINERS file.
|
||||
- Existing maintainers publicly mark their approval on the PR.
|
||||
- Existing maintainer updates repository permissions to grant write access to new maintainer.
|
||||
- New maintainer merges their PR.
|
||||
|
||||
## Removing maintainers
|
||||
|
||||
It is preferrable that a maintainer gracefully removes themselves from the MAINTAINERS file if they are
|
||||
aware they will no longer have the time or motivation to contribute to the project. Maintainers that
|
||||
have been inactive in the repo for a period of at least one year should be contacted to ask if they
|
||||
wish to be removed.
|
||||
|
||||
In the case that an inactive maintainer is unresponsive for any reason, a ceiling(two-thirds) supermajority
|
||||
vote of the existing maintainers can be used to approve their removal from the MAINTAINERS file, and revoke
|
||||
their merge permissions on the repository.
|
91
Makefile
91
Makefile
|
@ -1,6 +1,8 @@
|
|||
# Set an output prefix, which is the local directory if not specified
|
||||
PREFIX?=$(shell pwd)
|
||||
|
||||
GOFLAGS := -mod=vendor
|
||||
|
||||
# Populate version variables
|
||||
# Add to compile time flags
|
||||
NOTARY_PKG := github.com/theupdateframework/notary
|
||||
|
@ -17,14 +19,6 @@ GOOSES = darwin linux windows
|
|||
NOTARY_BUILDTAGS ?= pkcs11
|
||||
NOTARYDIR := /go/src/github.com/theupdateframework/notary
|
||||
|
||||
GO_VERSION := $(shell go version | grep "1\.[7-9]\(\.[0-9]+\)*\|devel")
|
||||
# check to make sure we have the right version. development versions of Go are
|
||||
# not officially supported, but allowed for building
|
||||
|
||||
ifeq ($(strip $(GO_VERSION))$(SKIPENVCHECK),)
|
||||
$(error Bad Go version - please install Go >= 1.7)
|
||||
endif
|
||||
|
||||
# check to be sure pkcs11 lib is always imported with a build tag
|
||||
GO_LIST_PKCS11 := $(shell go list -tags "${NOTARY_BUILDTAGS}" -e -f '{{join .Deps "\n"}}' ./... | grep -v /vendor/ | xargs go list -e -f '{{if not .Standard}}{{.ImportPath}}{{end}}' | grep -q pkcs11)
|
||||
ifeq ($(GO_LIST_PKCS11),)
|
||||
|
@ -45,10 +39,7 @@ PKGS ?= $(shell go list -tags "${NOTARY_BUILDTAGS}" ./... | grep -v /vendor/ | t
|
|||
.DELETE_ON_ERROR: cover
|
||||
.DEFAULT: default
|
||||
|
||||
all: AUTHORS clean lint build test binaries
|
||||
|
||||
AUTHORS: .git/HEAD
|
||||
git log --format='%aN <%aE>' | sort -fu > $@
|
||||
all: clean lint build test binaries
|
||||
|
||||
# This only needs to be generated by hand when cutting full releases.
|
||||
version/version.go:
|
||||
|
@ -93,32 +84,43 @@ ${PREFIX}/bin/static/notary:
|
|||
@go build -tags "${NOTARY_BUILDTAGS} netgo" -o $@ ${GO_LDFLAGS_STATIC} ./cmd/notary
|
||||
endif
|
||||
|
||||
|
||||
# run all lint functionality - excludes Godep directory, vendoring, binaries, python tests, and git files
|
||||
lint:
|
||||
@echo "+ $@: golint, go vet, go fmt, gocycle, misspell, ineffassign"
|
||||
# golint
|
||||
@test -z "$(shell find . -type f -name "*.go" -not -path "./vendor/*" -not -name "*.pb.*" -exec golint {} \; | tee /dev/stderr)"
|
||||
# gofmt
|
||||
@test -z "$$(gofmt -s -l .| grep -v .pb. | grep -v vendor/ | tee /dev/stderr)"
|
||||
# govet
|
||||
ifeq ($(shell uname -s), Darwin)
|
||||
@test -z "$(shell find . -iname *test*.go | grep -v _test.go | grep -v vendor | xargs echo "This file should end with '_test':" | tee /dev/stderr)"
|
||||
else
|
||||
@test -z "$(shell find . -iname *test*.go | grep -v _test.go | grep -v vendor | xargs -r echo "This file should end with '_test':" | tee /dev/stderr)"
|
||||
ifeq (, $(shell which staticcheck))
|
||||
STATICCHECK_BIN := $(GOBIN)/staticcheck
|
||||
$(STATICCHECK_BIN):
|
||||
@echo "+ $@"
|
||||
GOFLAGS="-mod=mod" go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
endif
|
||||
@test -z "$$(go tool vet -printf=false . 2>&1 | grep -v vendor/ | tee /dev/stderr)"
|
||||
# gocyclo - we require cyclomatic complexity to be < 16
|
||||
@test -z "$(shell find . -type f -name "*.go" -not -path "./vendor/*" -not -name "*.pb.*" -exec gocyclo -over 15 {} \; | tee /dev/stderr)"
|
||||
# misspell - requires that the following be run first:
|
||||
# go get -u github.com/client9/misspell/cmd/misspell
|
||||
@test -z "$$(find . -type f | grep -v vendor/ | grep -v bin/ | grep -v misc/ | grep -v .git/ | grep -v \.pdf | xargs misspell | tee /dev/stderr)"
|
||||
# ineffassign - requires that the following be run first:
|
||||
# go get -u github.com/gordonklaus/ineffassign
|
||||
@test -z "$(shell find . -type f -name "*.go" -not -path "./vendor/*" -not -name "*.pb.*" -exec ineffassign {} \; | tee /dev/stderr)"
|
||||
# gas - requires that the following be run first:
|
||||
# go get -u github.com/HewlettPackard/gas
|
||||
# @gas -skip=vendor -skip=*/*_test.go -skip=*/*/*_test.go -fmt=csv -out=gas_output.csv ./... && test -z "$$(cat gas_output.csv | tee /dev/stderr)"
|
||||
|
||||
# spin up a docker instance and run staticcheck inside it
|
||||
.PHONY: staticcheck-docker
|
||||
staticcheck-docker: $(STATICCHECK_BIN)
|
||||
@$(dockerbuild)
|
||||
ifeq ($(RUN_LOCAL),1)
|
||||
staticcheck -checks=all,-ST1000 ./...
|
||||
endif
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck: $(STATICCHECK_BIN)
|
||||
staticcheck -checks=all,-ST1000 ./...
|
||||
|
||||
ifneq ($(RUN_LOCAL),1)
|
||||
dockerbuild = @DOCKER_BUILDKIT=1 docker build \
|
||||
-f build.Dockerfile \
|
||||
--build-arg target=$@ \
|
||||
--target=builder \
|
||||
.
|
||||
dockertestbuild = @DOCKER_BUILDKIT=1 docker build \
|
||||
-f build.Dockerfile \
|
||||
--build-arg target=$@ \
|
||||
--target=test-builder \
|
||||
.
|
||||
endif
|
||||
|
||||
# run lint locally
|
||||
lint: staticcheck
|
||||
|
||||
# run lint target in docker
|
||||
lint-docker: staticcheck-docker
|
||||
|
||||
build:
|
||||
@echo "+ $@"
|
||||
|
@ -133,6 +135,17 @@ test:
|
|||
@echo
|
||||
go test -tags "${NOTARY_BUILDTAGS}" $(TESTOPTS) $(PKGS)
|
||||
|
||||
# run test target in docker
|
||||
test-docker: TESTOPTS =
|
||||
test-docker:
|
||||
@$(dockertestbuild)
|
||||
ifeq ($(RUN_LOCAL),1)
|
||||
@echo Note: when testing with a yubikey plugged in, make sure to include 'TESTOPTS="-p 1"'
|
||||
@echo "+ $@ $(TESTOPTS)"
|
||||
@echo
|
||||
go test -tags "${NOTARY_BUILDTAGS}" $(TESTOPTS) $(PKGS)
|
||||
endif
|
||||
|
||||
integration: TESTDB = mysql
|
||||
integration: clean
|
||||
buildscripts/integrationtest.sh $(TESTDB)
|
||||
|
@ -142,7 +155,7 @@ testdb:
|
|||
buildscripts/dbtests.sh $(TESTDB)
|
||||
|
||||
protos:
|
||||
@protoc --go_out=plugins=grpc:. proto/*.proto
|
||||
@protoc --go_out=. --go-grpc_out=. proto/*.proto
|
||||
|
||||
# This allows coverage for a package to come from tests in different package.
|
||||
# Requires that the following:
|
||||
|
@ -151,7 +164,7 @@ protos:
|
|||
# be run first
|
||||
gen-cover:
|
||||
gen-cover:
|
||||
@python -u buildscripts/covertest.py --tags "$(NOTARY_BUILDTAGS)" --pkgs="$(PKGS)" --testopts="${TESTOPTS}" --debug
|
||||
@python -u buildscripts/covertest.py --tags "$(NOTARY_BUILDTAGS)" --pkgs="$(PKGS)" --testopts="${TESTOPTS}"
|
||||
|
||||
# Generates the cover binaries and runs them all in serial, so this can be used
|
||||
# run all tests with a yubikey without any problems
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.6.0
|
||||
0.7.0
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# These are the current projects under the overall Notary project umbrella
|
||||
|
||||
## Notary
|
||||
|
||||
Notary is the original project. It is an implementation of TUF that runs next to a container
|
||||
registry and adds the ability to sign and verify content in the registry. By default it makes
|
||||
some different security choices, such as using TOFU by default. As it runs next to a registry
|
||||
it is not a standard part of the registry protocol and requires independent storage and for
|
||||
clients to have different code to handle signed content.
|
||||
|
||||
## Notation
|
||||
|
||||
Notation is a project to add signatures as standard items in the registry ecosystem, and to
|
||||
build a set of simple tooling for signing and verifying these signatures. This should be
|
||||
viewed as similar in security to checking git commit signatures, although the signatures are
|
||||
generic and can be used for additional purposes.
|
||||
|
||||
## TUF
|
||||
|
||||
TUF is a project to implement the full TUF specification in a registry native way. This may
|
||||
require upstream TUF spec changes or extensions, as there are some differences between the
|
||||
registry model and common usage to other TUF use cases. This project will use existing
|
||||
registry extensions where available but may need its own document types in addition.
|
88
README.md
88
README.md
|
@ -1,44 +1,42 @@
|
|||
<img src="docs/images/notary-blk.svg" alt="Notary" width="400px"/>
|
||||
|
||||
[](https://godoc.org/github.com/theupdateframework/notary)
|
||||
[](https://circleci.com/gh/theupdateframework/notary/tree/master) [](https://codecov.io/github/theupdateframework/notary) [](https://goreportcard.com/report/github.com/theupdateframework/notary)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Ftheupdateframework%2Fnotary?ref=badge_shield)
|
||||
|
||||
# Notice
|
||||
|
||||
The Notary project has officially been accepted in to the Cloud Native Computing Foundation (CNCF).
|
||||
It has moved to https://github.com/theupdateframework/notary. Any downstream consumers should update
|
||||
their Go imports to use this new location, which will be the canonical location going forward.
|
||||
|
||||
We have moved the repo in GitHub, which will allow existing importers to continue using the old
|
||||
location via GitHub's redirect.
|
||||
This repository provides an implementation of
|
||||
*[The Update Framework specification](https://github.com/theupdateframework/specification)*
|
||||
and all references to `notary` in this repository refer to the implementation of the client
|
||||
and server aligning with the [TUF](https://github.com/theupdateframework/specification) specification.
|
||||
The most prominent use of this implementation is in Docker Content Trust (DCT).
|
||||
The first release [v0.1](https://github.com/notaryproject/notary/releases/tag/v0.1) was released in November, 2015.
|
||||
|
||||
# Overview
|
||||
|
||||
The Notary project comprises a [server](cmd/notary-server) and a [client](cmd/notary) for running and interacting
|
||||
This repository comprises of a [server](cmd/notary-server) and a [client](cmd/notary) for running and interacting
|
||||
with trusted collections. See the [service architecture](docs/service_architecture.md) documentation
|
||||
for more information.
|
||||
|
||||
Notary aims to make the internet more secure by making it easy for people to
|
||||
The aim is to make the internet more secure by making it easy for people to
|
||||
publish and verify content. We often rely on TLS to secure our communications
|
||||
with a web server which is inherently flawed, as any compromise of the server
|
||||
with a web server, which is inherently flawed, as any compromise of the server
|
||||
enables malicious content to be substituted for the legitimate content.
|
||||
|
||||
With Notary, publishers can sign their content offline using keys kept highly
|
||||
Publishers can sign their content offline using keys kept highly
|
||||
secure. Once the publisher is ready to make the content available, they can
|
||||
push their signed trusted collection to a Notary Server.
|
||||
push their signed trusted collection to the `notary` server.
|
||||
|
||||
Consumers, having acquired the publisher's public key through a secure channel,
|
||||
can then communicate with any notary server or (insecure) mirror, relying
|
||||
can then communicate with any `notary` server or (insecure) mirror, relying
|
||||
only on the publisher's key to determine the validity and integrity of the
|
||||
received content.
|
||||
|
||||
## Goals
|
||||
|
||||
Notary is based on [The Update Framework](https://www.theupdateframework.com/), a secure general design for the problem of software distribution and updates. By using TUF, notary achieves a number of key advantages:
|
||||
The `notary` client and server is based on [The Update Framework](https://www.theupdateframework.com/), a secure general design for the problem of software distribution and updates. By using TUF, the `notary` client and server achieves a number of key advantages:
|
||||
|
||||
* **Survivable Key Compromise**: Content publishers must manage keys in order to sign their content. Signing keys may be compromised or lost so systems must be designed in order to be flexible and recoverable in the case of key compromise. TUF's notion of key roles is utilized to separate responsibilities across a hierarchy of keys such that loss of any particular key (except the root role) by itself is not fatal to the security of the system.
|
||||
* **Freshness Guarantees**: Replay attacks are a common problem in designing secure systems, where previously valid payloads are replayed to trick another system. The same problem exists in the software update systems, where old signed can be presented as the most recent. notary makes use of timestamping on publishing so that consumers can know that they are receiving the most up to date content. This is particularly important when dealing with software update where old vulnerable versions could be used to attack users.
|
||||
* **Freshness Guarantees**: Replay attacks are a common problem in designing secure systems, where previously valid payloads are replayed to trick another system. The same problem exists in the software update systems, where old signed can be presented as the most recent. Notary makes use of timestamping on publishing so that consumers can know that they are receiving the most up to date content. This is particularly important when dealing with software update where old vulnerable versions could be used to attack users.
|
||||
* **Configurable Trust Thresholds**: Oftentimes there are a large number of publishers that are allowed to publish a particular piece of content. For example, open source projects where there are a number of core maintainers. Trust thresholds can be used so that content consumers require a configurable number of signatures on a piece of content in order to trust it. Using thresholds increases security so that loss of individual signing keys doesn't allow publishing of malicious content.
|
||||
* **Signing Delegation**: To allow for flexible publishing of trusted collections, a content publisher can delegate part of their collection to another signer. This delegation is represented as signed metadata so that a consumer of the content can verify both the content and the delegation.
|
||||
* **Use of Existing Distribution**: Notary's trust guarantees are not tied at all to particular distribution channels from which content is delivered. Therefore, trust can be added to any existing content delivery mechanism.
|
||||
|
@ -46,28 +44,33 @@ Notary is based on [The Update Framework](https://www.theupdateframework.com/),
|
|||
|
||||
## Security
|
||||
|
||||
See Notary's [service architecture docs](docs/service_architecture.md#threat-model) for more information about our threat model, which details the varying survivability and severities for key compromise as well as mitigations.
|
||||
|
||||
Notary's last security audit was on July 31, 2015 by NCC ([results](docs/resources/ncc_docker_notary_audit_2015_07_31.pdf)).
|
||||
|
||||
Any security vulnerabilities can be reported to security@docker.com.
|
||||
|
||||
# Getting started with the Notary CLI
|
||||
See [service architecture docs](docs/service_architecture.md#threat-model) for more information about our threat model, which details the varying survivability and severities for key compromise as well as mitigations.
|
||||
|
||||
Get the Notary Client CLI binary from [the official releases page](https://github.com/theupdateframework/notary/releases) or you can [build one yourself](#building-notary).
|
||||
The version of Notary server and signer should be greater than or equal to Notary CLI's version to ensure feature compatibility (ex: CLI version 0.2, server/signer version >= 0.2), and all official releases are associated with GitHub tags.
|
||||
### Security Audits
|
||||
|
||||
To use the Notary CLI with Docker hub images, have a look at Notary's
|
||||
Below are the two public security audits:
|
||||
|
||||
* [August 7, 2018 by Cure53](docs/resources/cure53_tuf_notary_audit_2018_08_07.pdf) covering TUF and the `notary` client and server.
|
||||
* [July 31, 2015 by NCC](docs/resources/ncc_docker_notary_audit_2015_07_31.pdf) covering `notary` client and server.
|
||||
|
||||
# Getting started with the notary CLI
|
||||
|
||||
Get the `notary` client CLI binary from [the official releases page](https://github.com/theupdateframework/notary/releases) or you can [build one yourself](#building-notary).
|
||||
The version of the `notary` server and signer should be greater than or equal to notary CLI's version to ensure feature compatibility (ex: CLI version 0.2, server/signer version >= 0.2), and all official releases are associated with GitHub tags.
|
||||
|
||||
To use the notary CLI with Docker hub images, have a look at notary's
|
||||
[getting started docs](docs/getting_started.md).
|
||||
|
||||
For more advanced usage, see the
|
||||
[advanced usage docs](docs/advanced_usage.md).
|
||||
|
||||
To use the CLI against a local Notary server rather than against Docker Hub:
|
||||
To use the CLI against a local `notary` server rather than against Docker Hub:
|
||||
|
||||
1. Ensure that you have [docker and docker-compose](http://docs.docker.com/compose/install/) installed.
|
||||
1. Ensure that you have [docker and docker-compose](https://docs.docker.com/compose/install/) installed.
|
||||
1. `git clone https://github.com/theupdateframework/notary.git` and from the cloned repository path,
|
||||
start up a local Notary server and signer and copy the config file and testing certs to your
|
||||
start up a local `notary` server and signer and copy the config file and testing certs to your
|
||||
local notary config directory:
|
||||
|
||||
```sh
|
||||
|
@ -88,34 +91,43 @@ URL is specified already in the configuration, file you copied.
|
|||
You can also leave off the `-d ~/.docker/trust` argument if you do not care
|
||||
to use `notary` with Docker images.
|
||||
|
||||
## Upgrading dependencies
|
||||
|
||||
## Building Notary
|
||||
To prevent mistakes in vendoring the go modules a buildscript has been added to properly vendor the modules using the correct version of Go to mitigate differences in CI and development environment.
|
||||
|
||||
Note that Notary's [latest stable release](https://github.com/theupdateframework/notary/releases) is at the head of the
|
||||
Following procedure should be executed to upgrade a dependency. Preferably keep dependency upgrades in a separate commit from your code changes.
|
||||
|
||||
```bash
|
||||
go get -u github.com/spf13/viper
|
||||
buildscripts/circle-validate-vendor.sh
|
||||
git add .
|
||||
git commit -m "Upgraded github.com/spf13/viper"
|
||||
```
|
||||
|
||||
The `buildscripts/circle-validate-vendor.sh` runs `go mod tidy` and `go mod vendor` using the given version of Go to prevent differences if you are for example running on a different version of Go.
|
||||
|
||||
## Building notary
|
||||
|
||||
Note that the [latest stable release](https://github.com/theupdateframework/notary/releases) is at the head of the
|
||||
[releases branch](https://github.com/theupdateframework/notary/tree/releases). The master branch is the development
|
||||
branch and contains features for the next release.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- Go >= 1.7.1
|
||||
- Fedora: `dnf install golang`
|
||||
- libtool development headers installed
|
||||
- Ubuntu: `apt-get install libltdl-dev`
|
||||
- CentOS/RedHat: `yum install libtool-ltdl-devel`
|
||||
- Fedora: `dnf install libtool-ltdl-devel`
|
||||
- Mac OS ([Homebrew](http://brew.sh/)): `brew install libtool`
|
||||
* Go >= 1.12
|
||||
|
||||
Set [```GOPATH```](https://golang.org/doc/code.html#GOPATH). Then, run:
|
||||
|
||||
```bash
|
||||
$ export GO111MODULE=on
|
||||
$ go get github.com/theupdateframework/notary
|
||||
# build with pcks11 support by default to support yubikey
|
||||
# build with pkcs11 support by default to support yubikey
|
||||
$ go install -tags pkcs11 github.com/theupdateframework/notary/cmd/notary
|
||||
$ notary
|
||||
```
|
||||
|
||||
To build the server and signer, run `docker-compose build`.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Ftheupdateframework%2Fnotary?ref=badge_large)
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
# Roadmap
|
||||
|
||||
The Trust project consists of a number of moving parts of which Notary Server is one. Notary Server is the front line metadata service
|
||||
that clients interact with. It manages TUF metadata and interacts with a pluggable signing service to issue new TUF timestamp
|
||||
files.
|
||||
|
||||
The Notary-signer is provided as our reference implementation of a signing service. It supports HSMs along with Ed25519 software signing.
|
|
@ -0,0 +1,38 @@
|
|||
FROM golang:1.17.13-alpine3.16 as builder-base
|
||||
RUN apk add make bash git openssh build-base curl
|
||||
|
||||
#
|
||||
# STAGE - Build stage, calls make with given target argument (defaults to all make target)
|
||||
#
|
||||
FROM builder-base as builder
|
||||
ARG target=all
|
||||
ENV RUN_LOCAL=1
|
||||
RUN mkdir -p /go/src
|
||||
ADD . /go/src/
|
||||
WORKDIR /go/src
|
||||
RUN make $target
|
||||
|
||||
#
|
||||
# STAGE - Test Build stage, calls make with given target argument (defaults to all make target). Valid for testing purposes only as tests require a specific (non-root) user access for directories read/write access.
|
||||
#
|
||||
FROM builder-base as test-builder
|
||||
ARG target=all
|
||||
ENV GROUP=test-group
|
||||
ENV USER=test-user
|
||||
ENV UID=12345
|
||||
ENV GID=23456
|
||||
ENV RUN_LOCAL=1
|
||||
RUN addgroup -S $GROUP
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--home "$(pwd)" \
|
||||
--ingroup "$GROUP" \
|
||||
--no-create-home \
|
||||
--uid "$UID" \
|
||||
"$USER"
|
||||
USER $USER
|
||||
RUN mkdir -p /go/src
|
||||
ADD . /go/src/
|
||||
WORKDIR /go/src
|
||||
RUN make $target
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
go_version=1.17.13
|
||||
|
||||
docker run --rm --env GO111MODULE=on -w /notary --volume ${PWD}:/notary \
|
||||
golang:${go_version}-alpine \
|
||||
sh -c "apk update && apk add bash git && git config --global safe.directory /notary && buildscripts/validate-vendor.sh"
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
case $CIRCLE_NODE_INDEX in
|
||||
0) docker run --rm -e NOTARY_BUILDTAGS=pkcs11 --env-file buildscripts/env.list --user notary notary_client bash -c "make ci && codecov"
|
||||
;;
|
||||
1) docker run --rm -e NOTARY_BUILDTAGS=none --env-file buildscripts/env.list --user notary notary_client bash -c "make ci && codecov"
|
||||
;;
|
||||
2) SKIPENVCHECK=1 make TESTDB=mysql testdb
|
||||
SKIPENVCHECK=1 make TESTDB=mysql integration
|
||||
SKIPENVCHECK=1 make cross # just trying not to exceed 4 builders
|
||||
docker run --rm -e NOTARY_BUILDTAGS=pkcs11 notary_client make lint
|
||||
;;
|
||||
3) SKIPENVCHECK=1 make TESTDB=rethink testdb
|
||||
SKIPENVCHECK=1 make TESTDB=rethink integration
|
||||
SKIPENVCHECK=1 make TESTDB=postgresql testdb
|
||||
SKIPENVCHECK=1 make TESTDB=postgresql integration
|
||||
;;
|
||||
esac
|
|
@ -105,7 +105,7 @@ class CoverageRunner(object):
|
|||
|
||||
def run(self, pkgs=(), testopts="", covermode="atomic", debug=False):
|
||||
"""
|
||||
Run go test with coverage over the the given packages, with the following given options
|
||||
Run go test with coverage over the given packages, with the following given options
|
||||
"""
|
||||
pkgs = pkgs or self.test_imports.keys()
|
||||
pkgs.sort()
|
||||
|
|
|
@ -5,21 +5,21 @@ db="$1"
|
|||
case ${db} in
|
||||
mysql*)
|
||||
db="mysql"
|
||||
dbContainerOpts="--name mysql_tests mysql mysqld --innodb_file_per_table"
|
||||
DBURL="server@tcp(mysql_tests:3306)/notaryserver?parseTime=True"
|
||||
dbContainerOpts="mysql mysqld --innodb_file_per_table"
|
||||
DBURL="server@tcp(mysql:3306)/notaryserver?parseTime=True"
|
||||
;;
|
||||
rethink*)
|
||||
db="rethink"
|
||||
dbContainerOpts="--name rethinkdb_tests rdb-01 --bind all --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem"
|
||||
DBURL="rethinkdb_tests"
|
||||
dbContainerOpts="rdb-01 --bind all --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem"
|
||||
DBURL="rdb-01.rdb"
|
||||
;;
|
||||
postgresql*)
|
||||
db="postgresql"
|
||||
dbContainerOpts="--name postgresql_tests postgresql -l"
|
||||
DBURL="postgres://server@postgresql_tests:5432/notaryserver?sslmode=verify-ca&sslrootcert=/go/src/github.com/theupdateframework/notary/fixtures/database/ca.pem&sslcert=/go/src/github.com/theupdateframework/notary/fixtures/database/notary-server.pem&sslkey=/go/src/github.com/theupdateframework/notary/fixtures/database/notary-server-key.pem"
|
||||
dbContainerOpts="postgresql -l"
|
||||
DBURL="postgres://server@postgresql:5432/notaryserver?sslmode=verify-ca&sslrootcert=/go/src/github.com/theupdateframework/notary/fixtures/database/ca.pem&sslcert=/go/src/github.com/theupdateframework/notary/fixtures/database/notary-server.pem&sslkey=/go/src/github.com/theupdateframework/notary/fixtures/database/notary-server-key.pem"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 (mysql|rethink)"
|
||||
echo "Usage: $0 (mysql|rethink|postgresql)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -29,10 +29,10 @@ project=dbtests
|
|||
|
||||
function cleanup {
|
||||
rm -f bin/notary
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" kill
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" kill ||:
|
||||
# if we're in CircleCI, we cannot remove any containers
|
||||
if [[ -z "${CIRCLECI}" ]]; then
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" down -v --remove-orphans
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" down -v --remove-orphans ||:
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ trap cleanup SIGINT SIGTERM EXIT
|
|||
|
||||
# run the unit tests that require a DB
|
||||
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" run --no-deps -d ${dbContainerOpts}
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" run --no-deps --use-aliases -d ${dbContainerOpts}
|
||||
docker-compose -p "${project}_${db}" -f "${composeFile}" run --no-deps \
|
||||
-e NOTARY_BUILDTAGS="${db}db" -e DBURL="${DBURL}" \
|
||||
-e PKGS="github.com/theupdateframework/notary/server/storage github.com/theupdateframework/notary/signer/keydbstore" \
|
||||
|
|
|
@ -28,7 +28,7 @@ BUILD_URL
|
|||
WORKSPACE
|
||||
|
||||
# These are the Travis environment variables to pass through for codecov
|
||||
# http://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
|
||||
# https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables
|
||||
# TRAVIS
|
||||
# TRAVIS_BRANCH
|
||||
# TRAVIS_JOB_NUMBER
|
||||
|
|
|
@ -294,7 +294,7 @@ class Tester(object):
|
|||
for test_func in (self.basic_repo_test, self.add_delegation_test, self.root_rotation_test):
|
||||
_, tempfile = mkstemp()
|
||||
with open(tempfile, 'wb') as handle:
|
||||
handle.write(test_func.__name__ + "\n")
|
||||
handle.write(bytes(str(test_func.__name__ + "\n").encode("utf-8")))
|
||||
|
||||
tempdir = mkdtemp(suffix="_temp")
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
set -eu -o pipefail
|
||||
|
||||
go mod tidy
|
||||
if [ -d vendor ]; then
|
||||
rm -rf vendor/
|
||||
go mod vendor
|
||||
fi
|
||||
|
||||
DIFF_PATH="vendor/ go.mod go.sum"
|
||||
|
||||
# need word splitting here to avoid reading the whole DIFF_PATH as one pathspec
|
||||
#
|
||||
# shellcheck disable=SC2046
|
||||
DIFF=$(git status --porcelain -- $DIFF_PATH)
|
||||
|
||||
if [ "$DIFF" ]; then
|
||||
echo
|
||||
echo "These files were modified:"
|
||||
echo
|
||||
echo "$DIFF"
|
||||
echo
|
||||
exit 1
|
||||
else
|
||||
echo "$DIFF_PATH is correct"
|
||||
fi
|
23
circle.yml
23
circle.yml
|
@ -1,23 +0,0 @@
|
|||
machine:
|
||||
pre:
|
||||
# Upgrade docker
|
||||
- curl -sSL https://s3.amazonaws.com/circle-downloads/install-circleci-docker.sh | bash -s -- 1.10.0
|
||||
# upgrade compose
|
||||
- sudo pip install --upgrade docker-compose
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
dependencies:
|
||||
override:
|
||||
- docker build -t notary_client .
|
||||
|
||||
test:
|
||||
override:
|
||||
# circleci only supports manual parellism
|
||||
- buildscripts/circle_parallelism.sh:
|
||||
parallel: true
|
||||
timeout: 600
|
||||
post:
|
||||
- docker-compose -f docker-compose.yml down -v
|
||||
- docker-compose -f docker-compose.rethink.yml down -v
|
|
@ -98,7 +98,7 @@ func Test0Dot1Migration(t *testing.T) {
|
|||
files, err := ioutil.ReadDir(filepath.Join(tmpDir, notary.PrivDir))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, files[0].Name(), "7fc757801b9bab4ec9e35bfe7a6b61668ff6f4c81b5632af19e6c728ab799599.key")
|
||||
targKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "7fc757801b9bab4ec9e35bfe7a6b61668ff6f4c81b5632af19e6c728ab799599.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
targKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "7fc757801b9bab4ec9e35bfe7a6b61668ff6f4c81b5632af19e6c728ab799599.key"))
|
||||
require.NoError(t, err)
|
||||
defer targKey.Close()
|
||||
targBytes, _ := ioutil.ReadAll(targKey)
|
||||
|
@ -106,7 +106,7 @@ func Test0Dot1Migration(t *testing.T) {
|
|||
require.Contains(t, targString, "gun: docker.com/notary0.1/samplerepo")
|
||||
require.Contains(t, targString, "role: targets")
|
||||
require.Equal(t, files[1].Name(), "a55ccf652b0be4b6c4d356cbb02d9ea432bb84a2571665be3df7c7396af8e8b8.key")
|
||||
snapKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "a55ccf652b0be4b6c4d356cbb02d9ea432bb84a2571665be3df7c7396af8e8b8.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
snapKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "a55ccf652b0be4b6c4d356cbb02d9ea432bb84a2571665be3df7c7396af8e8b8.key"))
|
||||
require.NoError(t, err)
|
||||
defer snapKey.Close()
|
||||
snapBytes, _ := ioutil.ReadAll(snapKey)
|
||||
|
@ -114,7 +114,7 @@ func Test0Dot1Migration(t *testing.T) {
|
|||
require.Contains(t, snapString, "gun: docker.com/notary0.1/samplerepo")
|
||||
require.Contains(t, snapString, "role: snapshot")
|
||||
require.Equal(t, files[2].Name(), "d0c623c8e70c70d42a8a8125c44a8598588b3f6e31d5c21a83cbc338dfde8a68.key")
|
||||
rootKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "d0c623c8e70c70d42a8a8125c44a8598588b3f6e31d5c21a83cbc338dfde8a68.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
rootKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "d0c623c8e70c70d42a8a8125c44a8598588b3f6e31d5c21a83cbc338dfde8a68.key"))
|
||||
require.NoError(t, err)
|
||||
defer rootKey.Close()
|
||||
rootBytes, _ := ioutil.ReadAll(rootKey)
|
||||
|
@ -145,7 +145,7 @@ func Test0Dot3Migration(t *testing.T) {
|
|||
// check that root_keys and tuf_keys are gone and that all corect keys are present and have the correct headers
|
||||
files, _ := ioutil.ReadDir(filepath.Join(tmpDir, notary.PrivDir))
|
||||
require.Equal(t, files[0].Name(), "041b64dab281324ef2b62fd2d04f4758269e120ff063b7bc78709272821a0a02.key")
|
||||
targKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "041b64dab281324ef2b62fd2d04f4758269e120ff063b7bc78709272821a0a02.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
targKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "041b64dab281324ef2b62fd2d04f4758269e120ff063b7bc78709272821a0a02.key"))
|
||||
require.NoError(t, err)
|
||||
defer targKey.Close()
|
||||
targBytes, _ := ioutil.ReadAll(targKey)
|
||||
|
@ -153,7 +153,7 @@ func Test0Dot3Migration(t *testing.T) {
|
|||
require.Contains(t, targString, "gun: docker.com/notary0.3/tst")
|
||||
require.Contains(t, targString, "role: targets")
|
||||
require.Equal(t, files[1].Name(), "85559599cf3cf681ff193f432a7ca6d128182bd1cfa8ede2c70761deac8bc2dc.key")
|
||||
snapKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "85559599cf3cf681ff193f432a7ca6d128182bd1cfa8ede2c70761deac8bc2dc.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
snapKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "85559599cf3cf681ff193f432a7ca6d128182bd1cfa8ede2c70761deac8bc2dc.key"))
|
||||
require.NoError(t, err)
|
||||
defer snapKey.Close()
|
||||
snapBytes, _ := ioutil.ReadAll(snapKey)
|
||||
|
@ -161,7 +161,7 @@ func Test0Dot3Migration(t *testing.T) {
|
|||
require.Contains(t, snapString, "gun: docker.com/notary0.3/tst")
|
||||
require.Contains(t, snapString, "role: snapshot")
|
||||
require.Equal(t, files[2].Name(), "f4eaf871a74aa3b3a0ff95cef2455a1e4d461639f5625418e76756fc5c948690.key")
|
||||
rootKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "f4eaf871a74aa3b3a0ff95cef2455a1e4d461639f5625418e76756fc5c948690.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
rootKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "f4eaf871a74aa3b3a0ff95cef2455a1e4d461639f5625418e76756fc5c948690.key"))
|
||||
require.NoError(t, err)
|
||||
defer rootKey.Close()
|
||||
rootBytes, _ := ioutil.ReadAll(rootKey)
|
||||
|
@ -169,7 +169,7 @@ func Test0Dot3Migration(t *testing.T) {
|
|||
require.Contains(t, rootString, "role: root")
|
||||
require.NotContains(t, rootString, "gun")
|
||||
require.Equal(t, files[3].Name(), "fa842f66cac2dc898677a8660789dcff0e3b0b93b73f8952491f6493199936d3.key")
|
||||
delKey, err := os.OpenFile(filepath.Join(tmpDir, notary.PrivDir, "fa842f66cac2dc898677a8660789dcff0e3b0b93b73f8952491f6493199936d3.key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
delKey, err := os.Open(filepath.Join(tmpDir, notary.PrivDir, "fa842f66cac2dc898677a8660789dcff0e3b0b93b73f8952491f6493199936d3.key"))
|
||||
require.NoError(t, err)
|
||||
defer delKey.Close()
|
||||
delBytes, _ := ioutil.ReadAll(delKey)
|
||||
|
@ -239,7 +239,7 @@ func Test0Dot1RepoFormat(t *testing.T) {
|
|||
// and we can download the snapshot
|
||||
require.NoError(t, repo.RotateKey(data.CanonicalSnapshotRole, true, nil))
|
||||
require.NoError(t, repo.Publish())
|
||||
err = repo.Update(false)
|
||||
err = repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,7 @@ func Test0Dot3RepoFormat(t *testing.T) {
|
|||
// and we can download the snapshot
|
||||
require.NoError(t, repo.RotateKey(data.CanonicalSnapshotRole, true, nil))
|
||||
require.NoError(t, repo.Publish())
|
||||
err = repo.Update(false)
|
||||
err = repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -333,7 +333,7 @@ func TestDownloading0Dot1RepoFormat(t *testing.T) {
|
|||
require.NoError(t, err, "error creating repo: %s", err)
|
||||
repo := r.(*repository)
|
||||
|
||||
err = repo.Update(true)
|
||||
err = repo.updateTUF(true)
|
||||
require.NoError(t, err, "error updating repo: %s", err)
|
||||
}
|
||||
|
||||
|
@ -359,6 +359,6 @@ func TestDownloading0Dot3RepoFormat(t *testing.T) {
|
|||
require.NoError(t, err, "error creating repo: %s", err)
|
||||
repo := r.(*repository)
|
||||
|
||||
err = repo.Update(true)
|
||||
err = repo.updateTUF(true)
|
||||
require.NoError(t, err, "error updating repo: %s", err)
|
||||
}
|
||||
|
|
|
@ -82,8 +82,8 @@ func (c TUFChange) Content() []byte {
|
|||
// unexpected race conditions between humans modifying the same delegation
|
||||
type TUFDelegation struct {
|
||||
NewName data.RoleName `json:"new_name,omitempty"`
|
||||
NewThreshold int `json:"threshold, omitempty"`
|
||||
AddKeys data.KeyList `json:"add_keys, omitempty"`
|
||||
NewThreshold int `json:"threshold,omitempty"`
|
||||
AddKeys data.KeyList `json:"add_keys,omitempty"`
|
||||
RemoveKeys []string `json:"remove_keys,omitempty"`
|
||||
AddPaths []string `json:"add_paths,omitempty"`
|
||||
RemovePaths []string `json:"remove_paths,omitempty"`
|
||||
|
|
|
@ -35,7 +35,10 @@ func getFileNames(dirName string) ([]os.FileInfo, error) {
|
|||
if err != nil {
|
||||
return fileInfos, err
|
||||
}
|
||||
defer dir.Close()
|
||||
defer func() {
|
||||
_ = dir.Close()
|
||||
}()
|
||||
|
||||
dirListing, err = dir.Readdir(0)
|
||||
if err != nil {
|
||||
return fileInfos, err
|
||||
|
@ -89,7 +92,7 @@ func (cl FileChangelist) Add(c Change) error {
|
|||
return err
|
||||
}
|
||||
filename := fmt.Sprintf("%020d_%s.change", time.Now().UnixNano(), uuid.Generate())
|
||||
return ioutil.WriteFile(filepath.Join(cl.dir, filename), cJSON, 0644)
|
||||
return ioutil.WriteFile(filepath.Join(cl.dir, filename), cJSON, 0600)
|
||||
}
|
||||
|
||||
// Remove deletes the changes found at the given indices
|
||||
|
@ -120,7 +123,10 @@ func (cl FileChangelist) Clear(archive string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dir.Close()
|
||||
defer func() {
|
||||
_ = dir.Close()
|
||||
}()
|
||||
|
||||
files, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -50,6 +50,7 @@ func TestErrorConditions(t *testing.T) {
|
|||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
cl, err := NewFileChangelist(tmpDir)
|
||||
require.NoError(t, err)
|
||||
// Attempt to unmarshall a bad JSON file. Note: causes a WARN on the console.
|
||||
ioutil.WriteFile(filepath.Join(tmpDir, "broken_file.change"), []byte{5}, 0644)
|
||||
noItems := cl.List()
|
||||
|
@ -163,7 +164,9 @@ func TestFileChangeIterator(t *testing.T) {
|
|||
}
|
||||
|
||||
// negative test case: changelist directory does not exist
|
||||
os.RemoveAll(tmpDir)
|
||||
it, err = cl.NewIterator()
|
||||
err = os.RemoveAll(tmpDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = cl.NewIterator()
|
||||
require.Error(t, err, "Initializing iterator without underlying file store")
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ type Changelist interface {
|
|||
// Remove deletes the changes corresponding with the indices given
|
||||
Remove(idxs []int) error
|
||||
|
||||
// Close syncronizes any pending writes to the underlying
|
||||
// Close synchronizes any pending writes to the underlying
|
||||
// storage and closes the file/connection
|
||||
Close() error
|
||||
|
||||
|
|
431
client/client.go
431
client/client.go
|
@ -7,10 +7,8 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
canonicaljson "github.com/docker/go/canonical/json"
|
||||
|
@ -39,7 +37,6 @@ func init() {
|
|||
|
||||
// repository stores all the information needed to operate on a notary repository.
|
||||
type repository struct {
|
||||
baseDir string
|
||||
gun data.GUN
|
||||
baseURL string
|
||||
changelist changelist.Changelist
|
||||
|
@ -48,7 +45,6 @@ type repository struct {
|
|||
cryptoService signed.CryptoService
|
||||
tufRepo *tuf.Repo
|
||||
invalid *tuf.Repo // known data that was parsable but deemed invalid
|
||||
roundTrip http.RoundTripper
|
||||
trustPinning trustpinning.TrustPinConfig
|
||||
LegacyVersions int // number of versions back to fetch roots to sign with
|
||||
}
|
||||
|
@ -56,7 +52,8 @@ type repository struct {
|
|||
// NewFileCachedRepository is a wrapper for NewRepository that initializes
|
||||
// a file cache from the provided repository, local config information and a crypto service.
|
||||
// It also retrieves the remote store associated to the base directory under where all the
|
||||
// trust files will be stored and the specified GUN.
|
||||
// trust files will be stored (This is normally defaults to "~/.notary" or "~/.docker/trust"
|
||||
// when enabling Docker content trust) and the specified GUN.
|
||||
//
|
||||
// In case of a nil RoundTripper, a default offline store is used instead.
|
||||
func NewFileCachedRepository(baseDir string, gun data.GUN, baseURL string, rt http.RoundTripper,
|
||||
|
@ -90,16 +87,13 @@ func NewFileCachedRepository(baseDir string, gun data.GUN, baseURL string, rt ht
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return NewRepository(baseDir, gun, baseURL, remoteStore, cache, trustPinning, cryptoService, cl)
|
||||
return NewRepository(gun, baseURL, remoteStore, cache, trustPinning, cryptoService, cl)
|
||||
}
|
||||
|
||||
// NewRepository is the base method that returns a new notary repository.
|
||||
// It takes the base directory under where all the trust files will be stored
|
||||
// (This is normally defaults to "~/.notary" or "~/.docker/trust" when enabling
|
||||
// docker content trust).
|
||||
// It expects an initialized cache. In case of a nil remote store, a default
|
||||
// offline store is used.
|
||||
func NewRepository(baseDir string, gun data.GUN, baseURL string, remoteStore store.RemoteStore, cache store.MetadataStore,
|
||||
func NewRepository(gun data.GUN, baseURL string, remoteStore store.RemoteStore, cache store.MetadataStore,
|
||||
trustPinning trustpinning.TrustPinConfig, cryptoService signed.CryptoService, cl changelist.Changelist) (Repository, error) {
|
||||
|
||||
// Repo's remote store is either a valid remote store or an OfflineStore
|
||||
|
@ -114,7 +108,6 @@ func NewRepository(baseDir string, gun data.GUN, baseURL string, remoteStore sto
|
|||
nRepo := &repository{
|
||||
gun: gun,
|
||||
baseURL: baseURL,
|
||||
baseDir: baseDir,
|
||||
changelist: cl,
|
||||
cache: cache,
|
||||
remoteStore: remoteStore,
|
||||
|
@ -131,20 +124,62 @@ func (r *repository) GetGUN() data.GUN {
|
|||
return r.gun
|
||||
}
|
||||
|
||||
// Target represents a simplified version of the data TUF operates on, so external
|
||||
// applications don't have to depend on TUF data types.
|
||||
type Target struct {
|
||||
Name string // the name of the target
|
||||
Hashes data.Hashes // the hash of the target
|
||||
Length int64 // the size in bytes of the target
|
||||
Custom *canonicaljson.RawMessage // the custom data provided to describe the file at TARGETPATH
|
||||
func (r *repository) updateTUF(forWrite bool) error {
|
||||
repo, invalid, err := LoadTUFRepo(TUFLoadOptions{
|
||||
GUN: r.gun,
|
||||
TrustPinning: r.trustPinning,
|
||||
CryptoService: r.cryptoService,
|
||||
Cache: r.cache,
|
||||
RemoteStore: r.remoteStore,
|
||||
AlwaysCheckInitialized: forWrite,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.tufRepo = repo
|
||||
r.invalid = invalid
|
||||
return nil
|
||||
}
|
||||
|
||||
// TargetWithRole represents a Target that exists in a particular role - this is
|
||||
// produced by ListTargets and GetTargetByName
|
||||
type TargetWithRole struct {
|
||||
Target
|
||||
Role data.RoleName
|
||||
// ListTargets calls update first before listing targets
|
||||
func (r *repository) ListTargets(roles ...data.RoleName) ([]*TargetWithRole, error) {
|
||||
if err := r.updateTUF(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewReadOnly(r.tufRepo).ListTargets(roles...)
|
||||
}
|
||||
|
||||
// GetTargetByName calls update first before getting target by name
|
||||
func (r *repository) GetTargetByName(name string, roles ...data.RoleName) (*TargetWithRole, error) {
|
||||
if err := r.updateTUF(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewReadOnly(r.tufRepo).GetTargetByName(name, roles...)
|
||||
}
|
||||
|
||||
// GetAllTargetMetadataByName calls update first before getting targets by name
|
||||
func (r *repository) GetAllTargetMetadataByName(name string) ([]TargetSignedStruct, error) {
|
||||
if err := r.updateTUF(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewReadOnly(r.tufRepo).GetAllTargetMetadataByName(name)
|
||||
|
||||
}
|
||||
|
||||
// ListRoles calls update first before getting roles
|
||||
func (r *repository) ListRoles() ([]RoleWithSignatures, error) {
|
||||
if err := r.updateTUF(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewReadOnly(r.tufRepo).ListRoles()
|
||||
}
|
||||
|
||||
// GetDelegationRoles calls update first before getting all delegation roles
|
||||
func (r *repository) GetDelegationRoles() ([]data.Role, error) {
|
||||
if err := r.updateTUF(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewReadOnly(r.tufRepo).GetDelegationRoles()
|
||||
}
|
||||
|
||||
// NewTarget is a helper method that returns a Target
|
||||
|
@ -327,7 +362,7 @@ func (r *repository) Initialize(rootKeyIDs []string, serverManagedRoles ...data.
|
|||
type errKeyNotFound struct{}
|
||||
|
||||
func (errKeyNotFound) Error() string {
|
||||
return fmt.Sprintf("cannot find matching private key id")
|
||||
return "cannot find matching private key id"
|
||||
}
|
||||
|
||||
// keyExistsInList returns the id of the private key in ids that matches the public key
|
||||
|
@ -493,167 +528,6 @@ func (r *repository) RemoveTarget(targetName string, roles ...data.RoleName) err
|
|||
return addChange(r.changelist, template, roles...)
|
||||
}
|
||||
|
||||
// ListTargets lists all targets for the current repository. The list of
|
||||
// roles should be passed in order from highest to lowest priority.
|
||||
//
|
||||
// IMPORTANT: if you pass a set of roles such as [ "targets/a", "targets/x"
|
||||
// "targets/a/b" ], even though "targets/a/b" is part of the "targets/a" subtree
|
||||
// its entries will be strictly shadowed by those in other parts of the "targets/a"
|
||||
// subtree and also the "targets/x" subtree, as we will defer parsing it until
|
||||
// we explicitly reach it in our iteration of the provided list of roles.
|
||||
func (r *repository) ListTargets(roles ...data.RoleName) ([]*TargetWithRole, error) {
|
||||
if err := r.Update(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(roles) == 0 {
|
||||
roles = []data.RoleName{data.CanonicalTargetsRole}
|
||||
}
|
||||
targets := make(map[string]*TargetWithRole)
|
||||
for _, role := range roles {
|
||||
// Define an array of roles to skip for this walk (see IMPORTANT comment above)
|
||||
skipRoles := utils.RoleNameSliceRemove(roles, role)
|
||||
|
||||
// Define a visitor function to populate the targets map in priority order
|
||||
listVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
// We found targets so we should try to add them to our targets map
|
||||
for targetName, targetMeta := range tgt.Signed.Targets {
|
||||
// Follow the priority by not overriding previously set targets
|
||||
// and check that this path is valid with this role
|
||||
if _, ok := targets[targetName]; ok || !validRole.CheckPaths(targetName) {
|
||||
continue
|
||||
}
|
||||
targets[targetName] = &TargetWithRole{
|
||||
Target: Target{
|
||||
Name: targetName,
|
||||
Hashes: targetMeta.Hashes,
|
||||
Length: targetMeta.Length,
|
||||
Custom: targetMeta.Custom,
|
||||
},
|
||||
Role: validRole.Name,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
r.tufRepo.WalkTargets("", role, listVisitorFunc, skipRoles...)
|
||||
}
|
||||
|
||||
var targetList []*TargetWithRole
|
||||
for _, v := range targets {
|
||||
targetList = append(targetList, v)
|
||||
}
|
||||
|
||||
return targetList, nil
|
||||
}
|
||||
|
||||
// GetTargetByName returns a target by the given name. If no roles are passed
|
||||
// it uses the targets role and does a search of the entire delegation
|
||||
// graph, finding the first entry in a breadth first search of the delegations.
|
||||
// If roles are passed, they should be passed in descending priority and
|
||||
// the target entry found in the subtree of the highest priority role
|
||||
// will be returned.
|
||||
// See the IMPORTANT section on ListTargets above. Those roles also apply here.
|
||||
func (r *repository) GetTargetByName(name string, roles ...data.RoleName) (*TargetWithRole, error) {
|
||||
if err := r.Update(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(roles) == 0 {
|
||||
roles = append(roles, data.CanonicalTargetsRole)
|
||||
}
|
||||
var resultMeta data.FileMeta
|
||||
var resultRoleName data.RoleName
|
||||
var foundTarget bool
|
||||
for _, role := range roles {
|
||||
// Define an array of roles to skip for this walk (see IMPORTANT comment above)
|
||||
skipRoles := utils.RoleNameSliceRemove(roles, role)
|
||||
|
||||
// Define a visitor function to find the specified target
|
||||
getTargetVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
if tgt == nil {
|
||||
return nil
|
||||
}
|
||||
// We found the target and validated path compatibility in our walk,
|
||||
// so we should stop our walk and set the resultMeta and resultRoleName variables
|
||||
if resultMeta, foundTarget = tgt.Signed.Targets[name]; foundTarget {
|
||||
resultRoleName = validRole.Name
|
||||
return tuf.StopWalk{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Check that we didn't error, and that we assigned to our target
|
||||
if err := r.tufRepo.WalkTargets(name, role, getTargetVisitorFunc, skipRoles...); err == nil && foundTarget {
|
||||
return &TargetWithRole{Target: Target{Name: name, Hashes: resultMeta.Hashes, Length: resultMeta.Length, Custom: resultMeta.Custom}, Role: resultRoleName}, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrNoSuchTarget(name)
|
||||
|
||||
}
|
||||
|
||||
// TargetSignedStruct is a struct that contains a Target, the role it was found in, and the list of signatures for that role
|
||||
type TargetSignedStruct struct {
|
||||
Role data.DelegationRole
|
||||
Target Target
|
||||
Signatures []data.Signature
|
||||
}
|
||||
|
||||
//ErrNoSuchTarget is returned when no valid trust data is found.
|
||||
type ErrNoSuchTarget string
|
||||
|
||||
func (f ErrNoSuchTarget) Error() string {
|
||||
return fmt.Sprintf("No valid trust data for %s", string(f))
|
||||
}
|
||||
|
||||
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||
// If given an empty string for a target name, it will return back all targets signed into the repository in every role
|
||||
func (r *repository) GetAllTargetMetadataByName(name string) ([]TargetSignedStruct, error) {
|
||||
if err := r.Update(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var targetInfoList []TargetSignedStruct
|
||||
|
||||
// Define a visitor function to find the specified target
|
||||
getAllTargetInfoByNameVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
if tgt == nil {
|
||||
return nil
|
||||
}
|
||||
// We found a target and validated path compatibility in our walk,
|
||||
// so add it to our list if we have a match
|
||||
// if we have an empty name, add all targets, else check if we have it
|
||||
var targetMetaToAdd data.Files
|
||||
if name == "" {
|
||||
targetMetaToAdd = tgt.Signed.Targets
|
||||
} else {
|
||||
if meta, ok := tgt.Signed.Targets[name]; ok {
|
||||
targetMetaToAdd = data.Files{name: meta}
|
||||
}
|
||||
}
|
||||
|
||||
for targetName, resultMeta := range targetMetaToAdd {
|
||||
targetInfo := TargetSignedStruct{
|
||||
Role: validRole,
|
||||
Target: Target{Name: targetName, Hashes: resultMeta.Hashes, Length: resultMeta.Length, Custom: resultMeta.Custom},
|
||||
Signatures: tgt.Signatures,
|
||||
}
|
||||
targetInfoList = append(targetInfoList, targetInfo)
|
||||
}
|
||||
// continue walking to all child roles
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check that we didn't error, and that we found the target at least once
|
||||
if err := r.tufRepo.WalkTargets(name, "", getAllTargetInfoByNameVisitorFunc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(targetInfoList) == 0 {
|
||||
return nil, ErrNoSuchTarget(name)
|
||||
}
|
||||
return targetInfoList, nil
|
||||
}
|
||||
|
||||
// GetChangelist returns the list of the repository's unpublished changes
|
||||
func (r *repository) GetChangelist() (changelist.Changelist, error) {
|
||||
return r.changelist, nil
|
||||
|
@ -671,51 +545,6 @@ func (r *repository) getRemoteStore() store.RemoteStore {
|
|||
return r.remoteStore
|
||||
}
|
||||
|
||||
// RoleWithSignatures is a Role with its associated signatures
|
||||
type RoleWithSignatures struct {
|
||||
Signatures []data.Signature
|
||||
data.Role
|
||||
}
|
||||
|
||||
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||
// This represents the latest metadata for each role in this repo
|
||||
func (r *repository) ListRoles() ([]RoleWithSignatures, error) {
|
||||
// Update to latest repo state
|
||||
if err := r.Update(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get all role info from our updated keysDB, can be empty
|
||||
roles := r.tufRepo.GetAllLoadedRoles()
|
||||
|
||||
var roleWithSigs []RoleWithSignatures
|
||||
|
||||
// Populate RoleWithSignatures with Role from keysDB and signatures from TUF metadata
|
||||
for _, role := range roles {
|
||||
roleWithSig := RoleWithSignatures{Role: *role, Signatures: nil}
|
||||
switch role.Name {
|
||||
case data.CanonicalRootRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Root.Signatures
|
||||
case data.CanonicalTargetsRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Targets[data.CanonicalTargetsRole].Signatures
|
||||
case data.CanonicalSnapshotRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Snapshot.Signatures
|
||||
case data.CanonicalTimestampRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Timestamp.Signatures
|
||||
default:
|
||||
if !data.IsDelegation(role.Name) {
|
||||
continue
|
||||
}
|
||||
if _, ok := r.tufRepo.Targets[role.Name]; ok {
|
||||
// We'll only find a signature if we've published any targets with this delegation
|
||||
roleWithSig.Signatures = r.tufRepo.Targets[role.Name].Signatures
|
||||
}
|
||||
}
|
||||
roleWithSigs = append(roleWithSigs, roleWithSig)
|
||||
}
|
||||
return roleWithSigs, nil
|
||||
}
|
||||
|
||||
// Publish pushes the local changes in signed material to the remote notary-server
|
||||
// Conceptually it performs an operation similar to a `git rebase`
|
||||
func (r *repository) Publish() error {
|
||||
|
@ -736,7 +565,7 @@ func (r *repository) Publish() error {
|
|||
func (r *repository) publish(cl changelist.Changelist) error {
|
||||
var initialPublish bool
|
||||
// update first before publishing
|
||||
if err := r.Update(true); err != nil {
|
||||
if err := r.updateTUF(true); err != nil {
|
||||
// If the remote is not aware of the repo, then this is being published
|
||||
// for the first time. Try to initialize the repository before publishing.
|
||||
if _, ok := err.(ErrRepositoryNotExist); ok {
|
||||
|
@ -863,7 +692,14 @@ func (r *repository) oldKeysForLegacyClientSupport(legacyVersions int, initialPu
|
|||
}
|
||||
oldKeys := make(map[string]data.PublicKey)
|
||||
|
||||
c, err := r.bootstrapClient(true)
|
||||
c, err := bootstrapClient(TUFLoadOptions{
|
||||
GUN: r.gun,
|
||||
TrustPinning: r.trustPinning,
|
||||
CryptoService: r.cryptoService,
|
||||
Cache: r.cache,
|
||||
RemoteStore: r.remoteStore,
|
||||
AlwaysCheckInitialized: true,
|
||||
})
|
||||
// require a server connection to fetch old roots
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -1003,135 +839,6 @@ func (r *repository) saveMetadata(ignoreSnapshot bool) error {
|
|||
return r.cache.Set(data.CanonicalSnapshotRole.String(), snapshotJSON)
|
||||
}
|
||||
|
||||
// returns a properly constructed ErrRepositoryNotExist error based on this
|
||||
// repo's information
|
||||
func (r *repository) errRepositoryNotExist() error {
|
||||
host := r.baseURL
|
||||
parsed, err := url.Parse(r.baseURL)
|
||||
if err == nil {
|
||||
host = parsed.Host // try to exclude the scheme and any paths
|
||||
}
|
||||
return ErrRepositoryNotExist{remote: host, gun: r.gun}
|
||||
}
|
||||
|
||||
// Update bootstraps a trust anchor (root.json) before updating all the
|
||||
// metadata from the repo.
|
||||
func (r *repository) Update(forWrite bool) error {
|
||||
c, err := r.bootstrapClient(forWrite)
|
||||
if err != nil {
|
||||
if _, ok := err.(store.ErrMetaNotFound); ok {
|
||||
return r.errRepositoryNotExist()
|
||||
}
|
||||
return err
|
||||
}
|
||||
repo, invalid, err := c.Update()
|
||||
if err != nil {
|
||||
// notFound.Resource may include a version or checksum so when the role is root,
|
||||
// it will be root, <version>.root or root.<checksum>.
|
||||
notFound, ok := err.(store.ErrMetaNotFound)
|
||||
isRoot, _ := regexp.MatchString(`\.?`+data.CanonicalRootRole.String()+`\.?`, notFound.Resource)
|
||||
if ok && isRoot {
|
||||
return r.errRepositoryNotExist()
|
||||
}
|
||||
return err
|
||||
}
|
||||
// we can be assured if we are at this stage that the repo we built is good
|
||||
// no need to test the following function call for an error as it will always be fine should the repo be good- it is!
|
||||
r.tufRepo = repo
|
||||
r.invalid = invalid
|
||||
warnRolesNearExpiry(repo)
|
||||
return nil
|
||||
}
|
||||
|
||||
// bootstrapClient attempts to bootstrap a root.json to be used as the trust
|
||||
// anchor for a repository. The checkInitialized argument indicates whether
|
||||
// we should always attempt to contact the server to determine if the repository
|
||||
// is initialized or not. If set to true, we will always attempt to download
|
||||
// and return an error if the remote repository errors.
|
||||
//
|
||||
// Populates a tuf.RepoBuilder with this root metadata. If the root metadata
|
||||
// downloaded is a newer version than what is on disk, then intermediate
|
||||
// versions will be downloaded and verified in order to rotate trusted keys
|
||||
// properly. Newer root metadata must always be signed with the previous
|
||||
// threshold and keys.
|
||||
//
|
||||
// Fails if the remote server is reachable and does not know the repo
|
||||
// (i.e. before the first r.Publish()), in which case the error is
|
||||
// store.ErrMetaNotFound, or if the root metadata (from whichever source is used)
|
||||
// is not trusted.
|
||||
//
|
||||
// Returns a TUFClient for the remote server, which may not be actually
|
||||
// operational (if the URL is invalid but a root.json is cached).
|
||||
func (r *repository) bootstrapClient(checkInitialized bool) (*tufClient, error) {
|
||||
minVersion := 1
|
||||
// the old root on disk should not be validated against any trust pinning configuration
|
||||
// because if we have an old root, it itself is the thing that pins trust
|
||||
oldBuilder := tuf.NewRepoBuilder(r.gun, r.GetCryptoService(), trustpinning.TrustPinConfig{})
|
||||
|
||||
// by default, we want to use the trust pinning configuration on any new root that we download
|
||||
newBuilder := tuf.NewRepoBuilder(r.gun, r.GetCryptoService(), r.trustPinning)
|
||||
|
||||
// Try to read root from cache first. We will trust this root until we detect a problem
|
||||
// during update which will cause us to download a new root and perform a rotation.
|
||||
// If we have an old root, and it's valid, then we overwrite the newBuilder to be one
|
||||
// preloaded with the old root or one which uses the old root for trust bootstrapping.
|
||||
if rootJSON, err := r.cache.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit); err == nil {
|
||||
// if we can't load the cached root, fail hard because that is how we pin trust
|
||||
if err := oldBuilder.Load(data.CanonicalRootRole, rootJSON, minVersion, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// again, the root on disk is the source of trust pinning, so use an empty trust
|
||||
// pinning configuration
|
||||
newBuilder = tuf.NewRepoBuilder(r.gun, r.GetCryptoService(), trustpinning.TrustPinConfig{})
|
||||
|
||||
if err := newBuilder.Load(data.CanonicalRootRole, rootJSON, minVersion, false); err != nil {
|
||||
// Ok, the old root is expired - we want to download a new one. But we want to use the
|
||||
// old root to verify the new root, so bootstrap a new builder with the old builder
|
||||
// but use the trustpinning to validate the new root
|
||||
minVersion = oldBuilder.GetLoadedVersion(data.CanonicalRootRole)
|
||||
newBuilder = oldBuilder.BootstrapNewBuilderWithNewTrustpin(r.trustPinning)
|
||||
}
|
||||
}
|
||||
|
||||
remote := r.getRemoteStore()
|
||||
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) || checkInitialized {
|
||||
// remoteErr was nil and we were not able to load a root from cache or
|
||||
// are specifically checking for initialization of the repo.
|
||||
|
||||
// if remote store successfully set up, try and get root from remote
|
||||
// We don't have any local data to determine the size of root, so try the maximum (though it is restricted at 100MB)
|
||||
tmpJSON, err := remote.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit)
|
||||
if err != nil {
|
||||
// we didn't have a root in cache and were unable to load one from
|
||||
// the server. Nothing we can do but error.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) {
|
||||
// we always want to use the downloaded root if we couldn't load from cache
|
||||
if err := newBuilder.Load(data.CanonicalRootRole, tmpJSON, minVersion, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = r.cache.Set(data.CanonicalRootRole.String(), tmpJSON)
|
||||
if err != nil {
|
||||
// if we can't write cache we should still continue, just log error
|
||||
logrus.Errorf("could not save root to cache: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can only get here if remoteErr != nil (hence we don't download any new root),
|
||||
// and there was no root on disk
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) {
|
||||
return nil, ErrRepoNotInitialized{}
|
||||
}
|
||||
|
||||
return newTufClient(oldBuilder, newBuilder, remote, r.cache), nil
|
||||
}
|
||||
|
||||
// RotateKey removes all existing keys associated with the role. If no keys are
|
||||
// specified in keyList, then this creates and adds one new key or delegates
|
||||
// managing the key to the server. If key(s) are specified by keyList, then they are
|
||||
|
@ -1273,7 +980,7 @@ func DeleteTrustData(baseDir string, gun data.GUN, URL string, rt http.RoundTrip
|
|||
if deleteRemote {
|
||||
remote, err := getRemoteStore(URL, gun, rt)
|
||||
if err != nil {
|
||||
logrus.Error("unable to instantiate a remote store: %v", err)
|
||||
logrus.Errorf("unable to instantiate a remote store: %v", err)
|
||||
return err
|
||||
}
|
||||
if err := remote.RemoveAll(); err != nil {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/theupdateframework/notary/tuf/testutils"
|
||||
)
|
||||
|
||||
func newBlankRepo(t *testing.T, url string) *repository {
|
||||
func newBlankRepo(t *testing.T, url string) (*repository, string) {
|
||||
// Temporary directory where test files will be created
|
||||
tempBaseDir, err := ioutil.TempDir("", "notary-test-")
|
||||
require.NoError(t, err, "failed to create a temporary directory: %s", err)
|
||||
|
@ -34,7 +34,7 @@ func newBlankRepo(t *testing.T, url string) *repository {
|
|||
r, err := NewFileCachedRepository(tempBaseDir, "docker.com/notary", url,
|
||||
http.DefaultTransport, passphrase.ConstantRetriever("pass"), trustpinning.TrustPinConfig{})
|
||||
require.NoError(t, err)
|
||||
return r.(*repository)
|
||||
return r.(*repository), tempBaseDir
|
||||
}
|
||||
|
||||
var metadataDelegations = []data.RoleName{"targets/a", "targets/a/b", "targets/b", "targets/a/b/c", "targets/b/c"}
|
||||
|
@ -112,9 +112,9 @@ func TestUpdateSucceedsEvenIfCannotWriteNewRepo(t *testing.T) {
|
|||
defer ts.Close()
|
||||
|
||||
for role := range serverMeta {
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
repo.cache = &unwritableStore{MetadataStore: repo.cache, roleToNotWrite: role}
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
|
||||
for r, expected := range serverMeta {
|
||||
|
@ -130,7 +130,7 @@ func TestUpdateSucceedsEvenIfCannotWriteNewRepo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
os.RemoveAll(repo.baseDir)
|
||||
os.RemoveAll(baseDir)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,10 +145,10 @@ func TestUpdateSucceedsEvenIfCannotWriteExistingRepo(t *testing.T) {
|
|||
defer ts.Close()
|
||||
|
||||
// download existing metadata
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
|
||||
origFileStore := repo.cache
|
||||
|
@ -160,7 +160,7 @@ func TestUpdateSucceedsEvenIfCannotWriteExistingRepo(t *testing.T) {
|
|||
|
||||
// update fileStore
|
||||
repo.cache = &unwritableStore{MetadataStore: origFileStore, roleToNotWrite: role}
|
||||
err := repo.Update(forWrite)
|
||||
err := repo.updateTUF(forWrite)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -196,9 +196,9 @@ func TestUpdateInOfflineMode(t *testing.T) {
|
|||
}
|
||||
|
||||
// invalid URL, no cache - errors
|
||||
invalidURLRepo := newBlankRepo(t, "https://nothisdoesnotexist.com")
|
||||
defer os.RemoveAll(invalidURLRepo.baseDir)
|
||||
err := invalidURLRepo.Update(false)
|
||||
invalidURLRepo, baseDir := newBlankRepo(t, "https://nothisdoesnotexist.com")
|
||||
defer os.RemoveAll(baseDir)
|
||||
err := invalidURLRepo.updateTUF(false)
|
||||
require.Error(t, err)
|
||||
require.IsType(t, store.NetworkError{}, err)
|
||||
|
||||
|
@ -211,7 +211,7 @@ func TestUpdateInOfflineMode(t *testing.T) {
|
|||
nil, passphrase.ConstantRetriever("pass"), trustpinning.TrustPinConfig{})
|
||||
require.NoError(t, err)
|
||||
offlineRepo := or.(*repository)
|
||||
err = offlineRepo.Update(false)
|
||||
err = offlineRepo.updateTUF(false)
|
||||
require.Error(t, err)
|
||||
require.IsType(t, store.ErrOffline{}, err)
|
||||
|
||||
|
@ -224,8 +224,8 @@ func TestUpdateInOfflineMode(t *testing.T) {
|
|||
}
|
||||
|
||||
// both of these can read from cache and load repo
|
||||
require.NoError(t, invalidURLRepo.Update(false))
|
||||
require.NoError(t, offlineRepo.Update(false))
|
||||
require.NoError(t, invalidURLRepo.updateTUF(false))
|
||||
require.NoError(t, offlineRepo.updateTUF(false))
|
||||
}
|
||||
|
||||
type swizzleFunc func(*testutils.MetadataSwizzler, data.RoleName) error
|
||||
|
@ -274,10 +274,10 @@ func TestUpdateReplacesCorruptOrMissingMetadata(t *testing.T) {
|
|||
ts := readOnlyServer(t, store.NewMemoryStore(serverMeta), http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
err = repo.Update(false) // ensure we have all metadata to start with
|
||||
err = repo.updateTUF(false) // ensure we have all metadata to start with
|
||||
require.NoError(t, err)
|
||||
|
||||
// we want to swizzle the local cache, not the server, so create a new one
|
||||
|
@ -291,7 +291,7 @@ func TestUpdateReplacesCorruptOrMissingMetadata(t *testing.T) {
|
|||
text, messItUp := expt.desc, expt.swizzle
|
||||
for _, forWrite := range []bool{true, false} {
|
||||
require.NoError(t, messItUp(repoSwizzler, role), "could not fuzz %s (%s)", role, text)
|
||||
err := repo.Update(forWrite)
|
||||
err := repo.updateTUF(forWrite)
|
||||
// If this is a root role, we should error if it's corrupted or invalid data;
|
||||
// missing metadata is ok.
|
||||
if role == data.CanonicalRootRole && expt.desc != "missing metadata" &&
|
||||
|
@ -332,10 +332,10 @@ func TestUpdateFailsIfServerRootKeyChangedWithoutMultiSign(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
err := repo.Update(false) // ensure we have all metadata to start with
|
||||
err := repo.updateTUF(false) // ensure we have all metadata to start with
|
||||
require.NoError(t, err)
|
||||
|
||||
// rotate the server's root.json root key so that they no longer match trust anchors
|
||||
|
@ -358,7 +358,7 @@ func TestUpdateFailsIfServerRootKeyChangedWithoutMultiSign(t *testing.T) {
|
|||
|
||||
if _, ok := err.(store.ErrMetaNotFound); ok { // one of the ways to mess up is to delete metadata
|
||||
|
||||
err = repo.Update(forWrite)
|
||||
err = repo.updateTUF(forWrite)
|
||||
// the new server has a different root key, but we don't have any way of pinning against a previous root
|
||||
require.NoError(t, err)
|
||||
// revert our original metadata
|
||||
|
@ -369,7 +369,7 @@ func TestUpdateFailsIfServerRootKeyChangedWithoutMultiSign(t *testing.T) {
|
|||
|
||||
require.NoError(t, err)
|
||||
|
||||
err = repo.Update(forWrite)
|
||||
err = repo.updateTUF(forWrite)
|
||||
require.Error(t, err) // the new server has a different root, update fails
|
||||
|
||||
// we can't test that all the metadata is the same, because we probably would
|
||||
|
@ -686,11 +686,11 @@ func testUpdateRemoteNon200Error(t *testing.T, opts updateOpts, errExpected inte
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, opts.notFoundCode, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
if opts.localCache {
|
||||
err := repo.Update(false) // acquire local cache
|
||||
err := repo.updateTUF(false) // acquire local cache
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -700,7 +700,7 @@ func testUpdateRemoteNon200Error(t *testing.T, opts updateOpts, errExpected inte
|
|||
|
||||
require.NoError(t, serverSwizzler.RemoveMetadata(opts.role), "failed to remove %s", opts.role)
|
||||
|
||||
err := repo.Update(opts.forWrite)
|
||||
err := repo.updateTUF(opts.forWrite)
|
||||
if errExpected == nil {
|
||||
require.NoError(t, err, "expected no failure updating when %s is %v (forWrite: %v)",
|
||||
opts.role, opts.notFoundCode, opts.forWrite)
|
||||
|
@ -798,11 +798,11 @@ func testUpdateRemoteFileChecksumWrong(t *testing.T, opts updateOpts, errExpecte
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
if opts.localCache {
|
||||
err := repo.Update(false) // acquire local cache
|
||||
err := repo.updateTUF(false) // acquire local cache
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -812,7 +812,7 @@ func testUpdateRemoteFileChecksumWrong(t *testing.T, opts updateOpts, errExpecte
|
|||
|
||||
require.NoError(t, serverSwizzler.AddExtraSpace(opts.role), "failed to checksum-corrupt to %s", opts.role)
|
||||
|
||||
err := repo.Update(opts.forWrite)
|
||||
err := repo.updateTUF(opts.forWrite)
|
||||
if !errExpected {
|
||||
require.NoError(t, err, "expected no failure updating when %s has the wrong checksum (forWrite: %v)",
|
||||
opts.role, opts.forWrite)
|
||||
|
@ -993,7 +993,7 @@ func waysToMessUpServerNonRootPerRole(t *testing.T) map[string][]swizzleExpectat
|
|||
perRoleSwizzling[data.CanonicalSnapshotRole.String()] = append(
|
||||
perRoleSwizzling[data.CanonicalSnapshotRole.String()],
|
||||
swizzleExpectations{
|
||||
desc: fmt.Sprintf("snapshot missing root meta checksum"),
|
||||
desc: "snapshot missing root meta checksum",
|
||||
expectErrs: []interface{}{data.ErrInvalidMetadata{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role data.RoleName) error {
|
||||
return s.MutateSnapshot(func(sn *data.Snapshot) {
|
||||
|
@ -1003,7 +1003,7 @@ func waysToMessUpServerNonRootPerRole(t *testing.T) map[string][]swizzleExpectat
|
|||
})
|
||||
}
|
||||
perRoleSwizzling[data.CanonicalTargetsRole.String()] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("target missing delegations data"),
|
||||
desc: "target missing delegations data",
|
||||
expectErrs: []interface{}{data.ErrMismatchedChecksum{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role data.RoleName) error {
|
||||
return s.MutateTargets(func(tg *data.Targets) {
|
||||
|
@ -1012,7 +1012,7 @@ func waysToMessUpServerNonRootPerRole(t *testing.T) map[string][]swizzleExpectat
|
|||
},
|
||||
}}
|
||||
perRoleSwizzling[data.CanonicalTimestampRole.String()] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("timestamp missing snapshot meta checksum"),
|
||||
desc: "timestamp missing snapshot meta checksum",
|
||||
expectErrs: []interface{}{data.ErrInvalidMetadata{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role data.RoleName) error {
|
||||
return s.MutateTimestamp(func(ts *data.Timestamp) {
|
||||
|
@ -1021,7 +1021,7 @@ func waysToMessUpServerNonRootPerRole(t *testing.T) map[string][]swizzleExpectat
|
|||
},
|
||||
}}
|
||||
perRoleSwizzling["targets/a"] = []swizzleExpectations{{
|
||||
desc: fmt.Sprintf("delegation has invalid role"),
|
||||
desc: "delegation has invalid role",
|
||||
expectErrs: []interface{}{data.ErrInvalidMetadata{}},
|
||||
swizzle: func(s *testutils.MetadataSwizzler, role data.RoleName) error {
|
||||
return s.MutateTargets(func(tg *data.Targets) {
|
||||
|
@ -1057,10 +1057,9 @@ func TestUpdateNonRootRemoteCorruptedNoLocalCache(t *testing.T) {
|
|||
t.Skip("skipping test in short mode")
|
||||
}
|
||||
|
||||
for _, role := range append(data.BaseRoles) {
|
||||
for _, role := range data.BaseRoles {
|
||||
switch role {
|
||||
case data.CanonicalRootRole:
|
||||
break
|
||||
default:
|
||||
for _, testData := range waysToMessUpServer {
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
|
@ -1201,7 +1200,6 @@ func TestUpdateNonRootRemoteCorruptedCannotUseLocalCache(t *testing.T) {
|
|||
for _, role := range data.BaseRoles {
|
||||
switch role {
|
||||
case data.CanonicalRootRole:
|
||||
break
|
||||
default:
|
||||
for _, testData := range waysToMessUpServer {
|
||||
testUpdateRemoteCorruptValidChecksum(t, updateOpts{
|
||||
|
@ -1274,11 +1272,11 @@ func testUpdateRemoteCorruptValidChecksum(t *testing.T, opts updateOpts, expt sw
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
if opts.localCache {
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
@ -1312,7 +1310,7 @@ func testUpdateRemoteCorruptValidChecksum(t *testing.T, opts updateOpts, expt sw
|
|||
}
|
||||
}
|
||||
}
|
||||
err := repo.Update(opts.forWrite)
|
||||
err := repo.updateTUF(opts.forWrite)
|
||||
checkErrors(t, err, shouldErr, expt.expectErrs, msg)
|
||||
|
||||
if opts.checkRepo != nil {
|
||||
|
@ -1359,11 +1357,11 @@ func testUpdateLocalAndRemoteRootCorrupt(t *testing.T, forWrite bool, localExpt,
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// get local cache
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
repoSwizzler := &testutils.MetadataSwizzler{
|
||||
Gun: serverSwizzler.Gun,
|
||||
|
@ -1386,7 +1384,7 @@ func testUpdateLocalAndRemoteRootCorrupt(t *testing.T, forWrite bool, localExpt,
|
|||
msg := fmt.Sprintf("swizzling root locally to return <%v> and remotely to return: <%v> (forWrite: %v)",
|
||||
localExpt.desc, serverExpt.desc, forWrite)
|
||||
|
||||
err = repo.Update(forWrite)
|
||||
err = repo.updateTUF(forWrite)
|
||||
require.Error(t, err, "expected failure updating when %s", msg)
|
||||
|
||||
expectedErrs := serverExpt.expectErrs
|
||||
|
@ -1429,11 +1427,11 @@ func testUpdateRemoteKeyRotated(t *testing.T, role data.RoleName) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// get local cache
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.NoError(t, err)
|
||||
|
||||
cs := signed.NewEd25519()
|
||||
|
@ -1457,7 +1455,7 @@ func testUpdateRemoteKeyRotated(t *testing.T, role data.RoleName) {
|
|||
|
||||
msg := fmt.Sprintf("swizzling %s remotely to rotate key (forWrite: false)", role)
|
||||
|
||||
err = repo.Update(false)
|
||||
err = repo.updateTUF(false)
|
||||
// invalid signatures are ok - the delegation is just skipped
|
||||
if data.IsDelegation(role) {
|
||||
require.NoError(t, err)
|
||||
|
@ -1514,8 +1512,8 @@ func TestValidateRootRotationWithOldRole(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// --- setup so that the root starts with a role with 3 keys, and threshold of 2
|
||||
// --- signed by the first two keys (also, the original role which has 1 original
|
||||
|
@ -1550,7 +1548,7 @@ func TestValidateRootRotationWithOldRole(t *testing.T) {
|
|||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys[:2])
|
||||
|
||||
// Load this root for the first time with 3 keys
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// --- First root rotation: replace the first key with a different key and change the
|
||||
// --- threshold back to 1
|
||||
|
@ -1567,12 +1565,12 @@ func TestValidateRootRotationWithOldRole(t *testing.T) {
|
|||
// --- will fail. (signing with just the second key will not satisfy the first role,
|
||||
// --- because that one has a threshold of 2, although it will satisfy the new role)
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys[1:2])
|
||||
require.Error(t, repo.Update(false))
|
||||
require.Error(t, repo.updateTUF(false))
|
||||
|
||||
// --- If both the current and previous roles are satisfied, then the root rotation
|
||||
// --- will succeed (signing with the second and third keys will satisfies both)
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys[1:])
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// --- Older roles do not have to be satisfied in order to validate if the update
|
||||
// --- does not involve a root rotation (replacing the snapshot key is not a root
|
||||
|
@ -1586,7 +1584,7 @@ func TestValidateRootRotationWithOldRole(t *testing.T) {
|
|||
signedRoot.Signed.Roles[data.CanonicalSnapshotRole].KeyIDs = []string{snapKey.ID()}
|
||||
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{replacementKey})
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// --- Second root rotation: if only the previous role is satisfied but not the new role,
|
||||
// --- then the root rotation will fail (if we rotate to the only valid signing key being
|
||||
|
@ -1596,11 +1594,11 @@ func TestValidateRootRotationWithOldRole(t *testing.T) {
|
|||
signedRoot.Signed.Roles[data.CanonicalRootRole].KeyIDs = []string{keyIDs[0]}
|
||||
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{replacementKey})
|
||||
require.Error(t, repo.Update(false))
|
||||
require.Error(t, repo.updateTUF(false))
|
||||
|
||||
// again, signing with both will succeed
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{replacementKey, threeKeys[0]})
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
}
|
||||
|
||||
// A valid root role is signed by the current root role keys and the previous root role keys
|
||||
|
@ -1610,8 +1608,8 @@ func TestRootRoleInvariant(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// --- setup so that the root starts with a role with 1 keys, and threshold of 1
|
||||
rootBytes, err := serverSwizzler.MetadataCache.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit)
|
||||
|
@ -1642,7 +1640,7 @@ func TestRootRoleInvariant(t *testing.T) {
|
|||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{threeKeys[0]})
|
||||
|
||||
// Load this root for the first time with 1 key
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// --- First root rotation: replace the first key with a different key
|
||||
signedRoot.Signed.Version++
|
||||
|
@ -1652,13 +1650,13 @@ func TestRootRoleInvariant(t *testing.T) {
|
|||
// --- If the current role is satisfied but the previous one is not, root rotation
|
||||
// --- will fail. Signing with just the second key will not satisfy the first role.
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{threeKeys[1]})
|
||||
require.Error(t, repo.Update(false))
|
||||
require.Error(t, repo.updateTUF(false))
|
||||
requireRootSignatures(t, serverSwizzler, 1)
|
||||
|
||||
// --- If both the current and previous roles are satisfied, then the root rotation
|
||||
// --- will succeed (signing with the first and second keys will satisfy both)
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys[:2])
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
requireRootSignatures(t, serverSwizzler, 2)
|
||||
|
||||
// --- Second root rotation: replace the second key with a third
|
||||
|
@ -1669,18 +1667,18 @@ func TestRootRoleInvariant(t *testing.T) {
|
|||
// --- If the current role is satisfied but the previous one is not, root rotation
|
||||
// --- will fail. Signing with just the second key will not satisfy the first role.
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{threeKeys[2]})
|
||||
require.Error(t, repo.Update(false))
|
||||
require.Error(t, repo.updateTUF(false))
|
||||
requireRootSignatures(t, serverSwizzler, 1)
|
||||
|
||||
// --- If both the current and previous roles are satisfied, then the root rotation
|
||||
// --- will succeed (signing with the second and third keys will satisfy both)
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys[1:])
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
requireRootSignatures(t, serverSwizzler, 2)
|
||||
|
||||
// -- If signed with all previous roles, update will succeed
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, threeKeys)
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
requireRootSignatures(t, serverSwizzler, 3)
|
||||
}
|
||||
|
||||
|
@ -1691,8 +1689,8 @@ func TestBadIntermediateTransitions(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// --- setup so that the root starts with a role with 1 keys, and threshold of 1
|
||||
rootBytes, err := serverSwizzler.MetadataCache.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit)
|
||||
|
@ -1717,7 +1715,7 @@ func TestBadIntermediateTransitions(t *testing.T) {
|
|||
signedRoot.Signed.Roles[data.CanonicalRootRole].Threshold = 1
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{threeKeys[0]})
|
||||
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// increment the root version and sign with the second key only
|
||||
signedRoot.Signed.Version++
|
||||
|
@ -1738,7 +1736,7 @@ func TestBadIntermediateTransitions(t *testing.T) {
|
|||
requireRootSignatures(t, serverSwizzler, 1)
|
||||
|
||||
// Update fails because version 1 -> 2 is invalid.
|
||||
require.Error(t, repo.Update(false))
|
||||
require.Error(t, repo.updateTUF(false))
|
||||
}
|
||||
|
||||
// All intermediate roots must be signed by the previous root role
|
||||
|
@ -1748,8 +1746,8 @@ func TestExpiredIntermediateTransitions(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
// --- setup so that the root starts with a role with 1 keys, and threshold of 1
|
||||
rootBytes, err := serverSwizzler.MetadataCache.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit)
|
||||
|
@ -1774,7 +1772,7 @@ func TestExpiredIntermediateTransitions(t *testing.T) {
|
|||
signedRoot.Signed.Roles[data.CanonicalRootRole].Threshold = 1
|
||||
signSerializeAndUpdateRoot(t, signedRoot, serverSwizzler, []data.PublicKey{threeKeys[0]})
|
||||
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
|
||||
// increment the root version and sign with the first and second keys, but set metadata to be expired.
|
||||
signedRoot.Signed.Version++
|
||||
|
@ -1794,7 +1792,7 @@ func TestExpiredIntermediateTransitions(t *testing.T) {
|
|||
requireRootSignatures(t, serverSwizzler, 3)
|
||||
|
||||
// Update succeeds despite version 2 being expired.
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
}
|
||||
|
||||
// TestDownloadTargetsLarge: Check that we can download very large targets metadata files,
|
||||
|
@ -1827,8 +1825,8 @@ func TestDownloadTargetsLarge(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
notaryRepo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(notaryRepo.baseDir)
|
||||
notaryRepo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
tgts, err := notaryRepo.ListTargets()
|
||||
require.NoError(t, err)
|
||||
|
@ -1861,8 +1859,8 @@ func TestDownloadTargetsDeep(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
roles, err := repo.ListRoles()
|
||||
require.NoError(t, err)
|
||||
|
@ -1925,8 +1923,8 @@ func TestDownloadSnapshotLargeDelegationsMany(t *testing.T) {
|
|||
ts := readOnlyServer(t, serverSwizzler.MetadataCache, http.StatusNotFound, "docker.com/notary")
|
||||
defer ts.Close()
|
||||
|
||||
notaryRepo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(notaryRepo.baseDir)
|
||||
notaryRepo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
|
||||
roles, err := notaryRepo.ListRoles()
|
||||
require.NoError(t, err)
|
||||
|
@ -1955,20 +1953,45 @@ func TestRootOnDiskTrustPinning(t *testing.T) {
|
|||
restrictiveTrustPinning := trustpinning.TrustPinConfig{DisableTOFU: true}
|
||||
|
||||
// for sanity, ensure that without a root on disk, we can't download a new root
|
||||
repo := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir := newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
repo.trustPinning = restrictiveTrustPinning
|
||||
|
||||
err := repo.Update(false)
|
||||
err := repo.updateTUF(false)
|
||||
require.Error(t, err)
|
||||
require.IsType(t, &trustpinning.ErrValidationFail{}, err)
|
||||
|
||||
// show that if we have a root on disk, we can update
|
||||
repo = newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(repo.baseDir)
|
||||
repo, baseDir = newBlankRepo(t, ts.URL)
|
||||
defer os.RemoveAll(baseDir)
|
||||
repo.trustPinning = restrictiveTrustPinning
|
||||
// put root on disk
|
||||
require.NoError(t, repo.cache.Set(data.CanonicalRootRole.String(), meta[data.CanonicalRootRole]))
|
||||
|
||||
require.NoError(t, repo.Update(false))
|
||||
require.NoError(t, repo.updateTUF(false))
|
||||
}
|
||||
|
||||
// TestLoadTUFRepoBadURL checks that LoadTUFRepo correctly
|
||||
// returns an error when the URL is valid but does not point to
|
||||
// a TUF server, and there is no cache on disk
|
||||
func TestLoadTUFRepoBadURL(t *testing.T) {
|
||||
remote, err := store.NewNotaryServerStore("https://localhost:9998", "testGUN", http.DefaultTransport)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err1 := LoadTUFRepo(TUFLoadOptions{
|
||||
GUN: "testGUN",
|
||||
RemoteStore: remote,
|
||||
AlwaysCheckInitialized: true,
|
||||
})
|
||||
|
||||
_, _, err2 := LoadTUFRepo(TUFLoadOptions{
|
||||
GUN: "testGUN",
|
||||
RemoteStore: remote,
|
||||
AlwaysCheckInitialized: false,
|
||||
})
|
||||
|
||||
// same error should be returned because we don't have local data
|
||||
// and are requesting remote root regardless of checkInitialized
|
||||
// value
|
||||
require.EqualError(t, err1, err2.Error())
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/client/changelist"
|
||||
store "github.com/theupdateframework/notary/storage"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
"github.com/theupdateframework/notary/tuf/utils"
|
||||
)
|
||||
|
@ -77,7 +76,7 @@ func (r *repository) AddDelegationPaths(name data.RoleName, paths []string) erro
|
|||
}
|
||||
|
||||
// RemoveDelegationKeysAndPaths creates changelist entries to remove provided delegation key IDs and paths.
|
||||
// This method composes RemoveDelegationPaths and RemoveDelegationKeys (each creates one changelist if called).
|
||||
// This method composes RemoveDelegationPaths and RemoveDelegationKeys (each creates one changelist entry if called).
|
||||
func (r *repository) RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error {
|
||||
if len(paths) > 0 {
|
||||
err := r.RemoveDelegationPaths(name, paths)
|
||||
|
@ -201,41 +200,6 @@ func newDeleteDelegationChange(name data.RoleName, content []byte) *changelist.T
|
|||
)
|
||||
}
|
||||
|
||||
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||
// Also converts key IDs to canonical key IDs to keep consistent with signing prompts
|
||||
func (r *repository) GetDelegationRoles() ([]data.Role, error) {
|
||||
// Update state of the repo to latest
|
||||
if err := r.Update(false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// All top level delegations (ex: targets/level1) are stored exclusively in targets.json
|
||||
_, ok := r.tufRepo.Targets[data.CanonicalTargetsRole]
|
||||
if !ok {
|
||||
return nil, store.ErrMetaNotFound{Resource: data.CanonicalTargetsRole.String()}
|
||||
}
|
||||
|
||||
// make a copy for traversing nested delegations
|
||||
allDelegations := []data.Role{}
|
||||
|
||||
// Define a visitor function to populate the delegations list and translate their key IDs to canonical IDs
|
||||
delegationCanonicalListVisitor := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
// For the return list, update with a copy that includes canonicalKeyIDs
|
||||
// These aren't validated by the validRole
|
||||
canonicalDelegations, err := translateDelegationsToCanonicalIDs(tgt.Signed.Delegations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allDelegations = append(allDelegations, canonicalDelegations...)
|
||||
return nil
|
||||
}
|
||||
err := r.tufRepo.WalkTargets("", "", delegationCanonicalListVisitor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return allDelegations, nil
|
||||
}
|
||||
|
||||
func translateDelegationsToCanonicalIDs(delegationInfo data.Delegations) ([]data.Role, error) {
|
||||
canonicalDelegations := make([]data.Role, len(delegationInfo.Roles))
|
||||
// Do a copy by value to ensure local delegation metadata is untouched
|
||||
|
@ -248,11 +212,11 @@ func translateDelegationsToCanonicalIDs(delegationInfo data.Delegations) ([]data
|
|||
for _, keyID := range delegation.KeyIDs {
|
||||
pubKey, ok := delegationKeys[keyID]
|
||||
if !ok {
|
||||
return []data.Role{}, fmt.Errorf("Could not translate canonical key IDs for %s", delegation.Name)
|
||||
return []data.Role{}, fmt.Errorf("could not translate canonical key IDs for %s", delegation.Name)
|
||||
}
|
||||
canonicalKeyID, err := utils.CanonicalKeyID(pubKey)
|
||||
if err != nil {
|
||||
return []data.Role{}, fmt.Errorf("Could not translate canonical key IDs for %s: %v", delegation.Name, err)
|
||||
return []data.Role{}, fmt.Errorf("could not translate canonical key IDs for %s: %v", delegation.Name, err)
|
||||
}
|
||||
canonicalKeyIDs = append(canonicalKeyIDs, canonicalKeyID)
|
||||
}
|
||||
|
|
|
@ -6,42 +6,145 @@ import (
|
|||
"github.com/theupdateframework/notary/tuf/signed"
|
||||
)
|
||||
|
||||
// Repository represents the set of options that must be supported over a TUF repo.
|
||||
type Repository interface {
|
||||
// General management operations
|
||||
Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error
|
||||
InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error
|
||||
Publish() error
|
||||
|
||||
// Target Operations
|
||||
AddTarget(target *Target, roles ...data.RoleName) error
|
||||
RemoveTarget(targetName string, roles ...data.RoleName) error
|
||||
// ReadOnly represents the set of options that must be supported over a TUF repo for
|
||||
// reading
|
||||
type ReadOnly interface {
|
||||
// ListTargets lists all targets for the current repository. The list of
|
||||
// roles should be passed in order from highest to lowest priority.
|
||||
//
|
||||
// IMPORTANT: if you pass a set of roles such as [ "targets/a", "targets/x"
|
||||
// "targets/a/b" ], even though "targets/a/b" is part of the "targets/a" subtree
|
||||
// its entries will be strictly shadowed by those in other parts of the "targets/a"
|
||||
// subtree and also the "targets/x" subtree, as we will defer parsing it until
|
||||
// we explicitly reach it in our iteration of the provided list of roles.
|
||||
ListTargets(roles ...data.RoleName) ([]*TargetWithRole, error)
|
||||
|
||||
// GetTargetByName returns a target by the given name. If no roles are passed
|
||||
// it uses the targets role and does a search of the entire delegation
|
||||
// graph, finding the first entry in a breadth first search of the delegations.
|
||||
// If roles are passed, they should be passed in descending priority and
|
||||
// the target entry found in the subtree of the highest priority role
|
||||
// will be returned.
|
||||
// See the IMPORTANT section on ListTargets above. Those roles also apply here.
|
||||
GetTargetByName(name string, roles ...data.RoleName) (*TargetWithRole, error)
|
||||
|
||||
// GetAllTargetMetadataByName searches the entire delegation role tree to find
|
||||
// the specified target by name for all roles, and returns a list of
|
||||
// TargetSignedStructs for each time it finds the specified target.
|
||||
// If given an empty string for a target name, it will return back all targets
|
||||
// signed into the repository in every role
|
||||
GetAllTargetMetadataByName(name string) ([]TargetSignedStruct, error)
|
||||
|
||||
// Changelist operations
|
||||
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||
// This represents the latest metadata for each role in this repo
|
||||
ListRoles() ([]RoleWithSignatures, error)
|
||||
|
||||
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||
// Also converts key IDs to canonical key IDs to keep consistent with signing prompts
|
||||
GetDelegationRoles() ([]data.Role, error)
|
||||
}
|
||||
|
||||
// Repository represents the set of options that must be supported over a TUF repo
|
||||
// for both reading and writing.
|
||||
type Repository interface {
|
||||
ReadOnly
|
||||
|
||||
// ------------------- Publishing operations -------------------
|
||||
|
||||
// GetGUN returns the GUN associated with the repository
|
||||
GetGUN() data.GUN
|
||||
|
||||
// SetLegacyVersion sets the number of versions back to fetch roots to sign with
|
||||
SetLegacyVersions(int)
|
||||
|
||||
// ----- General management operations -----
|
||||
|
||||
// Initialize creates a new repository by using rootKey as the root Key for the
|
||||
// TUF repository. The remote store/server must be reachable (and is asked to
|
||||
// generate a timestamp key and possibly other serverManagedRoles), but the
|
||||
// created repository result is only stored on local cache, not published to
|
||||
// the remote store. To do that, use r.Publish() eventually.
|
||||
Initialize(rootKeyIDs []string, serverManagedRoles ...data.RoleName) error
|
||||
|
||||
// InitializeWithCertificate initializes the repository with root keys and their
|
||||
// corresponding certificates
|
||||
InitializeWithCertificate(rootKeyIDs []string, rootCerts []data.PublicKey, serverManagedRoles ...data.RoleName) error
|
||||
|
||||
// Publish pushes the local changes in signed material to the remote notary-server
|
||||
// Conceptually it performs an operation similar to a `git rebase`
|
||||
Publish() error
|
||||
|
||||
// ----- Target Operations -----
|
||||
|
||||
// AddTarget creates new changelist entries to add a target to the given roles
|
||||
// in the repository when the changelist gets applied at publish time.
|
||||
// If roles are unspecified, the default role is "targets"
|
||||
AddTarget(target *Target, roles ...data.RoleName) error
|
||||
|
||||
// RemoveTarget creates new changelist entries to remove a target from the given
|
||||
// roles in the repository when the changelist gets applied at publish time.
|
||||
// If roles are unspecified, the default role is "target".
|
||||
RemoveTarget(targetName string, roles ...data.RoleName) error
|
||||
|
||||
// ----- Changelist operations -----
|
||||
|
||||
// GetChangelist returns the list of the repository's unpublished changes
|
||||
GetChangelist() (changelist.Changelist, error)
|
||||
|
||||
// Role operations
|
||||
ListRoles() ([]RoleWithSignatures, error)
|
||||
GetDelegationRoles() ([]data.Role, error)
|
||||
// ----- Role operations -----
|
||||
|
||||
// AddDelegation creates changelist entries to add provided delegation public keys and paths.
|
||||
// This method composes AddDelegationRoleAndKeys and AddDelegationPaths (each creates one changelist if called).
|
||||
AddDelegation(name data.RoleName, delegationKeys []data.PublicKey, paths []string) error
|
||||
|
||||
// AddDelegationRoleAndKeys creates a changelist entry to add provided delegation public keys.
|
||||
// This method is the simplest way to create a new delegation, because the delegation must have at least
|
||||
// one key upon creation to be valid since we will reject the changelist while validating the threshold.
|
||||
AddDelegationRoleAndKeys(name data.RoleName, delegationKeys []data.PublicKey) error
|
||||
|
||||
// AddDelegationPaths creates a changelist entry to add provided paths to an existing delegation.
|
||||
// This method cannot create a new delegation itself because the role must meet the key threshold upon
|
||||
// creation.
|
||||
AddDelegationPaths(name data.RoleName, paths []string) error
|
||||
|
||||
// RemoveDelegationKeysAndPaths creates changelist entries to remove provided delegation key IDs and
|
||||
// paths. This method composes RemoveDelegationPaths and RemoveDelegationKeys (each creates one
|
||||
// changelist entry if called).
|
||||
RemoveDelegationKeysAndPaths(name data.RoleName, keyIDs, paths []string) error
|
||||
|
||||
// RemoveDelegationRole creates a changelist to remove all paths and keys from a role, and delete the
|
||||
// role in its entirety.
|
||||
RemoveDelegationRole(name data.RoleName) error
|
||||
|
||||
// RemoveDelegationPaths creates a changelist entry to remove provided paths from an existing delegation.
|
||||
RemoveDelegationPaths(name data.RoleName, paths []string) error
|
||||
|
||||
// RemoveDelegationKeys creates a changelist entry to remove provided keys from an existing delegation.
|
||||
// When this changelist is applied, if the specified keys are the only keys left in the role,
|
||||
// the role itself will be deleted in its entirety.
|
||||
// It can also delete a key from all delegations under a parent using a name
|
||||
// with a wildcard at the end.
|
||||
RemoveDelegationKeys(name data.RoleName, keyIDs []string) error
|
||||
|
||||
// ClearDelegationPaths creates a changelist entry to remove all paths from an existing delegation.
|
||||
ClearDelegationPaths(name data.RoleName) error
|
||||
|
||||
// Witness and other re-signing operations
|
||||
// ----- Witness and other re-signing operations -----
|
||||
|
||||
// Witness creates change objects to witness (i.e. re-sign) the given
|
||||
// roles on the next publish. One change is created per role
|
||||
Witness(roles ...data.RoleName) ([]data.RoleName, error)
|
||||
|
||||
// Key Operations
|
||||
// ----- Key Operations -----
|
||||
|
||||
// RotateKey removes all existing keys associated with the role. If no keys are
|
||||
// specified in keyList, then this creates and adds one new key or delegates
|
||||
// managing the key to the server. If key(s) are specified by keyList, then they are
|
||||
// used for signing the role.
|
||||
// These changes are staged in a changelist until publish is called.
|
||||
RotateKey(role data.RoleName, serverManagesKey bool, keyList []string) error
|
||||
|
||||
// GetCryptoService is the getter for the repository's CryptoService, which is used
|
||||
// to sign all updates.
|
||||
GetCryptoService() signed.CryptoService
|
||||
SetLegacyVersions(int)
|
||||
GetGUN() data.GUN
|
||||
}
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
canonicaljson "github.com/docker/go/canonical/json"
|
||||
store "github.com/theupdateframework/notary/storage"
|
||||
"github.com/theupdateframework/notary/tuf"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
"github.com/theupdateframework/notary/tuf/utils"
|
||||
)
|
||||
|
||||
// Target represents a simplified version of the data TUF operates on, so external
|
||||
// applications don't have to depend on TUF data types.
|
||||
type Target struct {
|
||||
Name string // the name of the target
|
||||
Hashes data.Hashes // the hash of the target
|
||||
Length int64 // the size in bytes of the target
|
||||
Custom *canonicaljson.RawMessage // the custom data provided to describe the file at TARGETPATH
|
||||
}
|
||||
|
||||
// TargetWithRole represents a Target that exists in a particular role - this is
|
||||
// produced by ListTargets and GetTargetByName
|
||||
type TargetWithRole struct {
|
||||
Target
|
||||
Role data.RoleName
|
||||
}
|
||||
|
||||
// TargetSignedStruct is a struct that contains a Target, the role it was found in, and the list of signatures for that role
|
||||
type TargetSignedStruct struct {
|
||||
Role data.DelegationRole
|
||||
Target Target
|
||||
Signatures []data.Signature
|
||||
}
|
||||
|
||||
//ErrNoSuchTarget is returned when no valid trust data is found.
|
||||
type ErrNoSuchTarget string
|
||||
|
||||
func (f ErrNoSuchTarget) Error() string {
|
||||
return fmt.Sprintf("No valid trust data for %s", string(f))
|
||||
}
|
||||
|
||||
// RoleWithSignatures is a Role with its associated signatures
|
||||
type RoleWithSignatures struct {
|
||||
Signatures []data.Signature
|
||||
data.Role
|
||||
}
|
||||
|
||||
// NewReadOnly is the base method that returns a new notary repository for reading.
|
||||
// It expects an initialized cache. In case of a nil remote store, a default
|
||||
// offline store is used.
|
||||
func NewReadOnly(repo *tuf.Repo) ReadOnly {
|
||||
return &reader{tufRepo: repo}
|
||||
}
|
||||
|
||||
type reader struct {
|
||||
tufRepo *tuf.Repo
|
||||
}
|
||||
|
||||
// ListTargets lists all targets for the current repository. The list of
|
||||
// roles should be passed in order from highest to lowest priority.
|
||||
//
|
||||
// IMPORTANT: if you pass a set of roles such as [ "targets/a", "targets/x"
|
||||
// "targets/a/b" ], even though "targets/a/b" is part of the "targets/a" subtree
|
||||
// its entries will be strictly shadowed by those in other parts of the "targets/a"
|
||||
// subtree and also the "targets/x" subtree, as we will defer parsing it until
|
||||
// we explicitly reach it in our iteration of the provided list of roles.
|
||||
func (r *reader) ListTargets(roles ...data.RoleName) ([]*TargetWithRole, error) {
|
||||
if len(roles) == 0 {
|
||||
roles = []data.RoleName{data.CanonicalTargetsRole}
|
||||
}
|
||||
targets := make(map[string]*TargetWithRole)
|
||||
for _, role := range roles {
|
||||
// Define an array of roles to skip for this walk (see IMPORTANT comment above)
|
||||
skipRoles := utils.RoleNameSliceRemove(roles, role)
|
||||
|
||||
// Define a visitor function to populate the targets map in priority order
|
||||
listVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
// We found targets so we should try to add them to our targets map
|
||||
for targetName, targetMeta := range tgt.Signed.Targets {
|
||||
// Follow the priority by not overriding previously set targets
|
||||
// and check that this path is valid with this role
|
||||
if _, ok := targets[targetName]; ok || !validRole.CheckPaths(targetName) {
|
||||
continue
|
||||
}
|
||||
targets[targetName] = &TargetWithRole{
|
||||
Target: Target{
|
||||
Name: targetName,
|
||||
Hashes: targetMeta.Hashes,
|
||||
Length: targetMeta.Length,
|
||||
Custom: targetMeta.Custom,
|
||||
},
|
||||
Role: validRole.Name,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
r.tufRepo.WalkTargets("", role, listVisitorFunc, skipRoles...)
|
||||
}
|
||||
|
||||
var targetList []*TargetWithRole
|
||||
for _, v := range targets {
|
||||
targetList = append(targetList, v)
|
||||
}
|
||||
|
||||
return targetList, nil
|
||||
}
|
||||
|
||||
// GetTargetByName returns a target by the given name. If no roles are passed
|
||||
// it uses the targets role and does a search of the entire delegation
|
||||
// graph, finding the first entry in a breadth first search of the delegations.
|
||||
// If roles are passed, they should be passed in descending priority and
|
||||
// the target entry found in the subtree of the highest priority role
|
||||
// will be returned.
|
||||
// See the IMPORTANT section on ListTargets above. Those roles also apply here.
|
||||
func (r *reader) GetTargetByName(name string, roles ...data.RoleName) (*TargetWithRole, error) {
|
||||
if len(roles) == 0 {
|
||||
roles = append(roles, data.CanonicalTargetsRole)
|
||||
}
|
||||
var resultMeta data.FileMeta
|
||||
var resultRoleName data.RoleName
|
||||
var foundTarget bool
|
||||
for _, role := range roles {
|
||||
// Define an array of roles to skip for this walk (see IMPORTANT comment above)
|
||||
skipRoles := utils.RoleNameSliceRemove(roles, role)
|
||||
|
||||
// Define a visitor function to find the specified target
|
||||
getTargetVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
if tgt == nil {
|
||||
return nil
|
||||
}
|
||||
// We found the target and validated path compatibility in our walk,
|
||||
// so we should stop our walk and set the resultMeta and resultRoleName variables
|
||||
if resultMeta, foundTarget = tgt.Signed.Targets[name]; foundTarget {
|
||||
resultRoleName = validRole.Name
|
||||
return tuf.StopWalk{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// Check that we didn't error, and that we assigned to our target
|
||||
if err := r.tufRepo.WalkTargets(name, role, getTargetVisitorFunc, skipRoles...); err == nil && foundTarget {
|
||||
return &TargetWithRole{Target: Target{Name: name, Hashes: resultMeta.Hashes, Length: resultMeta.Length, Custom: resultMeta.Custom}, Role: resultRoleName}, nil
|
||||
}
|
||||
}
|
||||
return nil, ErrNoSuchTarget(name)
|
||||
|
||||
}
|
||||
|
||||
// GetAllTargetMetadataByName searches the entire delegation role tree to find the specified target by name for all
|
||||
// roles, and returns a list of TargetSignedStructs for each time it finds the specified target.
|
||||
// If given an empty string for a target name, it will return back all targets signed into the repository in every role
|
||||
func (r *reader) GetAllTargetMetadataByName(name string) ([]TargetSignedStruct, error) {
|
||||
var targetInfoList []TargetSignedStruct
|
||||
|
||||
// Define a visitor function to find the specified target
|
||||
getAllTargetInfoByNameVisitorFunc := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
if tgt == nil {
|
||||
return nil
|
||||
}
|
||||
// We found a target and validated path compatibility in our walk,
|
||||
// so add it to our list if we have a match
|
||||
// if we have an empty name, add all targets, else check if we have it
|
||||
var targetMetaToAdd data.Files
|
||||
if name == "" {
|
||||
targetMetaToAdd = tgt.Signed.Targets
|
||||
} else {
|
||||
if meta, ok := tgt.Signed.Targets[name]; ok {
|
||||
targetMetaToAdd = data.Files{name: meta}
|
||||
}
|
||||
}
|
||||
|
||||
for targetName, resultMeta := range targetMetaToAdd {
|
||||
targetInfo := TargetSignedStruct{
|
||||
Role: validRole,
|
||||
Target: Target{Name: targetName, Hashes: resultMeta.Hashes, Length: resultMeta.Length, Custom: resultMeta.Custom},
|
||||
Signatures: tgt.Signatures,
|
||||
}
|
||||
targetInfoList = append(targetInfoList, targetInfo)
|
||||
}
|
||||
// continue walking to all child roles
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check that we didn't error, and that we found the target at least once
|
||||
if err := r.tufRepo.WalkTargets(name, "", getAllTargetInfoByNameVisitorFunc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(targetInfoList) == 0 {
|
||||
return nil, ErrNoSuchTarget(name)
|
||||
}
|
||||
return targetInfoList, nil
|
||||
}
|
||||
|
||||
// ListRoles returns a list of RoleWithSignatures objects for this repo
|
||||
// This represents the latest metadata for each role in this repo
|
||||
func (r *reader) ListRoles() ([]RoleWithSignatures, error) {
|
||||
// Get all role info from our updated keysDB, can be empty
|
||||
roles := r.tufRepo.GetAllLoadedRoles()
|
||||
|
||||
var roleWithSigs []RoleWithSignatures
|
||||
|
||||
// Populate RoleWithSignatures with Role from keysDB and signatures from TUF metadata
|
||||
for _, role := range roles {
|
||||
roleWithSig := RoleWithSignatures{Role: *role, Signatures: nil}
|
||||
switch role.Name {
|
||||
case data.CanonicalRootRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Root.Signatures
|
||||
case data.CanonicalTargetsRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Targets[data.CanonicalTargetsRole].Signatures
|
||||
case data.CanonicalSnapshotRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Snapshot.Signatures
|
||||
case data.CanonicalTimestampRole:
|
||||
roleWithSig.Signatures = r.tufRepo.Timestamp.Signatures
|
||||
default:
|
||||
if !data.IsDelegation(role.Name) {
|
||||
continue
|
||||
}
|
||||
if _, ok := r.tufRepo.Targets[role.Name]; ok {
|
||||
// We'll only find a signature if we've published any targets with this delegation
|
||||
roleWithSig.Signatures = r.tufRepo.Targets[role.Name].Signatures
|
||||
}
|
||||
}
|
||||
roleWithSigs = append(roleWithSigs, roleWithSig)
|
||||
}
|
||||
return roleWithSigs, nil
|
||||
}
|
||||
|
||||
// GetDelegationRoles returns the keys and roles of the repository's delegations
|
||||
// Also converts key IDs to canonical key IDs to keep consistent with signing prompts
|
||||
func (r *reader) GetDelegationRoles() ([]data.Role, error) {
|
||||
// All top level delegations (ex: targets/level1) are stored exclusively in targets.json
|
||||
_, ok := r.tufRepo.Targets[data.CanonicalTargetsRole]
|
||||
if !ok {
|
||||
return nil, store.ErrMetaNotFound{Resource: data.CanonicalTargetsRole.String()}
|
||||
}
|
||||
|
||||
// make a copy for traversing nested delegations
|
||||
allDelegations := []data.Role{}
|
||||
|
||||
// Define a visitor function to populate the delegations list and translate their key IDs to canonical IDs
|
||||
delegationCanonicalListVisitor := func(tgt *data.SignedTargets, validRole data.DelegationRole) interface{} {
|
||||
// For the return list, update with a copy that includes canonicalKeyIDs
|
||||
// These aren't validated by the validRole
|
||||
canonicalDelegations, err := translateDelegationsToCanonicalIDs(tgt.Signed.Delegations)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allDelegations = append(allDelegations, canonicalDelegations...)
|
||||
return nil
|
||||
}
|
||||
err := r.tufRepo.WalkTargets("", "", delegationCanonicalListVisitor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return allDelegations, nil
|
||||
}
|
|
@ -3,9 +3,11 @@ package client
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/cryptoservice"
|
||||
store "github.com/theupdateframework/notary/storage"
|
||||
"github.com/theupdateframework/notary/trustpinning"
|
||||
"github.com/theupdateframework/notary/tuf"
|
||||
|
@ -21,16 +23,6 @@ type tufClient struct {
|
|||
newBuilder tuf.RepoBuilder
|
||||
}
|
||||
|
||||
// newTufClient initialized a tufClient with the given repo, remote source of content, and cache
|
||||
func newTufClient(oldBuilder, newBuilder tuf.RepoBuilder, remote store.RemoteStore, cache store.MetadataStore) *tufClient {
|
||||
return &tufClient{
|
||||
oldBuilder: oldBuilder,
|
||||
newBuilder: newBuilder,
|
||||
remote: remote,
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
||||
// Update performs an update to the TUF repo as defined by the TUF spec
|
||||
func (c *tufClient) Update() (*tuf.Repo, *tuf.Repo, error) {
|
||||
// 1. Get timestamp
|
||||
|
@ -139,7 +131,7 @@ func (c *tufClient) updateRoot() error {
|
|||
|
||||
// Write newest to cache
|
||||
if err := c.cache.Set(data.CanonicalRootRole.String(), raw); err != nil {
|
||||
logrus.Debugf("unable to write %s to cache: %d.%s", newestVersion, data.CanonicalRootRole, err)
|
||||
logrus.Debugf("unable to write %d.%s to cache: %s", newestVersion, data.CanonicalRootRole, err)
|
||||
}
|
||||
logrus.Debugf("finished updating root files")
|
||||
return nil
|
||||
|
@ -241,7 +233,6 @@ func (c *tufClient) downloadTargets() error {
|
|||
return err
|
||||
}
|
||||
logrus.Warnf("Error getting %s: %s", role.Name, err)
|
||||
break
|
||||
case nil:
|
||||
toDownload = append(children, toDownload...)
|
||||
default:
|
||||
|
@ -323,3 +314,149 @@ func (c *tufClient) tryLoadRemote(consistentInfo tuf.ConsistentInfo, old []byte)
|
|||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
// TUFLoadOptions are provided to LoadTUFRepo, which loads a TUF repo from cache,
|
||||
// from a remote store, or both
|
||||
type TUFLoadOptions struct {
|
||||
GUN data.GUN
|
||||
TrustPinning trustpinning.TrustPinConfig
|
||||
CryptoService signed.CryptoService
|
||||
Cache store.MetadataStore
|
||||
RemoteStore store.RemoteStore
|
||||
AlwaysCheckInitialized bool
|
||||
}
|
||||
|
||||
// bootstrapClient attempts to bootstrap a root.json to be used as the trust
|
||||
// anchor for a repository. The checkInitialized argument indicates whether
|
||||
// we should always attempt to contact the server to determine if the repository
|
||||
// is initialized or not. If set to true, we will always attempt to download
|
||||
// and return an error if the remote repository errors.
|
||||
//
|
||||
// Populates a tuf.RepoBuilder with this root metadata. If the root metadata
|
||||
// downloaded is a newer version than what is on disk, then intermediate
|
||||
// versions will be downloaded and verified in order to rotate trusted keys
|
||||
// properly. Newer root metadata must always be signed with the previous
|
||||
// threshold and keys.
|
||||
//
|
||||
// Fails if the remote server is reachable and does not know the repo
|
||||
// (i.e. before any metadata has been published), in which case the error is
|
||||
// store.ErrMetaNotFound, or if the root metadata (from whichever source is used)
|
||||
// is not trusted.
|
||||
//
|
||||
// Returns a TUFClient for the remote server, which may not be actually
|
||||
// operational (if the URL is invalid but a root.json is cached).
|
||||
func bootstrapClient(l TUFLoadOptions) (*tufClient, error) {
|
||||
minVersion := 1
|
||||
// the old root on disk should not be validated against any trust pinning configuration
|
||||
// because if we have an old root, it itself is the thing that pins trust
|
||||
oldBuilder := tuf.NewRepoBuilder(l.GUN, l.CryptoService, trustpinning.TrustPinConfig{})
|
||||
|
||||
// by default, we want to use the trust pinning configuration on any new root that we download
|
||||
newBuilder := tuf.NewRepoBuilder(l.GUN, l.CryptoService, l.TrustPinning)
|
||||
|
||||
// Try to read root from cache first. We will trust this root until we detect a problem
|
||||
// during update which will cause us to download a new root and perform a rotation.
|
||||
// If we have an old root, and it's valid, then we overwrite the newBuilder to be one
|
||||
// preloaded with the old root or one which uses the old root for trust bootstrapping.
|
||||
if rootJSON, err := l.Cache.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit); err == nil {
|
||||
// if we can't load the cached root, fail hard because that is how we pin trust
|
||||
if err := oldBuilder.Load(data.CanonicalRootRole, rootJSON, minVersion, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// again, the root on disk is the source of trust pinning, so use an empty trust
|
||||
// pinning configuration
|
||||
newBuilder = tuf.NewRepoBuilder(l.GUN, l.CryptoService, trustpinning.TrustPinConfig{})
|
||||
|
||||
if err := newBuilder.Load(data.CanonicalRootRole, rootJSON, minVersion, false); err != nil {
|
||||
// Ok, the old root is expired - we want to download a new one. But we want to use the
|
||||
// old root to verify the new root, so bootstrap a new builder with the old builder
|
||||
// but use the trustpinning to validate the new root
|
||||
minVersion = oldBuilder.GetLoadedVersion(data.CanonicalRootRole)
|
||||
newBuilder = oldBuilder.BootstrapNewBuilderWithNewTrustpin(l.TrustPinning)
|
||||
}
|
||||
}
|
||||
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) || l.AlwaysCheckInitialized {
|
||||
// remoteErr was nil and we were not able to load a root from cache or
|
||||
// are specifically checking for initialization of the repo.
|
||||
|
||||
// if remote store successfully set up, try and get root from remote
|
||||
// We don't have any local data to determine the size of root, so try the maximum (though it is restricted at 100MB)
|
||||
tmpJSON, err := l.RemoteStore.GetSized(data.CanonicalRootRole.String(), store.NoSizeLimit)
|
||||
if err != nil {
|
||||
// we didn't have a root in cache and were unable to load one from
|
||||
// the server. Nothing we can do but error.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) {
|
||||
// we always want to use the downloaded root if we couldn't load from cache
|
||||
if err := newBuilder.Load(data.CanonicalRootRole, tmpJSON, minVersion, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = l.Cache.Set(data.CanonicalRootRole.String(), tmpJSON)
|
||||
if err != nil {
|
||||
// if we can't write cache we should still continue, just log error
|
||||
logrus.Errorf("could not save root to cache: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We can only get here if remoteErr != nil (hence we don't download any new root),
|
||||
// and there was no root on disk
|
||||
if !newBuilder.IsLoaded(data.CanonicalRootRole) {
|
||||
return nil, ErrRepoNotInitialized{}
|
||||
}
|
||||
|
||||
return &tufClient{
|
||||
oldBuilder: oldBuilder,
|
||||
newBuilder: newBuilder,
|
||||
remote: l.RemoteStore,
|
||||
cache: l.Cache,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LoadTUFRepo bootstraps a trust anchor (root.json) from cache (if provided) before updating
|
||||
// all the metadata for the repo from the remote (if provided). It loads a TUF repo from cache,
|
||||
// from a remote store, or both.
|
||||
func LoadTUFRepo(options TUFLoadOptions) (*tuf.Repo, *tuf.Repo, error) {
|
||||
// set some sane defaults, so nothing has to be provided necessarily
|
||||
if options.RemoteStore == nil {
|
||||
options.RemoteStore = store.OfflineStore{}
|
||||
}
|
||||
if options.Cache == nil {
|
||||
options.Cache = store.NewMemoryStore(nil)
|
||||
}
|
||||
if options.CryptoService == nil {
|
||||
options.CryptoService = cryptoservice.EmptyService
|
||||
}
|
||||
|
||||
c, err := bootstrapClient(options)
|
||||
if err != nil {
|
||||
if _, ok := err.(store.ErrMetaNotFound); ok {
|
||||
return nil, nil, ErrRepositoryNotExist{
|
||||
remote: options.RemoteStore.Location(),
|
||||
gun: options.GUN,
|
||||
}
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
repo, invalid, err := c.Update()
|
||||
if err != nil {
|
||||
// notFound.Resource may include a version or checksum so when the role is root,
|
||||
// it will be root, <version>.root or root.<checksum>.
|
||||
notFound, ok := err.(store.ErrMetaNotFound)
|
||||
isRoot, _ := regexp.MatchString(`\.?`+data.CanonicalRootRole.String()+`\.?`, notFound.Resource)
|
||||
if ok && isRoot {
|
||||
return nil, nil, ErrRepositoryNotExist{
|
||||
remote: options.RemoteStore.Location(),
|
||||
gun: options.GUN,
|
||||
}
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
warnRolesNearExpiry(repo)
|
||||
return repo, invalid, nil
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@ func init() {
|
|||
"config.toml",
|
||||
"path to configuration file; supported formats are JSON, YAML, and TOML",
|
||||
)
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
v, err := parseConfig(configPath)
|
||||
if err != nil {
|
||||
logrus.Fatalf("could not parse config file (%s): %s", configPath, err)
|
||||
|
|
|
@ -25,7 +25,7 @@ import (
|
|||
"github.com/theupdateframework/notary/tuf/signed"
|
||||
"github.com/theupdateframework/notary/utils"
|
||||
"golang.org/x/net/context"
|
||||
"gopkg.in/dancannon/gorethink.v3"
|
||||
gorethink "gopkg.in/rethinkdb/rethinkdb-go.v6"
|
||||
)
|
||||
|
||||
// gets the required gun prefixes accepted by this server
|
||||
|
@ -74,7 +74,7 @@ func grpcTLS(configuration *viper.Viper) (*tls.Config, error) {
|
|||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Unable to configure TLS to the trust service: %s", err.Error())
|
||||
"unable to configure TLS to the trust service: %s", err.Error())
|
||||
}
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ func getStore(configuration *viper.Viper, hRegister healthRegister, doBootstrap
|
|||
}
|
||||
s, err := storage.NewSQLStorage(storeConfig.Backend, storeConfig.Source)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error())
|
||||
return nil, fmt.Errorf("error starting %s driver: %s", backend, err.Error())
|
||||
}
|
||||
store = *storage.NewTUFMetaStorage(s)
|
||||
hRegister("DB operational", 10*time.Second, s.CheckHealth)
|
||||
|
@ -118,7 +118,7 @@ func getStore(configuration *viper.Viper, hRegister healthRegister, doBootstrap
|
|||
sess, err = rethinkdb.UserConnection(tlsOpts, storeConfig.Source, storeConfig.Username, storeConfig.Password)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error())
|
||||
return nil, fmt.Errorf("error starting %s driver: %s", backend, err.Error())
|
||||
}
|
||||
s := storage.NewRethinkDBStorage(storeConfig.DBName, storeConfig.Username, storeConfig.Password, sess)
|
||||
store = *storage.NewTUFMetaStorage(s)
|
||||
|
|
|
@ -5,9 +5,10 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
_ "net/http/pprof" // #nosec G108 // false positive as it's only listening through debugServer()
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -28,6 +29,7 @@ type cmdFlags struct {
|
|||
logFormat string
|
||||
configFile string
|
||||
doBootstrap bool
|
||||
version bool
|
||||
}
|
||||
|
||||
func setupFlags(flagStorage *cmdFlags) {
|
||||
|
@ -36,6 +38,7 @@ func setupFlags(flagStorage *cmdFlags) {
|
|||
flag.BoolVar(&flagStorage.debug, "debug", false, "Enable the debugging server on localhost:8080")
|
||||
flag.StringVar(&flagStorage.logFormat, "logf", "json", "Set the format of the logs. Only 'json' and 'logfmt' are supported at the moment.")
|
||||
flag.BoolVar(&flagStorage.doBootstrap, "bootstrap", false, "Do any necessary setup of configured backend storage services")
|
||||
flag.BoolVar(&flagStorage.version, "version", false, "Print the version number of notary-server")
|
||||
|
||||
// this needs to be in init so that _ALL_ logs are in the correct format
|
||||
if flagStorage.logFormat == jsonLogFormat {
|
||||
|
@ -51,12 +54,17 @@ func main() {
|
|||
|
||||
flag.Parse()
|
||||
|
||||
if flagStorage.version {
|
||||
fmt.Println("notary-server " + getVersion())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if flagStorage.debug {
|
||||
go debugServer(DebugAddress)
|
||||
}
|
||||
|
||||
// when the server starts print the version for debugging and issue logs later
|
||||
logrus.Infof("Version: %s, Git commit: %s", version.NotaryVersion, version.GitCommit)
|
||||
logrus.Info(getVersion())
|
||||
|
||||
ctx, serverConfig, err := parseServerConfig(flagStorage.configFile, health.RegisterPeriodicFunc, flagStorage.doBootstrap)
|
||||
if err != nil {
|
||||
|
@ -78,7 +86,6 @@ func main() {
|
|||
if err != nil {
|
||||
logrus.Fatal(err.Error())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func usage() {
|
||||
|
@ -86,6 +93,10 @@ func usage() {
|
|||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
func getVersion() string {
|
||||
return fmt.Sprintf("Version: %s, Git commit: %s, Go version: %s", version.NotaryVersion, version.GitCommit, runtime.Version())
|
||||
}
|
||||
|
||||
// debugServer starts the debug server with pprof, expvar among other
|
||||
// endpoints. The addr should not be exposed externally. For most of these to
|
||||
// work, tls cannot be enabled on the endpoint, so it is generally separate.
|
||||
|
|
|
@ -279,7 +279,7 @@ func TestGetTrustServiceTLSFailure(t *testing.T) {
|
|||
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(),
|
||||
"Unable to configure TLS to the trust service"))
|
||||
"unable to configure TLS to the trust service"))
|
||||
|
||||
// no health function ever registered
|
||||
require.Equal(t, 0, registerCalled)
|
||||
|
@ -380,9 +380,9 @@ func TestGetCacheConfig(t *testing.T) {
|
|||
|
||||
func TestGetGUNPRefixes(t *testing.T) {
|
||||
valids := map[string][]string{
|
||||
`{}`: nil,
|
||||
`{"repositories": {"gun_prefixes": []}}`: nil,
|
||||
`{"repositories": {}}`: nil,
|
||||
`{}`: nil,
|
||||
`{"repositories": {"gun_prefixes": []}}`: nil,
|
||||
`{"repositories": {}}`: nil,
|
||||
`{"repositories": {"gun_prefixes": ["hello/"]}}`: {"hello/"},
|
||||
}
|
||||
invalids := []string{
|
||||
|
|
|
@ -32,7 +32,7 @@ import (
|
|||
"github.com/theupdateframework/notary/utils"
|
||||
ghealth "google.golang.org/grpc/health"
|
||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||
"gopkg.in/dancannon/gorethink.v3"
|
||||
gorethink "gopkg.in/rethinkdb/rethinkdb-go.v6"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -135,7 +135,7 @@ func setUpCryptoservices(configuration *viper.Viper, allowedBackends []string, d
|
|||
sess, err = rethinkdb.UserConnection(tlsOpts, storeConfig.Source, storeConfig.Username, storeConfig.Password)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error())
|
||||
return nil, fmt.Errorf("error starting %s driver: %w", backend, err)
|
||||
}
|
||||
s := keydbstore.NewRethinkDBKeyStore(storeConfig.DBName, storeConfig.Username, storeConfig.Password, passphraseRetriever, defaultAlias, sess)
|
||||
health.RegisterPeriodicFunc("DB operational", time.Minute, s.CheckHealth)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func protect() error {
|
||||
// Make sure process is not dumpable, so will not core dump, which would
|
||||
// write keys to disk, and cannot be ptraced to read keys.
|
||||
return unix.Prctl(unix.PR_SET_DUMPABLE, 0, 0, 0, 0)
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// +build !linux
|
||||
|
||||
package main
|
||||
|
||||
func protect() error {
|
||||
return nil
|
||||
}
|
|
@ -3,10 +3,12 @@ package main
|
|||
import (
|
||||
_ "expvar"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
|
@ -25,14 +27,16 @@ type cmdFlags struct {
|
|||
logFormat string
|
||||
configFile string
|
||||
doBootstrap bool
|
||||
version bool
|
||||
}
|
||||
|
||||
func setupFlags(flagStorage *cmdFlags) {
|
||||
// Setup flags
|
||||
flag.StringVar(&flagStorage.configFile, "config", "", "Path to configuration file")
|
||||
flag.BoolVar(&flagStorage.debug, "debug", false, "Show the version and exit")
|
||||
flag.BoolVar(&flagStorage.debug, "debug", false, "Run in debug mode, enables Go debug server")
|
||||
flag.StringVar(&flagStorage.logFormat, "logf", "json", "Set the format of the logs. Only 'json' and 'logfmt' are supported at the moment.")
|
||||
flag.BoolVar(&flagStorage.doBootstrap, "bootstrap", false, "Do any necessary setup of configured backend storage services")
|
||||
flag.BoolVar(&flagStorage.version, "version", false, "Print the version number of notary-signer")
|
||||
|
||||
// this needs to be in init so that _ALL_ logs are in the correct format
|
||||
if flagStorage.logFormat == jsonLogFormat {
|
||||
|
@ -48,12 +52,22 @@ func main() {
|
|||
|
||||
flag.Parse()
|
||||
|
||||
if flagStorage.version {
|
||||
fmt.Println("notary-signer " + getVersion())
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if flagStorage.debug {
|
||||
go debugServer(debugAddr)
|
||||
} else {
|
||||
// If not in debug mode, stop tracing, core dumps if supported to help protect keys.
|
||||
if err := protect(); err != nil {
|
||||
logrus.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// when the signer starts print the version for debugging and issue logs later
|
||||
logrus.Infof("Version: %s, Git commit: %s", version.NotaryVersion, version.GitCommit)
|
||||
logrus.Info(getVersion())
|
||||
|
||||
signerConfig, err := parseSignerConfig(flagStorage.configFile, flagStorage.doBootstrap)
|
||||
if err != nil {
|
||||
|
@ -82,6 +96,10 @@ func usage() {
|
|||
flag.PrintDefaults()
|
||||
}
|
||||
|
||||
func getVersion() string {
|
||||
return fmt.Sprintf("Version: %s, Git commit: %s, Go version: %s", version.NotaryVersion, version.GitCommit, runtime.Version())
|
||||
}
|
||||
|
||||
// debugServer starts the debug server with pprof, expvar among other
|
||||
// endpoints. The addr should not be exposed externally. For most of these to
|
||||
// work, tls cannot be enabled on the endpoint, so it is generally separate.
|
||||
|
|
|
@ -83,12 +83,12 @@ func (d *delegationCommander) GetCommand() *cobra.Command {
|
|||
func (d *delegationCommander) delegationPurgeKeys(cmd *cobra.Command, args []string) error {
|
||||
if len(args) != 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Please provide a single Global Unique Name as an argument to remove")
|
||||
return fmt.Errorf("please provide a single Global Unique Name as an argument to remove")
|
||||
}
|
||||
|
||||
if len(d.keyIDs) == 0 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Please provide at least one key ID to be removed using the --key flag")
|
||||
return fmt.Errorf("please provide at least one key ID to be removed using the --key flag")
|
||||
}
|
||||
|
||||
gun := data.GUN(args[0])
|
||||
|
@ -132,7 +132,7 @@ func (d *delegationCommander) delegationsList(cmd *cobra.Command, args []string)
|
|||
if len(args) != 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf(
|
||||
"Please provide a Global Unique Name as an argument to list")
|
||||
"please provide a Global Unique Name as an argument to list")
|
||||
}
|
||||
|
||||
config, err := d.configGetter()
|
||||
|
@ -161,7 +161,7 @@ func (d *delegationCommander) delegationsList(cmd *cobra.Command, args []string)
|
|||
|
||||
delegationRoles, err := nRepo.GetDelegationRoles()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error retrieving delegation roles for repository %s: %v", gun, err)
|
||||
return fmt.Errorf("error retrieving delegation roles for repository %s: %w", gun, err)
|
||||
}
|
||||
|
||||
cmd.Println("")
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"crypto/sha512"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -416,7 +417,7 @@ func TestClientTUFInteraction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Contains(t, output, target2)
|
||||
|
||||
// Check the file this was written to to inspect metadata
|
||||
// Check the file this was written to inspect metadata
|
||||
cache, err := nstorage.NewFileStore(
|
||||
filepath.Join(tempDir, "tuf", filepath.FromSlash("gun"), "metadata"),
|
||||
"json",
|
||||
|
@ -762,7 +763,7 @@ func TestClientTUFAddByHashInteraction(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Contains(t, output, target4)
|
||||
|
||||
// Check the file this was written to to inspect metadata
|
||||
// Check the file this was written to inspect metadata
|
||||
cache, err := nstorage.NewFileStore(
|
||||
filepath.Join(tempDir, "tuf", filepath.FromSlash("gun"), "metadata"),
|
||||
"json",
|
||||
|
@ -1802,6 +1803,7 @@ func tempDirWithConfig(t *testing.T, config string) string {
|
|||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
if testing.Short() {
|
||||
// skip
|
||||
os.Exit(0)
|
||||
|
@ -2576,7 +2578,7 @@ func TestClientKeyImport(t *testing.T) {
|
|||
// if there is hardware available, root will only be on hardware, and not
|
||||
// on disk
|
||||
assertNumKeys(t, tempDir, 2, 1, !rootOnHardware())
|
||||
file, err := os.OpenFile(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
file, err := os.Open(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"))
|
||||
require.NoError(t, err)
|
||||
filebytes, _ := ioutil.ReadAll(file)
|
||||
require.Contains(t, string(filebytes), ("role: " + notary.DefaultImportRole))
|
||||
|
@ -2606,7 +2608,7 @@ func TestClientKeyImport(t *testing.T) {
|
|||
// if there is hardware available, root will only be on hardware, and not
|
||||
// on disk
|
||||
assertNumKeys(t, tempDir, 2, 2, !rootOnHardware())
|
||||
file, err = os.OpenFile(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
file, err = os.Open(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"))
|
||||
require.NoError(t, err)
|
||||
filebytes, _ = ioutil.ReadAll(file)
|
||||
require.Contains(t, string(filebytes), ("role: " + "somerole"))
|
||||
|
@ -2637,7 +2639,7 @@ func TestClientKeyImport(t *testing.T) {
|
|||
// if there is hardware available, root will only be on hardware, and not
|
||||
// on disk
|
||||
assertNumKeys(t, tempDir, 2, 3, !rootOnHardware())
|
||||
file, err = os.OpenFile(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
file, err = os.Open(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"))
|
||||
require.NoError(t, err)
|
||||
filebytes, _ = ioutil.ReadAll(file)
|
||||
require.Contains(t, string(filebytes), ("role: " + data.CanonicalSnapshotRole.String()))
|
||||
|
@ -2694,7 +2696,7 @@ func TestClientKeyImport(t *testing.T) {
|
|||
// if there is hardware available, root will only be on hardware, and not
|
||||
// on disk
|
||||
assertNumKeys(t, tempDir, 2, 4, !rootOnHardware())
|
||||
file, err = os.OpenFile(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
file, err = os.Open(filepath.Join(tempDir, notary.PrivDir, privKey.ID()+".key"))
|
||||
require.NoError(t, err)
|
||||
filebytes, _ = ioutil.ReadAll(file)
|
||||
require.Contains(t, string(filebytes), ("role: " + "somerole"))
|
||||
|
@ -2918,7 +2920,7 @@ func TestExportImportFlow(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// make sure the export has been done properly
|
||||
from, err := os.OpenFile(filepath.Join(tempDir, "exported"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
from, err := os.Open(filepath.Join(tempDir, "exported"))
|
||||
require.NoError(t, err)
|
||||
defer from.Close()
|
||||
fromBytes, _ := ioutil.ReadAll(from)
|
||||
|
@ -2929,7 +2931,7 @@ func TestExportImportFlow(t *testing.T) {
|
|||
|
||||
// now setup new filestore
|
||||
newTempDir := tempDirWithConfig(t, "{}")
|
||||
defer os.Remove(newTempDir)
|
||||
defer os.RemoveAll(newTempDir)
|
||||
|
||||
// and new server
|
||||
newServer := setupServer()
|
||||
|
@ -2957,7 +2959,7 @@ func TestExportImportFlow(t *testing.T) {
|
|||
|
||||
if !rootOnHardware() {
|
||||
// validate root is imported correctly
|
||||
rootKey, err := os.OpenFile(filepath.Join(newTempDir, notary.PrivDir, root[0]+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
rootKey, err := os.Open(filepath.Join(newTempDir, notary.PrivDir, root[0]+".key"))
|
||||
require.NoError(t, err)
|
||||
defer rootKey.Close()
|
||||
rootBytes, _ := ioutil.ReadAll(rootKey)
|
||||
|
@ -2968,7 +2970,7 @@ func TestExportImportFlow(t *testing.T) {
|
|||
}
|
||||
|
||||
// validate snapshot is imported correctly
|
||||
snapKey, err := os.OpenFile(filepath.Join(newTempDir, notary.PrivDir, signing[0]+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
snapKey, err := os.Open(filepath.Join(newTempDir, notary.PrivDir, signing[0]+".key"))
|
||||
require.NoError(t, err)
|
||||
defer snapKey.Close()
|
||||
snapBytes, _ := ioutil.ReadAll(snapKey)
|
||||
|
@ -2977,7 +2979,7 @@ func TestExportImportFlow(t *testing.T) {
|
|||
require.True(t, strings.Contains(snapString, "role: snapshot") || strings.Contains(snapString, "role: target"))
|
||||
|
||||
// validate targets is imported correctly
|
||||
targKey, err := os.OpenFile(filepath.Join(newTempDir, notary.PrivDir, signing[1]+".key"), os.O_RDONLY, notary.PrivExecPerms)
|
||||
targKey, err := os.Open(filepath.Join(newTempDir, notary.PrivDir, signing[1]+".key"))
|
||||
require.NoError(t, err)
|
||||
defer targKey.Close()
|
||||
targBytes, _ := ioutil.ReadAll(targKey)
|
||||
|
@ -2995,10 +2997,10 @@ func TestDelegationKeyImportExport(t *testing.T) {
|
|||
defer os.RemoveAll(tempDir)
|
||||
|
||||
tempExportedDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempDir)
|
||||
defer os.RemoveAll(tempExportedDir)
|
||||
|
||||
tempImportingDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempDir)
|
||||
defer os.RemoveAll(tempImportingDir)
|
||||
|
||||
// Setup key in a file for import
|
||||
keyFile, err := ioutil.TempFile("", "pemfile")
|
||||
|
|
|
@ -70,7 +70,7 @@ var cmdKeyPasswdTemplate = usageTemplate{
|
|||
var cmdKeyImportTemplate = usageTemplate{
|
||||
Use: "import pemfile [ pemfile ... ]",
|
||||
Short: "Imports all keys from all provided .pem files",
|
||||
Long: "Imports all keys from all provided .pem files by reading each PEM block from the file and writing that block to a unique object in the local keystore. A Yubikey will be the prefferred import location for root keys if present.",
|
||||
Long: "Imports all keys from all provided .pem files by reading each PEM block from the file and writing that block to a unique object in the local keystore. A Yubikey will be the preferred import location for root keys if present.",
|
||||
}
|
||||
|
||||
var cmdKeyExportTemplate = usageTemplate{
|
||||
|
@ -188,7 +188,7 @@ func (k *keyCommander) keysGenerate(cmd *cobra.Command, args []string) error {
|
|||
if len(args) > 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf(
|
||||
"Please provide only one Algorithm as an argument to generate (rsa, ecdsa)")
|
||||
"please provide only one Algorithm as an argument to generate (rsa, ecdsa)")
|
||||
}
|
||||
|
||||
// If no param is given to generate, generates an ecdsa key by default
|
||||
|
@ -196,15 +196,15 @@ func (k *keyCommander) keysGenerate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
// If we were provided an argument lets attempt to use it as an algorithm
|
||||
if len(args) > 0 {
|
||||
algorithm = args[0]
|
||||
algorithm = strings.ToLower(args[0])
|
||||
}
|
||||
|
||||
allowedCiphers := map[string]bool{
|
||||
data.ECDSAKey: true,
|
||||
}
|
||||
|
||||
if !allowedCiphers[strings.ToLower(algorithm)] {
|
||||
return fmt.Errorf("Algorithm not allowed, possible values are: ECDSA")
|
||||
if !allowedCiphers[algorithm] {
|
||||
return fmt.Errorf("algorithm not allowed, possible values are: ECDSA")
|
||||
}
|
||||
|
||||
config, err := k.configGetter()
|
||||
|
@ -222,7 +222,7 @@ func (k *keyCommander) keysGenerate(cmd *cobra.Command, args []string) error {
|
|||
|
||||
pubKey, err := cs.Create(data.RoleName(k.generateRole), "", algorithm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create a new %s key: %v", k.generateRole, err)
|
||||
return fmt.Errorf("failed to create a new %s key: %v", k.generateRole, err)
|
||||
}
|
||||
|
||||
cmd.Printf("Generated new %s %s key with keyID: %s\n", algorithm, k.generateRole, pubKey.ID())
|
||||
|
@ -288,7 +288,7 @@ func generateKeyToFile(role, algorithm string, retriever notary.PassRetriever, o
|
|||
func (k *keyCommander) keysRotate(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN and a key role to rotate")
|
||||
return fmt.Errorf("must specify a GUN and a key role to rotate")
|
||||
}
|
||||
|
||||
config, err := k.configGetter()
|
||||
|
@ -325,7 +325,7 @@ func (k *keyCommander) keysRotate(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
err = nRepo.GetCryptoService().AddKey(rotateKeyRole, gun, privKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error importing key: %v", err)
|
||||
return fmt.Errorf("error importing key: %v", err)
|
||||
}
|
||||
keyList = append(keyList, privKey.ID())
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ func removeKeyInteractively(keyStores []trustmanager.KeyStore, keyID string,
|
|||
}
|
||||
|
||||
if len(foundKeys) == 0 {
|
||||
return fmt.Errorf("No key with ID %s found", keyID)
|
||||
return fmt.Errorf("no key with ID %s found", keyID)
|
||||
}
|
||||
|
||||
if len(foundKeys) > 1 {
|
||||
|
@ -518,11 +518,13 @@ func (k *keyCommander) importKeys(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
for _, file := range args {
|
||||
from, err := os.OpenFile(file, os.O_RDONLY, notary.PrivExecPerms)
|
||||
from, err := os.Open(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer from.Close()
|
||||
defer func() {
|
||||
_ = from.Close()
|
||||
}()
|
||||
if err = trustmanager.ImportKeys(from, importers, k.importRole, k.keysImportGUN, k.getRetriever()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -547,11 +549,13 @@ func (k *keyCommander) exportKeys(cmd *cobra.Command, args []string) error {
|
|||
if k.outFile == "" {
|
||||
out = cmd.OutOrStdout()
|
||||
} else {
|
||||
f, err := os.OpenFile(k.outFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, notary.PrivExecPerms)
|
||||
f, err := os.OpenFile(k.outFile, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, notary.PrivNoExecPerms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
defer func() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
out = f
|
||||
}
|
||||
|
||||
|
@ -562,7 +566,7 @@ func (k *keyCommander) exportKeys(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
if len(k.exportGUNs) > 0 {
|
||||
if len(k.exportKeyIDs) > 0 {
|
||||
return fmt.Errorf("Only the --gun or --key flag may be provided, not a mix of the two flags")
|
||||
return fmt.Errorf("only the --gun or --key flag may be provided, not a mix of the two flags")
|
||||
}
|
||||
for _, gun := range k.exportGUNs {
|
||||
return trustmanager.ExportKeysByGUN(out, fileStore, gun)
|
||||
|
@ -590,7 +594,7 @@ func (k *keyCommander) getKeyStores(
|
|||
fileKeyStore, err := trustmanager.NewKeyFileStore(directory, retriever)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(
|
||||
"Failed to create private key store in directory: %s", directory)
|
||||
"failed to create private key store in directory: %s", directory)
|
||||
}
|
||||
|
||||
ks := []trustmanager.KeyStore{fileKeyStore}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !pkcs11
|
||||
// +build !pkcs11
|
||||
|
||||
package main
|
||||
|
@ -11,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func getYubiStore(fileKeyStore trustmanager.KeyStore, ret notary.PassRetriever) (trustmanager.KeyStore, error) {
|
||||
return nil, errors.New("Not built with hardware support")
|
||||
return nil, errors.New("not built with hardware support")
|
||||
}
|
||||
|
||||
func getImporters(baseDir string, _ notary.PassRetriever) ([]trustmanager.Importer, error) {
|
||||
|
|
|
@ -43,7 +43,7 @@ func TestRemoveIfNoKey(t *testing.T) {
|
|||
stores := []trustmanager.KeyStore{trustmanager.NewKeyMemoryStore(nil)}
|
||||
err := removeKeyInteractively(stores, "12345", &buf, &buf)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "No key with ID")
|
||||
require.Contains(t, err.Error(), "no key with ID")
|
||||
}
|
||||
|
||||
// If there is one key, asking to remove it will ask for confirmation. Passing
|
||||
|
@ -309,7 +309,7 @@ func TestRotateKeyNoGUN(t *testing.T) {
|
|||
}
|
||||
err := k.keysRotate(&cobra.Command{}, []string{})
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "Must specify a GUN")
|
||||
require.Contains(t, err.Error(), "must specify a GUN")
|
||||
}
|
||||
|
||||
// initialize a repo with keys, so they can be rotated
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -62,6 +62,7 @@ type notaryCommander struct {
|
|||
// these are for command line parsing - no need to set
|
||||
debug bool
|
||||
verbose bool
|
||||
version bool
|
||||
trustDir string
|
||||
configFile string
|
||||
remoteTrustServer string
|
||||
|
@ -75,12 +76,11 @@ func (n *notaryCommander) parseConfig() (*viper.Viper, error) {
|
|||
n.setVerbosityLevel()
|
||||
|
||||
// Get home directory for current user
|
||||
homeDir, err := homedir.Dir()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot get current user home directory: %v", err)
|
||||
}
|
||||
homeDir := os.Getenv(homeEnv)
|
||||
if homeDir == "" {
|
||||
return nil, fmt.Errorf("cannot get current user home directory")
|
||||
logrus.Warn("cannot get current user home directory: environment variable not set")
|
||||
pwd, _ := os.Getwd()
|
||||
logrus.Warnf("notary will use %s to store configuration and keys", filepath.Join(pwd, configDir))
|
||||
}
|
||||
|
||||
config := viper.New()
|
||||
|
@ -130,11 +130,9 @@ func (n *notaryCommander) parseConfig() (*viper.Viper, error) {
|
|||
}
|
||||
|
||||
// Expands all the possible ~/ that have been given, either through -d or config
|
||||
// If there is no error, use it, if not, just attempt to use whatever the user gave us
|
||||
expandedTrustDir, err := homedir.Expand(config.GetString("trust_dir"))
|
||||
if err == nil {
|
||||
config.Set("trust_dir", expandedTrustDir)
|
||||
}
|
||||
// Otherwise just attempt to use whatever the user gave us
|
||||
expandedTrustDir := homeExpand(homeDir, config.GetString("trust_dir"))
|
||||
config.Set("trust_dir", expandedTrustDir)
|
||||
logrus.Debugf("Using the following trust directory: %s", config.GetString("trust_dir"))
|
||||
|
||||
return config, nil
|
||||
|
@ -147,7 +145,13 @@ func (n *notaryCommander) GetCommand() *cobra.Command {
|
|||
Long: "Notary allows the creation and management of collections of signed targets, allowing the signing and validation of arbitrary content.",
|
||||
SilenceUsage: true, // we don't want to print out usage for EVERY error
|
||||
SilenceErrors: true, // we do our own error reporting with fatalf
|
||||
Run: func(cmd *cobra.Command, args []string) { cmd.Usage() },
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if n.version {
|
||||
fmt.Printf("notary Version: %s, Git commit: %s, Go version: %s\n", version.NotaryVersion, version.GitCommit, runtime.Version())
|
||||
os.Exit(0)
|
||||
}
|
||||
cmd.Usage()
|
||||
},
|
||||
}
|
||||
notaryCmd.SetOutput(os.Stdout)
|
||||
notaryCmd.AddCommand(&cobra.Command{
|
||||
|
@ -155,7 +159,7 @@ func (n *notaryCommander) GetCommand() *cobra.Command {
|
|||
Short: "Print the version number of notary",
|
||||
Long: "Print the version number of notary",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("notary\n Version: %s\n Git commit: %s\n", version.NotaryVersion, version.GitCommit)
|
||||
fmt.Printf("notary\n Version: %s\n Git commit: %s\n Go version: %s\n", version.NotaryVersion, version.GitCommit, runtime.Version())
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -164,6 +168,7 @@ func (n *notaryCommander) GetCommand() *cobra.Command {
|
|||
notaryCmd.PersistentFlags().StringVarP(
|
||||
&n.configFile, "configFile", "c", "", "Path to the configuration file to use")
|
||||
notaryCmd.PersistentFlags().BoolVarP(&n.verbose, "verbose", "v", false, "Verbose output")
|
||||
notaryCmd.Flags().BoolVar(&n.version, "version", false, "Print the version number of notary")
|
||||
notaryCmd.PersistentFlags().BoolVarP(&n.debug, "debug", "D", false, "Debug output")
|
||||
notaryCmd.PersistentFlags().StringVarP(&n.remoteTrustServer, "server", "s", "", "Remote trust server location")
|
||||
notaryCmd.PersistentFlags().StringVar(&n.tlsCAFile, "tlscacert", "", "Trust certs signed only by this CA")
|
||||
|
|
|
@ -114,7 +114,7 @@ func TestInvalidAddHashCommands(t *testing.T) {
|
|||
cmd.SetArgs(append([]string{"-c", configFile, "-d", tempDir}, "addhash", "gun", "test", "10"))
|
||||
err := cmd.Execute()
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "Must specify a GUN, target, byte size of target data, and at least one hash")
|
||||
require.Contains(t, err.Error(), "must specify a GUN, target, byte size of target data, and at least one hash")
|
||||
|
||||
// Invalid byte size given
|
||||
cmd = NewNotaryCommand()
|
||||
|
|
|
@ -87,7 +87,7 @@ func (k keyInfoSorter) Less(i, j int) bool {
|
|||
case orderedI[x] > orderedJ[x]:
|
||||
return false
|
||||
}
|
||||
// continue on and evalulate the next item
|
||||
// continue on and evaluate the next item
|
||||
}
|
||||
// this shouldn't happen - that means two values are exactly equal
|
||||
return false
|
||||
|
|
|
@ -10,15 +10,13 @@ import (
|
|||
"github.com/theupdateframework/notary/tuf/data"
|
||||
)
|
||||
|
||||
const remoteConfigField = "api"
|
||||
|
||||
// RepoFactory takes a GUN and returns an initialized client.Repository, or an error.
|
||||
type RepoFactory func(gun data.GUN) (client.Repository, error)
|
||||
|
||||
// ConfigureRepo takes in the configuration parameters and returns a repoFactory that can
|
||||
// initialize new client.Repository objects with the correct upstreams and password
|
||||
// retrieval mechanisms.
|
||||
func ConfigureRepo(v *viper.Viper, retriever notary.PassRetriever, onlineOperation bool) RepoFactory {
|
||||
func ConfigureRepo(v *viper.Viper, retriever notary.PassRetriever, onlineOperation bool, permission httpAccess) RepoFactory {
|
||||
localRepo := func(gun data.GUN) (client.Repository, error) {
|
||||
var rt http.RoundTripper
|
||||
trustPin, err := getTrustPinning(v)
|
||||
|
@ -26,7 +24,7 @@ func ConfigureRepo(v *viper.Viper, retriever notary.PassRetriever, onlineOperati
|
|||
return nil, err
|
||||
}
|
||||
if onlineOperation {
|
||||
rt, err = getTransport(v, gun, admin)
|
||||
rt, err = getTransport(v, gun, permission)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
rba7O3YGSuScQakjt9mw2Q5ISwImkRHF3qE=
|
||||
BBRHApr7kqsc+nK64kWf307KRqWf4TANBgkqhkiG9w0BAQsFAAOCAgEAg7lggbLA
|
||||
QPl6Ua+utbUGbl/A8hmo0acGcdUCTN1/leAJFza6RHwYVKzNPJJn8OOSxGNRnO7U
|
||||
h+UVcdiJC54iUCeVMQFYMXopTVeA2SAkIXVSytuSy31Hn+sf7augwROtIq08/7k8
|
||||
WpMImLdb7BAOQrTxro4cjvwOIdi5Ep19XmHaNFMUANhjJ9elNYH77ZyX/31zcpiI
|
||||
KrBCYo1FqVgDha11d2Sq/0UCxRBGYhq4gNb6NR9cdKLfY3XkQ0oQJSQW9t4F2137
|
||||
GpVq4KUSHVpKj3TTneL+hCtBGfnYzVXveYVFMJXSz1NVkIMiTDllx7MfhfQ1OBYt
|
||||
eQnIF7axPWgrM5ndioAMPeYGBicbPtIHFjYgNku2LxrTQ9KkOVOgAsnWiurvxNLb
|
||||
9oXg27PtEIaR6wACGLi2iIeZtH5zXyURybFr58nfngP9FCkNJpSKaLLmv77XQCNY
|
||||
fW6UjiaTUd1IlOxVC5+Yl9tnUo69NVOB2FEUK2gUwt7K+R3xuOPcGAdi3uXuTUuE
|
||||
LqPHX3FrPvVFB0AIorv9sbDZsyANGlHiBrnEMgb5bzAv8oylmQ/TnvBIdxi4CHfb
|
||||
SI+z6xZzWeOwGkqinxAPUO9aHqiYBe4reXrLOS+SEit2Al6fgFiZJ+ImX6aAxApt
|
||||
FYeLBznZE854WQV0jmEvPR0u7+EYIny4f/g=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -195,7 +195,7 @@ func (t *tufCommander) AddToCommand(cmd *cobra.Command) {
|
|||
func (t *tufCommander) tufWitness(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Please provide a GUN and at least one role to witness")
|
||||
return fmt.Errorf("please provide a GUN and at least one role to witness")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -205,7 +205,7 @@ func (t *tufCommander) tufWitness(cmd *cobra.Command, args []string) error {
|
|||
gun := data.GUN(args[0])
|
||||
roles := data.NewRoleList(args[1:])
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, readOnly)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -269,7 +269,7 @@ func getTargetCustom(targetCustomFilename string) (*canonicaljson.RawMessage, er
|
|||
func (t *tufCommander) tufAddByHash(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 3 || t.sha256 == "" && t.sha512 == "" {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN, target, byte size of target data, and at least one hash")
|
||||
return fmt.Errorf("must specify a GUN, target, byte size of target data, and at least one hash")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -294,7 +294,7 @@ func (t *tufCommander) tufAddByHash(cmd *cobra.Command, args []string) error {
|
|||
|
||||
// no online operations are performed by add so the transport argument
|
||||
// should be nil
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, readWrite)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -330,7 +330,7 @@ func (t *tufCommander) tufAddByHash(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufAdd(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 3 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN, target, and path to target data")
|
||||
return fmt.Errorf("must specify a GUN, target, and path to target data")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -350,7 +350,7 @@ func (t *tufCommander) tufAdd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
// no online operations are performed by add so the transport argument
|
||||
// should be nil
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, readWrite)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -373,7 +373,7 @@ func (t *tufCommander) tufAdd(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufDeleteGUN(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -421,7 +421,7 @@ func importRootKey(cmd *cobra.Command, rootKey string, nRepo notaryclient.Reposi
|
|||
// add root key to repo
|
||||
err = nRepo.GetCryptoService().AddKey(data.CanonicalRootRole, "", privKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error importing key: %v", err)
|
||||
return nil, fmt.Errorf("error importing key: %w", err)
|
||||
}
|
||||
rootKeyList = []string{privKey.ID()}
|
||||
} else {
|
||||
|
@ -462,7 +462,7 @@ func importRootCert(certFilePath string) ([]data.PublicKey, error) {
|
|||
// convert the file to data.PublicKey
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parsing certificate PEM bytes to x509 certificate: %v", err)
|
||||
return nil, fmt.Errorf("parsing certificate PEM bytes to x509 certificate: %w", err)
|
||||
}
|
||||
publicKeys = append(publicKeys, tufutils.CertToKey(cert))
|
||||
|
||||
|
@ -472,7 +472,7 @@ func importRootCert(certFilePath string) ([]data.PublicKey, error) {
|
|||
func (t *tufCommander) tufInit(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
|
||||
config, err := t.configGetter()
|
||||
|
@ -481,7 +481,7 @@ func (t *tufCommander) tufInit(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
gun := data.GUN(args[0])
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, true)
|
||||
fact := ConfigureRepo(config, t.retriever, true, readWrite)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -497,7 +497,7 @@ func (t *tufCommander) tufInit(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// if key is not defined but cert is, then clear the key to to allow key to be searched in keystore
|
||||
// if key is not defined but cert is, then clear the key to allow key to be searched in keystore
|
||||
if t.rootKey == "" && t.rootCert != "" {
|
||||
rootKeyIDs = []string{}
|
||||
}
|
||||
|
@ -514,7 +514,7 @@ func (t *tufCommander) tufInit(cmd *cobra.Command, args []string) error {
|
|||
func readKey(role data.RoleName, keyFilename string, retriever notary.PassRetriever) (data.PrivateKey, error) {
|
||||
pemBytes, err := ioutil.ReadFile(keyFilename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading input root key file: %v", err)
|
||||
return nil, fmt.Errorf("error reading input root key file: %v", err)
|
||||
}
|
||||
isEncrypted := true
|
||||
if err = cryptoservice.CheckRootKeyIsEncrypted(pemBytes); err != nil {
|
||||
|
@ -539,7 +539,7 @@ func readKey(role data.RoleName, keyFilename string, retriever notary.PassRetrie
|
|||
func (t *tufCommander) tufList(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -547,7 +547,7 @@ func (t *tufCommander) tufList(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
gun := data.GUN(args[0])
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, true)
|
||||
fact := ConfigureRepo(config, t.retriever, true, readOnly)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -566,7 +566,7 @@ func (t *tufCommander) tufList(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufLookup(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN and target")
|
||||
return fmt.Errorf("must specify a GUN and target")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -576,7 +576,7 @@ func (t *tufCommander) tufLookup(cmd *cobra.Command, args []string) error {
|
|||
gun := data.GUN(args[0])
|
||||
targetName := args[1]
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, true)
|
||||
fact := ConfigureRepo(config, t.retriever, true, readOnly)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -594,7 +594,7 @@ func (t *tufCommander) tufLookup(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufStatus(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
|
||||
config, err := t.configGetter()
|
||||
|
@ -603,7 +603,7 @@ func (t *tufCommander) tufStatus(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
gun := data.GUN(args[0])
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, readOnly)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -642,11 +642,11 @@ func (t *tufCommander) tufStatus(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufReset(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
if !t.resetAll && len(t.deleteIdx) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify changes to reset with -n or the --all flag")
|
||||
return fmt.Errorf("must specify changes to reset with -n or the --all flag")
|
||||
}
|
||||
|
||||
config, err := t.configGetter()
|
||||
|
@ -655,7 +655,7 @@ func (t *tufCommander) tufReset(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
gun := data.GUN(args[0])
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, admin)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -681,7 +681,7 @@ func (t *tufCommander) tufReset(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufPublish(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN")
|
||||
return fmt.Errorf("must specify a GUN")
|
||||
}
|
||||
|
||||
config, err := t.configGetter()
|
||||
|
@ -692,7 +692,7 @@ func (t *tufCommander) tufPublish(cmd *cobra.Command, args []string) error {
|
|||
|
||||
cmd.Println("Pushing changes to", gun)
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, true)
|
||||
fact := ConfigureRepo(config, t.retriever, true, readWrite)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -703,7 +703,7 @@ func (t *tufCommander) tufPublish(cmd *cobra.Command, args []string) error {
|
|||
|
||||
func (t *tufCommander) tufRemove(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return fmt.Errorf("Must specify a GUN and target")
|
||||
return fmt.Errorf("must specify a GUN and target")
|
||||
}
|
||||
config, err := t.configGetter()
|
||||
if err != nil {
|
||||
|
@ -713,7 +713,7 @@ func (t *tufCommander) tufRemove(cmd *cobra.Command, args []string) error {
|
|||
gun := data.GUN(args[0])
|
||||
targetName := args[1]
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, false)
|
||||
fact := ConfigureRepo(config, t.retriever, false, admin)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -732,7 +732,7 @@ func (t *tufCommander) tufRemove(cmd *cobra.Command, args []string) error {
|
|||
func (t *tufCommander) tufVerify(cmd *cobra.Command, args []string) error {
|
||||
if len(args) < 2 {
|
||||
cmd.Usage()
|
||||
return fmt.Errorf("Must specify a GUN and target")
|
||||
return fmt.Errorf("must specify a GUN and target")
|
||||
}
|
||||
|
||||
config, err := t.configGetter()
|
||||
|
@ -748,7 +748,7 @@ func (t *tufCommander) tufVerify(cmd *cobra.Command, args []string) error {
|
|||
gun := data.GUN(args[0])
|
||||
targetName := args[1]
|
||||
|
||||
fact := ConfigureRepo(config, t.retriever, true)
|
||||
fact := ConfigureRepo(config, t.retriever, true, readOnly)
|
||||
nRepo, err := fact(gun)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -796,7 +796,7 @@ func (ps passwordStore) Basic(u *url.URL) (string, string) {
|
|||
|
||||
i := strings.Index(plain, ":")
|
||||
if i == 0 {
|
||||
logrus.Error("Authentication string with zero-legnth username")
|
||||
logrus.Error("Authentication string with zero-length username")
|
||||
return "", ""
|
||||
} else if i > -1 {
|
||||
username := plain[:i]
|
||||
|
@ -912,14 +912,14 @@ func tokenAuth(trustServerURL string, baseTransport *http.Transport, gun data.GU
|
|||
}
|
||||
endpoint, err := url.Parse(trustServerURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not parse remote trust server url (%s): %s", trustServerURL, err.Error())
|
||||
return nil, fmt.Errorf("could not parse remote trust server url (%s): %w", trustServerURL, err)
|
||||
}
|
||||
if endpoint.Scheme == "" {
|
||||
return nil, fmt.Errorf("Trust server url has to be in the form of http(s)://URL:PORT. Got: %s", trustServerURL)
|
||||
return nil, fmt.Errorf("trust server url has to be in the form of http(s)://URL:PORT. Got: %s", trustServerURL)
|
||||
}
|
||||
subPath, err := url.Parse(path.Join(endpoint.Path, "/v2") + "/")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse v2 subpath. This error should not have been reached. Please report it as an issue at https://github.com/theupdateframework/notary/issues: %s", err.Error())
|
||||
return nil, fmt.Errorf("failed to parse v2 subpath. This error should not have been reached. Please report it as an issue at https://github.com/theupdateframework/notary/issues: %w", err)
|
||||
}
|
||||
endpoint = endpoint.ResolveReference(subPath)
|
||||
req, err := http.NewRequest("GET", endpoint.String(), nil)
|
||||
|
@ -960,7 +960,7 @@ func tokenAuth(trustServerURL string, baseTransport *http.Transport, gun data.GU
|
|||
case readOnly:
|
||||
actions = []string{"pull"}
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid permission requested for token authentication of gun %s", gun)
|
||||
return nil, fmt.Errorf("invalid permission requested for token authentication of gun %s", gun)
|
||||
}
|
||||
|
||||
tokenHandler := auth.NewTokenHandler(authTransport, ps, gun.String(), actions...)
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -89,7 +90,7 @@ adLwkjqoeEKMaAXf
|
|||
|
||||
_, err = importRootCert(errCertFile)
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "Parsing certificate PEM bytes to x509 certificate")
|
||||
require.Contains(t, err.Error(), "parsing certificate PEM bytes to x509 certificate")
|
||||
|
||||
}
|
||||
|
||||
|
@ -199,6 +200,76 @@ func TestAdminTokenAuthNon200Non401Status(t *testing.T) {
|
|||
require.Nil(t, auth)
|
||||
}
|
||||
|
||||
func fakeAuthServerFactory(t *testing.T, expectedScope string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Contains(t, r.URL.RawQuery, "scope="+url.QueryEscape(expectedScope))
|
||||
w.WriteHeader(200)
|
||||
}
|
||||
}
|
||||
|
||||
func authChallengerFactory(URL string) func(w http.ResponseWriter, r *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Www-Authenticate", fmt.Sprintf(`Bearer realm="%s"`, URL))
|
||||
w.WriteHeader(401)
|
||||
}
|
||||
}
|
||||
func TestConfigureRepo(t *testing.T) {
|
||||
authserver := httptest.NewServer(http.HandlerFunc(fakeAuthServerFactory(t, "repository:yes:pull")))
|
||||
defer authserver.Close()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(authChallengerFactory(authserver.URL)))
|
||||
defer s.Close()
|
||||
|
||||
tempBaseDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
v := viper.New()
|
||||
v.SetDefault("trust_dir", tempBaseDir)
|
||||
v.Set("remote_server.url", s.URL)
|
||||
|
||||
repo, err := ConfigureRepo(v, nil, true, readOnly)("yes")
|
||||
require.NoError(t, err)
|
||||
//perform an arbitrary action to trigger a call to the fake auth server
|
||||
repo.ListRoles()
|
||||
}
|
||||
|
||||
func TestConfigureRepoRW(t *testing.T) {
|
||||
authserver := httptest.NewServer(http.HandlerFunc(fakeAuthServerFactory(t, "repository:yes:push,pull")))
|
||||
defer authserver.Close()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(authChallengerFactory(authserver.URL)))
|
||||
defer s.Close()
|
||||
|
||||
tempBaseDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
v := viper.New()
|
||||
v.SetDefault("trust_dir", tempBaseDir)
|
||||
v.Set("remote_server.url", s.URL)
|
||||
|
||||
repo, err := ConfigureRepo(v, nil, true, readWrite)("yes")
|
||||
require.NoError(t, err)
|
||||
//perform an arbitrary action to trigger a call to the fake auth server
|
||||
repo.ListRoles()
|
||||
}
|
||||
|
||||
func TestConfigureRepoAdmin(t *testing.T) {
|
||||
authserver := httptest.NewServer(http.HandlerFunc(fakeAuthServerFactory(t, "repository:yes:*")))
|
||||
defer authserver.Close()
|
||||
|
||||
s := httptest.NewServer(http.HandlerFunc(authChallengerFactory(authserver.URL)))
|
||||
defer s.Close()
|
||||
|
||||
tempBaseDir := tempDirWithConfig(t, "{}")
|
||||
defer os.RemoveAll(tempBaseDir)
|
||||
v := viper.New()
|
||||
v.SetDefault("trust_dir", tempBaseDir)
|
||||
v.Set("remote_server.url", s.URL)
|
||||
|
||||
repo, err := ConfigureRepo(v, nil, true, admin)("yes")
|
||||
require.NoError(t, err)
|
||||
//perform an arbitrary action to trigger a call to the fake auth server
|
||||
repo.ListRoles()
|
||||
}
|
||||
|
||||
func TestStatusUnstageAndReset(t *testing.T) {
|
||||
setUp(t)
|
||||
tempBaseDir := tempDirWithConfig(t, "{}")
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -30,7 +31,7 @@ func getPayload(t *tufCommander) ([]byte, error) {
|
|||
// Reads all of the data on STDIN
|
||||
payload, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error reading content from STDIN: %v", err)
|
||||
return nil, fmt.Errorf("error reading content from STDIN: %w", err)
|
||||
}
|
||||
return payload, nil
|
||||
}
|
||||
|
@ -46,9 +47,18 @@ func feedback(t *tufCommander, payload []byte) error {
|
|||
|
||||
// Flag "quiet" was not "true", that's why we get here.
|
||||
if t.output != "" {
|
||||
return ioutil.WriteFile(t.output, payload, 0644)
|
||||
return ioutil.WriteFile(t.output, payload, 0600)
|
||||
}
|
||||
|
||||
os.Stdout.Write(payload)
|
||||
return nil
|
||||
}
|
||||
|
||||
// homeExpand will expand an initial ~ to the user home directory. This is supported for
|
||||
// config files where the shell will not have expanded paths.
|
||||
func homeExpand(homeDir, path string) string {
|
||||
if path == "" || path[0] != '~' || (len(path) > 1 && path[1] != os.PathSeparator) {
|
||||
return path
|
||||
}
|
||||
return filepath.Join(homeDir, path[1:])
|
||||
}
|
||||
|
|
|
@ -52,3 +52,12 @@ func TestFeedback(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t, "", string(content))
|
||||
}
|
||||
|
||||
func TestHomeExpand(t *testing.T) {
|
||||
require.Equal(t, homeExpand("home", ""), "")
|
||||
require.Equal(t, homeExpand("home", "~"), "home")
|
||||
require.Equal(t, homeExpand("home", "~"+string(os.PathSeparator)), "home")
|
||||
require.Equal(t, homeExpand("home", filepath.Join("~", "test")), filepath.Join("home", "test"))
|
||||
require.Equal(t, homeExpand("home", "~cyli"), "~cyli")
|
||||
require.Equal(t, homeExpand(string(os.PathSeparator)+"home", filepath.Join("~", "test")), string(os.PathSeparator)+filepath.Join("home", "test"))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// +build !windows
|
||||
|
||||
package main
|
||||
|
||||
const homeEnv = "HOME"
|
|
@ -0,0 +1,3 @@
|
|||
package main
|
||||
|
||||
const homeEnv = "USERPROFILE"
|
|
@ -1,10 +1,9 @@
|
|||
FROM golang:1.9.4
|
||||
FROM dockercore/golang-cross:1.13.15
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
clang \
|
||||
file \
|
||||
libltdl-dev \
|
||||
libsqlite3-dev \
|
||||
patch \
|
||||
tar \
|
||||
|
@ -15,21 +14,19 @@ RUN apt-get update && apt-get install -y \
|
|||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN useradd -ms /bin/bash notary \
|
||||
&& pip install codecov \
|
||||
&& go get github.com/golang/lint/golint github.com/fzipp/gocyclo github.com/client9/misspell/cmd/misspell github.com/gordonklaus/ineffassign github.com/HewlettPackard/gas
|
||||
&& pip install codecov
|
||||
|
||||
# Configure the container for OSX cross compilation
|
||||
ENV OSX_SDK MacOSX10.11.sdk
|
||||
ENV OSX_CROSS_COMMIT 1a1733a773fe26e7b6c93b16fbf9341f22fac831
|
||||
RUN set -x \
|
||||
&& export OSXCROSS_PATH="/osxcross" \
|
||||
&& git clone https://github.com/tpoechtrager/osxcross.git $OSXCROSS_PATH \
|
||||
&& ( cd $OSXCROSS_PATH && git checkout -q $OSX_CROSS_COMMIT) \
|
||||
&& curl -sSL https://s3.dockerproject.org/darwin/v2/${OSX_SDK}.tar.xz -o "${OSXCROSS_PATH}/tarballs/${OSX_SDK}.tar.xz" \
|
||||
&& UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh > /dev/null
|
||||
ENV PATH /osxcross/target/bin:$PATH
|
||||
ENV GO111MODULE=on
|
||||
|
||||
ENV NOTARYDIR /go/src/github.com/theupdateframework/notary
|
||||
# Locked go cyclo on this commit as newer commits depend on Golang 1.16 io/fs
|
||||
RUN go get golang.org/x/lint/golint \
|
||||
github.com/client9/misspell/cmd/misspell \
|
||||
github.com/gordonklaus/ineffassign \
|
||||
github.com/securego/gosec/cmd/gosec/... \
|
||||
github.com/fzipp/gocyclo@ffe36aa317dcbb421a536de071660261136174dd
|
||||
|
||||
ENV GOFLAGS=-mod=vendor \
|
||||
NOTARYDIR=/go/src/github.com/theupdateframework/notary
|
||||
|
||||
COPY . ${NOTARYDIR}
|
||||
RUN chmod -R a+rw /go
|
||||
|
|
|
@ -21,6 +21,9 @@ var (
|
|||
// ErrRootKeyNotEncrypted is returned if a root key being imported is
|
||||
// unencrypted
|
||||
ErrRootKeyNotEncrypted = errors.New("only encrypted root keys may be imported")
|
||||
|
||||
// EmptyService is an empty crypto service
|
||||
EmptyService = NewCryptoService()
|
||||
)
|
||||
|
||||
// CryptoService implements Sign and Create, holding a specific GUN and keystore to
|
||||
|
@ -82,7 +85,7 @@ func (cs *CryptoService) GetKeyInfo(keyID string) (trustmanager.KeyInfo, error)
|
|||
return info, nil
|
||||
}
|
||||
}
|
||||
return trustmanager.KeyInfo{}, fmt.Errorf("Could not find info for keyID %s", keyID)
|
||||
return trustmanager.KeyInfo{}, fmt.Errorf("could not find info for keyID %s", keyID)
|
||||
}
|
||||
|
||||
// RemoveKey deletes a key by ID
|
||||
|
@ -151,6 +154,7 @@ func CheckRootKeyIsEncrypted(pemBytes []byte) error {
|
|||
if block.Type == "ENCRYPTED PRIVATE KEY" {
|
||||
return nil
|
||||
}
|
||||
//lint:ignore SA1019 Needed for legacy keys.
|
||||
if !notary.FIPSEnabled() && x509.IsEncryptedPEMBlock(block) {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
// +build gofuzz
|
||||
|
||||
package fuzz
|
||||
|
||||
import (
|
||||
"github.com/theupdateframework/notary/cryptoservice"
|
||||
"github.com/theupdateframework/notary/passphrase"
|
||||
"github.com/theupdateframework/notary/trustmanager"
|
||||
)
|
||||
|
||||
// Fuzz implements the fuzzer that targets GetPrivateKey
|
||||
func Fuzz(data []byte) int {
|
||||
cryptos := cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore(passphrase.ConstantRetriever("pass")))
|
||||
_, _, err := cryptos.GetPrivateKey(string(data))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
|
@ -30,10 +30,12 @@ services:
|
|||
- mysql
|
||||
mysql:
|
||||
networks:
|
||||
- mdb
|
||||
mdb:
|
||||
aliases:
|
||||
- mysql
|
||||
volumes:
|
||||
- ./notarysql/mysql-initdb.d:/docker-entrypoint-initdb.d
|
||||
image: mariadb:10.1.28
|
||||
image: mariadb:10.4
|
||||
environment:
|
||||
- TERM=dumb
|
||||
- MYSQL_ALLOW_EMPTY_PASSWORD="true"
|
||||
|
|
|
@ -37,7 +37,9 @@ services:
|
|||
postgresql:
|
||||
image: postgres:9.5.4
|
||||
networks:
|
||||
- mdb
|
||||
mdb:
|
||||
aliases:
|
||||
- postgresql
|
||||
volumes:
|
||||
- ./notarysql/postgresql-initdb.d:/docker-entrypoint-initdb.d
|
||||
command: -l
|
||||
|
|
|
@ -34,7 +34,7 @@ services:
|
|||
volumes:
|
||||
- ./notarysql/mysql-initdb.d:/docker-entrypoint-initdb.d
|
||||
- notary_data:/var/lib/mysql
|
||||
image: mariadb:10.1.28
|
||||
image: mariadb:10.4
|
||||
environment:
|
||||
- TERM=dumb
|
||||
- MYSQL_ALLOW_EMPTY_PASSWORD="true"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
FROM docs/base:oss
|
||||
MAINTAINER Mary Anthony <mary@docker.com> (@moxiegirl)
|
||||
|
||||
ENV PROJECT=notary
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ draft = true
|
|||
|
||||
# Contributing to the Docker Notary documentation
|
||||
|
||||
The documentation in this directory is part of the [https://docs.docker.com](https://docs.docker.com) website. Docker uses [the Hugo static generator](http://gohugo.io/overview/introduction/) to convert project Markdown files to a static HTML site.
|
||||
The documentation in this directory is part of the [https://docs.docker.com](https://docs.docker.com) website. Docker uses [the Hugo static generator](https://gohugo.io/getting-started/) to convert project Markdown files to a static HTML site.
|
||||
|
||||
You don't need to be a Hugo expert to contribute to the Notary documentation. If you are familiar with Markdown, you can modify the content in the `docs` files.
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ $ notary key rotate example.com/collection snapshot -r
|
|||
|
||||
Here, `-r` specifies to rotate the key to the remote server.
|
||||
|
||||
When adding a delegation, your must acquire a x509 certificate with the public
|
||||
When adding a delegation, you must acquire a x509 certificate with the public
|
||||
key of the user you wish to delegate to. The user who will assume this
|
||||
delegation role must hold the private key to sign content with notary.
|
||||
|
||||
|
|
|
@ -185,6 +185,7 @@ passphrase.
|
|||
|`NOTARY_TARGETS_PASSPHRASE` | The targets (an online) key passphrase |
|
||||
|`NOTARY_SNAPSHOT_PASSPHRASE` | The snapshot (an online) key passphrase |
|
||||
|`NOTARY_DELEGATION_PASSPHRASE` | The delegation (an online) key passphrase |
|
||||
|`NOTARY_AUTH` | The notary server creds ("username:password"), base64-ed |
|
||||
|
||||
|
||||
Please note that if provided, the passphrase in `NOTARY_DELEGATION_PASSPHRASE`
|
||||
|
|
|
@ -10,7 +10,7 @@ parent="mn_notary_config"
|
|||
|
||||
# Notary server configuration file
|
||||
|
||||
This document is for those who are [running their own Notary service](../running_a_service.md) who
|
||||
This document is for those who are [running their own Notary service](../running_a_service.md) and
|
||||
want to specify custom options.
|
||||
|
||||
## Overview
|
||||
|
@ -240,7 +240,7 @@ DB storage example:
|
|||
<td valign="top"><code>db_url</code></td>
|
||||
<td valign="top">yes if not <code>memory</code></td>
|
||||
<td valign="top">The <a href="https://github.com/go-sql-driver/mysql">
|
||||
the Data Source Name used to access the DB.</a>
|
||||
Data Source Name used to access the DB.</a>
|
||||
(note: please include <code>parseTime=true</code> as part of the DSN)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -363,6 +363,7 @@ Example:
|
|||
|
||||
## Hot logging level reload
|
||||
We don't support completely reloading notary configuration files yet at present. What we support for Linux and OSX now is:
|
||||
|
||||
- increase logging level by signaling `SIGUSR1`
|
||||
- decrease logging level by signaling `SIGUSR2`
|
||||
|
||||
|
@ -387,7 +388,7 @@ or
|
|||
|
||||
$ docker exec -i CONTAINER_ID kill -s SIGUSR2 PID
|
||||
```
|
||||
PID is the process id of `notary-server` and it may not the PID 1 process if you are running
|
||||
PID is the process ID of `notary-server` and it may not the PID 1 process if you are running
|
||||
the container with some kind of wrapper startup script or something.
|
||||
|
||||
You can get the PID of `notary-server` through
|
||||
|
|
Binary file not shown.
|
@ -104,7 +104,7 @@ server, and signer:
|
|||

|
||||
|
||||
1. Notary server optionally supports authentication from clients using
|
||||
<a href="http://jwt.io/" target="_blank">JWT</a> tokens. This requires an authorization server that
|
||||
<a href="https://jwt.io" target="_blank">JWT</a> tokens. This requires an authorization server that
|
||||
manages access controls, and a cert bundle from this authorization server
|
||||
containing the public key it uses to sign tokens.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
FROM golang:1.9.4-alpine
|
||||
MAINTAINER David Lawrence "david.lawrence@docker.com"
|
||||
FROM golang:1.17.13-alpine
|
||||
|
||||
ENV NOTARYPKG github.com/theupdateframework/notary
|
||||
ENV GO111MODULE=on
|
||||
|
||||
# Copy the local repo to the expected go path
|
||||
COPY . /go/src/${NOTARYPKG}
|
||||
|
|
17
fips.go
17
fips.go
|
@ -1,13 +1,14 @@
|
|||
package notary
|
||||
|
||||
import "os"
|
||||
import (
|
||||
"crypto"
|
||||
// Need to import md5 so can test availability.
|
||||
_ "crypto/md5" // #nosec
|
||||
)
|
||||
|
||||
// FIPSEnvVar is the name of the environment variable that is being used to switch
|
||||
// between FIPS and non-FIPS mode
|
||||
const FIPSEnvVar = "GOFIPS"
|
||||
|
||||
// FIPSEnabled returns true if environment variable `GOFIPS` has been set to enable
|
||||
// FIPS mode
|
||||
// FIPSEnabled returns true if running in FIPS mode.
|
||||
// If compiled in FIPS mode the md5 hash function is never available
|
||||
// even when imported. This seems to be the best test we have for it.
|
||||
func FIPSEnabled() bool {
|
||||
return os.Getenv(FIPSEnvVar) != ""
|
||||
return !crypto.MD5.Available()
|
||||
}
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDajCCAlKgAwIBAgIUHN8eDMtoTOBXOd+RjnCxLYUs4kYwDQYJKoZIhvcNAQEL
|
||||
BQAwTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJh
|
||||
bmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENBMB4XDTE3MDUxMjIyMzcw
|
||||
MFoXDTIyMDUxMTIyMzcwMFowTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYw
|
||||
FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy9811sQcEoe2pH0+jUQP
|
||||
8Jq7RkuUnFtbYpR7H6AyMXfyCsiz4ghpkENFScJlQhFE/Q5XXk0mTVEJD7UEwuQp
|
||||
haqqSbDYMKVXHGY3CESyRF6z/k4jPTpxK0KxqsIXi8MZFvLOMUVGhXp+duFFX365
|
||||
ZXi0GTIhkkbo6/tQLLAYAL5dfAOU7FTOthK6RkPBnPLdb5ZuKJfbSBkIBH+Rdrm5
|
||||
atJYzL6rha3p2Hnm6FFF0eqdd+uqYpBuXcmQsftxPLBMvqbHXaPMov51+WvRXz0K
|
||||
EeluT0Fue0LuYCRYFMlbmALFg85tFAHWXKer6M/ejK4MCWQnpPwalE9Oaetb1/q5
|
||||
MwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
|
||||
HQ4EFgQU30PAjq5cOwlLzi4fxSE3J/v9EPcwDQYJKoZIhvcNAQELBQADggEBAJhV
|
||||
p1Va9r/NdCXaL5Ah+4i+l5m3hcKXT9h3811rmtLtKqcUwwnBbG+V3Ko+arbuCDYV
|
||||
VajGLRnhTjy1thqYZr6KbeG6HZ6BN8Zxhcam86O7JXDBKoWJH4SIGysXO0jXg1n4
|
||||
fM1teEhQ69OUCrCkFGBblL88uHbdgIQGTDkD9F4hFGia6NSII46MTIE6tH0UBrIy
|
||||
L5ZNCgG5Mn5w4D2Su6X6vq5ovE/mXRJLYCQLkvKSi5BQDdM26SwmKFSNk2V+DUeu
|
||||
te3qluUTIFLa+V+U0C6vJMaxgaTB5phzQ1R7HykqBnSrzcqyQKYKnR3aGzvHnb2m
|
||||
VYGGXEToG4TacQ/psn8=
|
||||
MIIDAjCCAeqgAwIBAgIUXVJRkZt3nqfJpaVeEEVNoX5w4bEwDQYJKoZIhvcNAQEL
|
||||
BQAwGTEXMBUGA1UEAxMOVGVzdCBOb3RhcnkgQ0EwHhcNMjEwNDAyMTMwNTAwWhcN
|
||||
MjYwNDAxMTMwNTAwWjAZMRcwFQYDVQQDEw5UZXN0IE5vdGFyeSBDQTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANPxWDzc8fGeC8mNdVbz0L5qatZRAYkG
|
||||
MmhNVrmICPT3S0kS0AzvnHf1ZpqTsUqF3W0ujpGzLDgdmtstQESLYFvBwDMQAu6X
|
||||
axF3HesFd2BqIjiTD4HdTlYSWVhk+YKOrOtF6CpxvTVJpFPjSIPEA79c84wrI6Eu
|
||||
+FgcG5Al8NdkTSu1D1fNk1JGvIDki3+PQQEAjCKGbwjXJe/Zv1rga4xnCFVCx63J
|
||||
7Esj1UWssCQ1RaqPV5xqnIldHzWatiEpfU4Vk7+Hyoep/3H+xTqUP2JNfKblHGCw
|
||||
/DLeU4aXvTDjgRYKHWgSZQBFQYLRz2h2xE6UYeomloNguLvJ4A7xo38CAwEAAaNC
|
||||
MEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEVE
|
||||
JL9mT7Twv0BLNevED4280MPgMA0GCSqGSIb3DQEBCwUAA4IBAQCyIc548I14Es7b
|
||||
i1KDBHOeXmQiM9g1hbMJk7Q9+IjPy+fmbqDcop/9U9pCCdSvEOR3z0zeKwEfqxMI
|
||||
ukLG/tjAn+DB0Wid/RznBMTmTvreghmfAsQfGs/j+PC+B6OyaV4+4lUbvTjmsThu
|
||||
3cOPUQTypytUgy00C1mdQfUXMJbNRFAor6ux6ZIQw358urDWWWdrQ8fSF2bb28GA
|
||||
3cBjZ8X2EtABZs4BYVt/2R+5w9ejeUDz3rSXwV+9DYdZ2dxsK240VTJRskc1UazY
|
||||
p/mM9bSOrgvaGeFJkJXrKII0BCrVUREXk8WwxoKdIBkJrtIjxuBxiiXNHFPYxbV/
|
||||
3TQNaexo
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAznRYoWEqB8VQQ3VnFSv1b2PU1UwTdREfsFu/O/yxdBpCEbSY
|
||||
s1Qc6ynHZuMOyscS46kiB3PSX1/CxMmPPSGcO1Z3VIbf8YUBtaMxTsO7nA5H22EO
|
||||
/M8SI+psrDhv+OtmrjzDtWVC9KgDV/F5+/8vynyh4J7HMilUjzbMHXYCZvW7aG7z
|
||||
rrItMNjhGmJeRXFlBIuSLxdbKGcuFv2xz3QPqF151mNcPaQosj1k7LtvB5Dkfhra
|
||||
33nMEsBp8QZfAag6xfuhEREeV6qOlG2DQL8nKuti1hLYUDFy3G7k1iswG/HadUBo
|
||||
MGrn+n8SywTmAW3HDvcfxOXzl5brmLURNUY+dQIDAQABAoIBAAu+cow7iriGcNpl
|
||||
g0ehCIUdmK3JdhHit3rAvVAcP7vrAncfXtBUqJB3/+/KWr0ONfTdWiIyZHUobVvk
|
||||
W1GO5+Q4NvGH+pUyi7ZZYiSo3bMy3MON8dxPqyh/3U6upy/xtBWVP0zCRdzE8eu+
|
||||
wMGk8oMCM/MjFRG1aCn9Y/8JB3nzxl2d8QCxeLjbIHJ/NWj7gf0xGVmKK7YVXd7W
|
||||
FHFFLTAxLRgfjZcxZB/u/L/T0pEwuyzbk2iGc9YkkgiBVUEqtIce6a7HHnKL7oBJ
|
||||
9sWxqc10rs9EP/2W7qfNolNkFVNnfJmY4x8ZpfAjW7/Osin22qCp5+kWyT2I/Qg6
|
||||
+TwNQgECgYEA5ie0FdwsJbh0qNuWpXyMYJ2m27ag1zhpnsGs8iT9yWorZwp8BNm0
|
||||
1NchF/hE1Gkwvo+47U3ZvEmx7tLEA7Ekl7KZZro5+0jumSKd/vUrEpThqeJglz68
|
||||
T6/xZBGPIa3KZdXszs1pGjBNVEs1WuXgMPiFSypFT3ODnXgbFovX/nkCgYEA5aNR
|
||||
fCF2ACs3oeKHDwVCwMh3fbSmf4ZwpzdhARV5rSc8Je9K7oyoO5fgGWWXZqKLP138
|
||||
1ARQGwGcwImzrYvY8g7AqXe/J+Mr9Jr6+vrLDPShmeqyTiBdOTwgg/5muDdv+GS3
|
||||
zqzXtPI1Upuo8/1EwYUacYOk4EX7ga7iZMEoEN0CgYEAvkOgSloDXQOJ3XX6qb+2
|
||||
xMBPil8FxCXsmsN9V4hhDTrpunseX1wic7mMsCYbsIVtOHvT4sly8Ibzw30Vcf/l
|
||||
QkrxKc1V1XhLVukZOAYxn2DY1PpB44aHYlEO+yzQ6ISlR158L9H7yxyXMNIjv4s9
|
||||
tP4eIy9EsRPLgEgkDJV67/ECgYAwHbxhKhGzj1qkzPZHq26FPnvrFwMcDWtlXjEx
|
||||
LPLF2Ua9HBqzST2m3vfR2nuSwdQzftoPAqhWQEw7+55uarMWZQjxeWnQTcVUB3U3
|
||||
SX1qRYfm3EpoHFfsOjEF9zRGvTb08QWihIzeGTIbEQqhtRvHAMC9sDvH0mIUljRR
|
||||
sDdY8QKBgQDcT3yamYnGy6GzxWfpZYwoWqJFMtXjacD2rV32jwHifCa1RNu/Su6S
|
||||
UJcN9v/1GYfvLWzjDMv6hKFt/Q1e3mACgohL9vfZtgiZx5SCVi0AXdOpXLBWlLvl
|
||||
KM4XVhbuVTko/DsuGPVyXAHFHRFOjr+00Bw8y80DQIjNv4fgocr58Q==
|
||||
MIIEogIBAAKCAQEAtVuK/nw4lU0CAoN7hDuzSPQk8rdNFMRnH10B0gDGyrpbgE+J
|
||||
IKFDIdhAIwmtt0/WHXPwQzby6vLcw/ngrYrcMnGOC8MK1yH2E9s8NeKSvzAi0Jp1
|
||||
CzpRXeGZkFF3wIJkCqoiojMPsCmAjvPZHuOatddiM24o1EnxVP5Zgt84/lOyJaXR
|
||||
XKOjQd408+pBQD7Rrah7BwXOSDj2UdXQ6ea0ASxv7JWxBu/pTmrczD9MsvTOV73j
|
||||
A6Ag41pfQE5zYenfhR6aGrihYuKmjWnn9iZdXWPpXJmTlCXawaGFDBL95tS3xLEN
|
||||
Taz+aC3DQm9ecpTPv0nH3TbEFaQG2vJ9mbgtKQIDAQABAoIBAC+6Ep8cU8u+w1uj
|
||||
/Hp1N55oWdziLk/bzAOt90+r0qUBXBktVToYFlGu1loiLuxB/2gq3bzilhUMqtqM
|
||||
RPuGwqInzij8QDsTfe4F0RehM9tKsK7TJyA4Tbd2KnKXbftklS1VTt3+sA89LM7y
|
||||
D16YqVtXfklooSgU+YTTlvzg/9+19u5MlmSyjdgX0/6hq54OU6MRmIKduLNY7l1L
|
||||
GtGGp4LYTXoEiNpztQWMmV0rQ+GyBaL5qyD8RMHY4Jfo+uu3PFhQpofVOlVgutrh
|
||||
jDIM6Uc6z0juWIxWSwtCdOnGHkl4cu+YMdZ5i5Ija3fX6FLtbqlqbMMAuzS1smt+
|
||||
Id7QEi0CgYEAweVaNX3G6AHS9mNwLnqVqtQuXfqsKi9n4e/tNJ0sAWKTmfn5BoaB
|
||||
cNEv/KoII3bLnrzyAmDIyQgWx3oYuzrXbwp/OUQSuDT3EMHpkngtBnF/jhidGGw/
|
||||
TFi7p8n6hMFbWZwsqEeYLcESnqzkVL09/59EcpbYLdrhtX2FgQNpud8CgYEA73IZ
|
||||
7vGJJD236eCXIe5YwDud1RXgQ4a8XONRtpt3GfcM2Fj4YkKdxM8Ur3OXWBDVyso7
|
||||
CU++RuOYsm+MBR5yIeBT9mQXl5elq57CDu8ElfVQ7TUW1d376PHgxUDc91HBUkh4
|
||||
+UwIDJvmStD0aDPOdHiHgUdMGp+9D7nFjOhzCfcCgYBqqxhjkRxaCpbagX33s+ye
|
||||
nDgd74fDdWz6+RlP9p9865Q0AzciheC0BgEWSRxNFk+StnOVJ1WOcurFNsBgUFCw
|
||||
f9/Zyz9ZI5pAF829jGuIvevkaloSU4rHH5GtDwrI+e6db7OJqElp8muh6495ptpy
|
||||
xFXNjHrFT0MYq0NE5HHHlQKBgHlvP5G781Zq6pv1KBCwRVhwo7IOnyb/7QWaz7Ux
|
||||
kSyc62nJbWa/7C2E7DOzBr1GBHcNKvWk+JYRFT7hbXynHTDrCQn7Zy+dXAr2v+o8
|
||||
8/FtcXZrp0Idi4VvLhQ7uhS/5LBrStb75VUnt5qX8GvsYjcVbXt2AjW6b3LLP1Ig
|
||||
DT+vAoGAbir3AxcSNPNlKwz7ERWDAKeWOn1/wRKger5a7gxoWDO6aijdHmmE2GWj
|
||||
+wgjBrOrCznivmHz3kmSlv9FsxlbU+K2vlXCDrbMx3lab53dExn2ZubSqm4wm3bH
|
||||
VyjlKGl3Qvmay1+j3DkulFFO710+6EJwPbovzsOF9mG+sJbIdqY=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIUXF5OjDTCDfBwQkJSdzPtt7HTljUwDQYJKoZIhvcNAQEL
|
||||
BQAwTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJh
|
||||
bmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENBMB4XDTE3MDUxMjIyNDAw
|
||||
MFoXDTE4MDUxMjIyNDAwMFowQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYw
|
||||
FAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQDEwZzZXJ2ZXIwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOdFihYSoHxVBDdWcVK/VvY9TVTBN1ER+w
|
||||
W787/LF0GkIRtJizVBzrKcdm4w7KxxLjqSIHc9JfX8LEyY89IZw7VndUht/xhQG1
|
||||
ozFOw7ucDkfbYQ78zxIj6mysOG/462auPMO1ZUL0qANX8Xn7/y/KfKHgnscyKVSP
|
||||
NswddgJm9btobvOusi0w2OEaYl5FcWUEi5IvF1soZy4W/bHPdA+oXXnWY1w9pCiy
|
||||
PWTsu28HkOR+GtrfecwSwGnxBl8BqDrF+6ERER5Xqo6UbYNAvycq62LWEthQMXLc
|
||||
buTWKzAb8dp1QGgwauf6fxLLBOYBbccO9x/E5fOXluuYtRE1Rj51AgMBAAGjgYMw
|
||||
gYAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB
|
||||
/wQCMAAwHQYDVR0OBBYEFAs/6pFKZmzdHb27KyFFd0G9G/39MB8GA1UdIwQYMBaA
|
||||
FN9DwI6uXDsJS84uH8UhNyf7/RD3MAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAhCYtK8m7gPrijUgmYFyUqwiYFSLIhTEE+9nGZ/3Q5IeLneTVcQMAogUY
|
||||
cZCNPrj8QBQmEXupacHBH1UO58L0OsXf+jJ3Gx5W9YiNyEzhZxoi08u2y/JzQ+3K
|
||||
OVfSYpsHPVH82f9pz9TVmBhcVBrxUY1cO4vTxBm5P9irVo1M8KHRB3qLjHSSr7mP
|
||||
pvFRYTrnG8cEMRwJT+Akfc9jFDXzCxPptHGme5lZAXH0OcyAEaGLrBlmrZKOuGa8
|
||||
ssJWcp5OoTdUiL0j6LfRZSghbVkNsSTXPVcBU38YsowpOm8AOpqu+mF0hl/cq8/h
|
||||
vE8cxe19y4FmiPD5JaUtndkwXxM8bQ==
|
||||
MIIDPDCCAiSgAwIBAgIUYbrToHmIONcG3sEKhQvMVU+KqT8wDQYJKoZIhvcNAQEL
|
||||
BQAwGTEXMBUGA1UEAxMOVGVzdCBOb3RhcnkgQ0EwHhcNMjEwNDAyMTMwNTAwWhcN
|
||||
MjYwNDAxMTMwNTAwWjARMQ8wDQYDVQQDEwZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQC1W4r+fDiVTQICg3uEO7NI9CTyt00UxGcfXQHSAMbK
|
||||
uluAT4kgoUMh2EAjCa23T9Ydc/BDNvLq8tzD+eCtitwycY4LwwrXIfYT2zw14pK/
|
||||
MCLQmnULOlFd4ZmQUXfAgmQKqiKiMw+wKYCO89ke45q112IzbijUSfFU/lmC3zj+
|
||||
U7IlpdFco6NB3jTz6kFAPtGtqHsHBc5IOPZR1dDp5rQBLG/slbEG7+lOatzMP0yy
|
||||
9M5XveMDoCDjWl9ATnNh6d+FHpoauKFi4qaNaef2Jl1dY+lcmZOUJdrBoYUMEv3m
|
||||
1LfEsQ1NrP5oLcNCb15ylM+/ScfdNsQVpAba8n2ZuC0pAgMBAAGjgYMwgYAwDgYD
|
||||
VR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAw
|
||||
HQYDVR0OBBYEFA5KHj/qntl1+m/9lnjpDWIn+g6SMB8GA1UdIwQYMBaAFEVEJL9m
|
||||
T7Twv0BLNevED4280MPgMAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
L6CwdBhLpJPTmbRWiDsKX1U3ezJ8Cc4Sd3kDb6fV7+v0xV0IYFMRYXlqTzaz/Wc0
|
||||
EiF3Pw0hphDkrv61CoRfaJa93ZVHVR24jJ/yofaxbvUQ9E6VBjZ6K2RXEfm9uEsK
|
||||
11qEx8WszvEdqCheu76zVmqm/AprpNEeANwy1pvTOh4xTSEYgk+qUnXbDk9qLlGo
|
||||
SIZ3ZctDaQID3XN8ZoH98gMuyPjSZ9T4mKIv+My5D6DnEKCNNxfbe2uUsKHFyDVx
|
||||
BKgJkzb+J56IY6LK8V0gFi9GaN4kPqhOzZ9Qg4rWRkTMiuouHx3S6rYxBojpfvKk
|
||||
83rkMHSIOih3Kjl5IAyj+A==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIUeYAM7aBfKP6UBYbE83msSo04RsowDQYJKoZIhvcNAQEL
|
||||
BQAwTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJh
|
||||
bmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENBMB4XDTE3MDUxMjIyNDAw
|
||||
MFoXDTE4MDUxMjIyNDAwMFowQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYw
|
||||
FAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQDEwZzaWduZXIwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRSJoACkfFBSMEBj7Tb6KhAps+K+sWYKuw
|
||||
0QLhU8eYC4d+BuEjBJ/7Nmrj7EvaPsh/fngxvtGmBRP5jSMV9ogEEtZdVcb7/3UR
|
||||
VPAVOPfeIKZHI0EBsPQGSIBipXk+SqVSGQIiCUt6WX8yI4z7wIRQBEoDcvzZuQgs
|
||||
bzp90eFgrRxHN/UI9CuC1aDUa1ZmUMSKWcbTzdrw+NTJzV6O5KOhrrTqezNL9Ry0
|
||||
oCQaS+GX4pDIR6kQV9+bVeZvrrC/9L6ncFrhiFTnGpPtvpNJNwi5enM46SQ3CfJT
|
||||
v0EgFo/UFIATxHERcG2z0ujoTxv1CEQnLM/GZBczmoTXLbJig6gvAgMBAAGjgYMw
|
||||
gYAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB
|
||||
/wQCMAAwHQYDVR0OBBYEFKKGeJZLHFg3QgqFOFE7UjmSYCjNMB8GA1UdIwQYMBaA
|
||||
FN9DwI6uXDsJS84uH8UhNyf7/RD3MAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAREI6iRUC0Pjn41QLI0Xtjv/2GeM1jKY0i6LcT+779QAU5iqPvmxhtO1N
|
||||
BM5ycQwyLD3T55t50ANDDm91klFlXF8IgSvq3efCVSWPtEkVznfQVMOu4dwVblhT
|
||||
GPg1BWbRsbjqdSVfU2cjoQNlflqRaw0XMJ738TrciaLxRHkvYsd0XCOjNTUfUuzi
|
||||
G16zdjBYn43XXW+4FnB2FzqzoM+PicCfEl8Gvi20QlgqtM5kaflhik2gQy6zXc1i
|
||||
hCiiRiE1Qv60VjsGvLFG+TN6HeWQlE260v5drzjmMen9i8hYc42glRDolUSg6hQs
|
||||
DLjTitTiXond4yxJ80LQH6CTtPybvg==
|
||||
MIIDPDCCAiSgAwIBAgIUKYtSEDZrBg5pAlOPfv5c2tIMEGgwDQYJKoZIhvcNAQEL
|
||||
BQAwGTEXMBUGA1UEAxMOVGVzdCBOb3RhcnkgQ0EwHhcNMjEwNDAyMTMwNTAwWhcN
|
||||
MjYwNDAxMTMwNTAwWjARMQ8wDQYDVQQDEwZzaWduZXIwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQDHKQ1z7cRlU5e0vgrtNccsefz6d+bn1SEy8zr7PozE
|
||||
xs+ULlWiXRxlKR+SRyn4wzV966cr/iOb+VT05WJ4+xCRt+enDpOLC4N2qL3mT6b2
|
||||
jqMcTbOb4ogn7i2/bxt4kXwH5cfKC668yfIgmLAu9uypnUCItHt84BcYj4ZCog+0
|
||||
Gfw/L1RZJnjPUY1BcovzxkduhpmA65Fy7JZOwKpxgtZZbpCH9hdak6G4kIKA4nn1
|
||||
xQ/7v+POMl/7uM2NoHWKDBsUKjGfAz3gY2LveYezQZ+NVP6G+l4EVb7c0U8hf5Aq
|
||||
QqthydkAZzAmrkBc7PHKmJJKoxDYWBGLAUUiq5JlcQ4vAgMBAAGjgYMwgYAwDgYD
|
||||
VR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAw
|
||||
HQYDVR0OBBYEFNTPeNsMoBnLR2z0NNpTJCRls9RjMB8GA1UdIwQYMBaAFEVEJL9m
|
||||
T7Twv0BLNevED4280MPgMAsGA1UdEQQEMAKCADANBgkqhkiG9w0BAQsFAAOCAQEA
|
||||
o8opPN0cswtaYPXhgueVfBkW5I7ftXxj8X+aHmz7Chniit6BweffuMCtLH9zrs2o
|
||||
ppK+XnxDAeu9jj+J7lOoxVbc7fnXcgQGh7zE8hNoQ0tS8Z/sShO1tTxTubFdTD4F
|
||||
YJUkKg4mpcj1TUjz8f0zdG7uo1l1nXiEey4wR0pFsf8Q1c8h+JMP0/fzsM2/o7O1
|
||||
7qniLp+gn+fYy3EHJgxbVGZoVz/uU4LyPdD3T+vznum+6RggeX72OJ1/Y9UKnJ7f
|
||||
HrKXocJpfENM9pmlhHuqwwR1d96JdkGyfVrRObKL2dkRRkPA8MV0LTQq6sVbEsxS
|
||||
Ka4voRAdxNpl3tCiPaCEuA==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
ALNmRewqFkXD
|
||||
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
|
||||
g3JmsAmHh8HP
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIGBDCCA+ygAwIBAgIJAPlHYZzp1daIMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0G
|
||||
A1UEChMGRG9ja2VyMScwJQYDVQQDEx5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp
|
||||
bmcgQ0EwHhcNMTcwMjE3MDA0MzE3WhcNMTkwMzA5MDA0MzE3WjBbMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xDzANBgNV
|
||||
BAoTBkRvY2tlcjEWMBQGA1UEAxMNbm90YXJ5LWVzY3JvdzCCAiIwDQYJKoZIhvcN
|
||||
MIIGBDCCA+ygAwIBAgIJAIBGh753nFCxMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0G
|
||||
A1UECgwGRG9ja2VyMScwJQYDVQQDDB5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp
|
||||
bmcgQ0EwHhcNMjEwNDAyMTMwOTMzWhcNMjMwNDIyMTMwOTMzWjBbMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNV
|
||||
BAoMBkRvY2tlcjEWMBQGA1UEAwwNbm90YXJ5LWVzY3JvdzCCAiIwDQYJKoZIhvcN
|
||||
AQEBBQADggIPADCCAgoCggIBAMFzgrRu1r3leMdD19sSgfqW85Bi4FCv6LCDbnAO
|
||||
WQKkwooP9LUNGs+zvFru7LbDbEyyIi4TsP0ZSsDcxinw2GYglLw6DmgmRC16RY0W
|
||||
NTckgHsVDTmxRVERFWpKh0ZgEX7p8xCvbZooC6vTNtCWvjKeEHxTolPbSiaOyIyp
|
||||
|
@ -16,54 +16,54 @@ voL/5206/Npd0bCodXGX62ARUdEuTayG5a7fJ6NCZa+C7W6hhAs9Mvw6LC8Webuw
|
|||
+wuzFE1v/Ktt2dLkwtvYC2N+J3nmxbBN4y0Uud0MqnO+SFV+Ib2nzlLKtZoNAG9x
|
||||
kcMQzuubdsj0HHq0ywYCCkjDaz+ltcUqF7NNhRJL47ccNfOumJD5LY9KbRPeZ19X
|
||||
f63g0iniyBFxcAmwwCql2PX07i8X4FcteH5J2ehiLuAJ8inz7uwMPEVFSr8n3AqS
|
||||
y079AgMBAAGjgbkwgbYwHwYDVR0jBBgwFoAUupdDG81X7//TnYCdldrf396Did0w
|
||||
y079AgMBAAGjgbkwgbYwHwYDVR0jBBgwFoAUF1UWfhLmmQ4B9xzoXmOg3U2qnFUw
|
||||
DAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYD
|
||||
VR0PAQH/BAQDAgWgMDcGA1UdEQQwMC6CDW5vdGFyeS1lc2Nyb3eCDG5vdGFyeWVz
|
||||
Y3Jvd4IJbG9jYWxob3N0hwR/AAABMB0GA1UdDgQWBBQdk/HK+26ISl+VOgKh5vtV
|
||||
WRmqWzANBgkqhkiG9w0BAQsFAAOCAgEAFOxSPTgsFvF7lP/PPRr5faJGypEafRVk
|
||||
YuyrSu/45O2L1BZLsiE4TjLVgiNGHq0ECL8GCMgHgfFeWrbqlFpvHc3F8xiwzKZq
|
||||
GA0ig2ql9JGxGyancgHbkA5xkfGLY139Q8ORmCn6QCUF05uSiosckGuJ4ke/Xz6v
|
||||
MH2OCcW+tRn+KsA+eurDueFjjqLAOE04d1PQ3sHIkeTlMgFVhj19oPp6lcr0VoN4
|
||||
rUPC1wzBNwp+odenl/84/9UiDTIUfmW7k+jxVEsEDMRh5xyM9yrNMkiuvOXOVc89
|
||||
IkaJPZBX+wynjPgStsfZNRHJWSY2NlIyQI1/Y/tjjygSIjR6HmOFaKp5y+2TNZfA
|
||||
r1yNwI1nRN4HrkA+zxhoIgidL/mEwL1NGiLgS4fZc3V71VSqGomGZKfqbQotPCBP
|
||||
qTH875io9wQWPLCMaNiTocrLiTLQREdW0OmVxkn8PEwImRb7lLhvVA2I1tVB4cXd
|
||||
EQME2qvp2Lx6lGJJHx0X/kwK6f9aOn5I9VNAPcpmgzk4wvlylFJSII78TSg8LBlE
|
||||
xYMr5G5Y5D6Z/WS53pj+qRxtRMTjZXHBUFuKicWHZnM9MtIAXS2m0G16gYMRkCqJ
|
||||
VUdLIBaY8FC8efdPXP/7yd9STdnCKAaJ8d80ZbSSJSAPDK3r0DKWw3Nj1gioIEx+
|
||||
vXLaxnuP4Nc=
|
||||
WRmqWzANBgkqhkiG9w0BAQsFAAOCAgEABAun3W0W+nZwXlF/pM4ZmKRecem5ZW9S
|
||||
OXqFOugv0n51tFfJz+XDbaMTLmhcfhmzeEEFrklTvVrQtsZ/FxhWGu5jHWqWJgX2
|
||||
sNFqD00KHNFtQvdAMw43OIr3j9qCeGqfPBJo17NfJzeibmUlx1wQwssrZZVlLccf
|
||||
q44m3489HOR9LwOMneGIX0MzGnKZbDmyPf0OX/KLCiBi7A0ASqRX017HyZoLTMBd
|
||||
j/P/dvDiH+Xy9sGigrgzvuU8AC3P/IaIDr9aoAeusMDUGaviK6ddETFTj+rmAnW3
|
||||
aOP0PXliF34wdD1FEAyps4ffPi+PJRsxpWQKUbtbFfo6FK+5MTXCXM75AeD+51VT
|
||||
t1ak51VI/Cq2JckboGXpRsR6OHhC7+5AtndWzIBlLByWPsUObLQsGvAlwRBlkVGr
|
||||
ioulBZxMKkUVxPyVrkRKyNORowYETBzzwqY/kWTQ82yeNnaRms0dJXblwQbKdofV
|
||||
eBhFHKpKHjIYVjBr3/4omoqE++cOLaa4TTcB3AledBK5EbWNfTlrZ27oEiEfYefT
|
||||
qkRdPbLLpoirsFceuxSM8DW59J8EfmL4WGkdjwOmh6KdakkEsS8U5sWikv+8QQHt
|
||||
FEslsHBzapQB9LShG7xbqYpt8eZN/HO7rCLV53lzLOzLS6t1bHq+PZxQ4iQG3VWh
|
||||
OG3DvNFvPhM=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
ALNmRewqFkXD
|
||||
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
|
||||
g3JmsAmHh8HP
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
ALNmRewqFkXD
|
||||
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
|
||||
g3JmsAmHh8HP
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF1TCCA72gAwIBAgIJAKfYxoqVGl7nMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0G
|
||||
A1UEChMGRG9ja2VyMRowGAYDVQQDExFOb3RhcnkgVGVzdGluZyBDQTAeFw0xNzAy
|
||||
MTcwMDQzMTdaFw0yNzAyMTUwMDQzMTdaMGwxCzAJBgNVBAYTAlVTMQswCQYDVQQI
|
||||
EwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMScw
|
||||
JQYDVQQDEx5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3RpbmcgQ0EwggIiMA0GCSqG
|
||||
SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/VjDUa9JQLhfnHvonnF+yxsbwJSkFWbad
|
||||
ci5boMGakJGsjgjDK+IfzzkRNbA3aYSd27UX5Vz+nPyt3BLJHIhlxOW9iDA6nqWb
|
||||
q/eJn5eV42eXoR+6ttrNzFWLZOTT+v5ZGQJYOKmk4vmZT/xoHTgHlsRshpj3EFRd
|
||||
PxgolcKMSsZpSD8I2sgUYwh+rmI/nbesZGmb7mjQxMb2jtZPhxlHpSwL79RlFw4f
|
||||
cS0x7qts0WsZtY8pa3HWxSG0x4uWuNkwivojq0vpsFvynpLY6t7jdb0Vu7iUgMAA
|
||||
t8AsbCt+uTv4KhyJw5rD7kg+Ad55QqVuTqtwoz0+SBREHm67q8gn/skTQT3ro4pB
|
||||
nQdlAQDNPBa3JnZvXmLDkgHdVCKZtaarm92L0P5byIUo+UtDA4j+FkkRXLyVC1FU
|
||||
O3awwbAOIK2/VznRpaKoxEV7p2sp7pkqFIFAX1ALUXQRjuxd2EPuTn4HgMdIta6e
|
||||
xnZjTxcehUzpSxMBEnlfSNmYvSWD6enMDr0ZuRU1L5ZnLU6RibBtMREqfTaHAygf
|
||||
kPBRO6AHB+K5OPK5yVwzp4G8yve5FAUo0YnNTnaIYs7ZYL14eOzPH3RIkRE+F8hB
|
||||
A8YB5vFEAbjto/ZxeikvCVk6jNuuvw5mbHN9yHIfD7qI1pPY54EIEGgxVZGwaJTj
|
||||
mRKvTbf6JQIDAQABo4GGMIGDMB8GA1UdIwQYMBaAFMXa5XX+ba5Jf0YRuL6UqjtU
|
||||
QS5ZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG
|
||||
AQUFBwMCMA4GA1UdDwEB/wQEAwIBRjAdBgNVHQ4EFgQUupdDG81X7//TnYCdldrf
|
||||
396Did0wDQYJKoZIhvcNAQELBQADggIBAEKzd2/OInjHpFNmqJnuAvrFJPQHhwAQ
|
||||
CUv4HwLqMdRbKLhAF2Xc687K0rJaW6ZpvvCWP/bsgzDi7bcti+sbpRtutL98ollq
|
||||
NtqEBW7pW3ljvQteBHiXCPzHmSdKBG5B972mFvIi1k9NpeHcEz4y9q5s9BBW5hIu
|
||||
6UwKIQSZ/dQGsukgQXe3lXJ/MjRg/QK0U1Xn/ABknm75vMbdc7L+WLvmrEY11NAy
|
||||
3vso6qm7k2elDLUVmqIwMU+r9pfGZFi0nQCxfiRhW1hZyDxzpngBZFnRppiO+2CX
|
||||
u16yiJfipD5wHZc1NjZ1WQ+XuoUhDgV1yzGpgRGtUdX4fByEUqNZb1GbY6UdIjmx
|
||||
LvwT2SJnEcv9irGlQU2D4mm5oXgeZXJhxP3gMxEtw9bZS3tUDMWkMD5GCdo8T+FB
|
||||
tjlGIe8Uh8R4wn33EYDMq+qFeUe+NiMDsVcFIlKWSwCRvmsTB3gvTYYkssuyS65Y
|
||||
8Ngdsy5GIBhMEsLnZNdwmP7NJ41CECqlojK9tQeu8KAhB7xsKibbwPUbec7whQFl
|
||||
82vOLgag7Fn3V1eVonqxk7uBt0nriV39/hXifPwBRo3WLoVLUTs+IAOiLapLAb6o
|
||||
LCQV7ymBRptOyj9bPPYV+NJrfr/5IlkNamioWlbzH3SJdvyp5ldZH/2vciItlO3s
|
||||
ALNmRewqFkXD
|
||||
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
|
||||
g3JmsAmHh8HP
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -170,8 +170,8 @@ done
|
|||
|
||||
# Postgresql keys for testing server/client auth
|
||||
|
||||
command -v cfssljson >/dev/null 2>&1 || {
|
||||
echo >&2 "Installing cfssl tools"; go get -u github.com/cloudflare/cfssl/cmd/...;
|
||||
command -v cfssljson >/dev/null 2>&1 || {
|
||||
echo >&2 "Installing cfssl tools"; go get github.com/cloudflare/cfssl/cmd/...;
|
||||
}
|
||||
|
||||
# Create a dir to store keys generated temporarily
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC8zCCAdugAwIBAgIJANrYVzo59a4lMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
|
||||
BAMMBSoucmRiMB4XDTE2MDQwNTIzMDcyNFoXDTI2MDQwMzIzMDcyNFowEDEOMAwG
|
||||
A1UEAwwFKi5yZGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD54K+k
|
||||
KRjKH33vsZn98YY8bE4p+wJ7OjlVcKdojlVxQ8ZlNM9kip4jDXQK4P90PdxkT8t2
|
||||
0xxZJqEh2oaOJ9dTi96M0stleeHgud2i862g15iKR9djvLXGaYV50FyT6ZDqaz1y
|
||||
2KVS0fNy/rKKo8exphhKUymLgroTd9+biNFQ701EfqyNzDHbRCyWD0nIJah218tR
|
||||
lCCfYfYzPiPIKDc40wPSn16f7pKxLTxYwMSk6iQ2rrF/uRz/Pn0nIjfFsEih15Bz
|
||||
XibZsToru/SCmJv1T8mYPRccQ+hLfoFpg81pAwcHvOCI8zYkzgNWwTrymlxn65If
|
||||
EhnjexODf3p7EgnvAgMBAAGjUDBOMB0GA1UdDgQWBBSABTfpeRP7nqHmtXaA4Ai8
|
||||
E7IGqzAfBgNVHSMEGDAWgBSABTfpeRP7nqHmtXaA4Ai8E7IGqzAMBgNVHRMEBTAD
|
||||
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA3rtK/vl2bAxCk1aF5ub4KVfsQUru7gRfj
|
||||
UvFZcLGzigAXQ1zHX5TEaivUanDkXmEJ2/sTpHHaZDIDMG6776Jlq7I+rWurVKW3
|
||||
Lsq05KMW095bn0om4nGrPLZRyfhubJ27nmQhri/+zWCaWkTe1kVpAhjqDyWqkYw4
|
||||
/roVk4r9P3hf7M1bB9EK/MZU1OLIAGlSn3MaDUewpgwYZDSdItHm1XS56NL3xKgF
|
||||
r3WtsbRPf71sldL24/YnC/ZLcQq2plrDN7TYv1Xxfo+biI8JWGgQX2bkOSmi7SZ/
|
||||
46uKF1tdJu6xyZdTko62SFPO9A6+KeY1wosmGc+RAiebPQEoeMUC
|
||||
MIIByDCCAW6gAwIBAgIUU9sydVXy1tXRw/DTtbiVJ75fn4gwCgYIKoZIzj0EAwIw
|
||||
QjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNp
|
||||
c2NvMQ4wDAYDVQQDEwUqLnJkYjAeFw0yMTEwMTkwODMzMDBaFw0zNjA0MjMwODMz
|
||||
MDBaMEIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZy
|
||||
YW5jaXNjbzEOMAwGA1UEAxMFKi5yZGIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
|
||||
AAQHPEygXoJGVI5ATUGXh672Qs0wT5O+Xp9i0Eg+7yNJG8WN25gkr8mKWPiFn9K4
|
||||
JJtpRzwwkDUoaH8HUKLSw+/bo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
|
||||
BAUwAwEB/zAdBgNVHQ4EFgQUGVkaED9hYhVvD0T/u6Edqd2/290wCgYIKoZIzj0E
|
||||
AwIDSAAwRQIgcnRGRoZvCmss3tFY+0R55SDLDqwEhNKzMhd/WJaWXukCIQC6aUYr
|
||||
zrfOSvWsFa85unYsMeuWtkihKFzNtZUMrkjQOA==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC8zCCAdugAwIBAgIJANrYVzo59a4lMA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
|
||||
BAMMBSoucmRiMB4XDTE2MDQwNTIzMDcyNFoXDTI2MDQwMzIzMDcyNFowEDEOMAwG
|
||||
A1UEAwwFKi5yZGIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD54K+k
|
||||
KRjKH33vsZn98YY8bE4p+wJ7OjlVcKdojlVxQ8ZlNM9kip4jDXQK4P90PdxkT8t2
|
||||
0xxZJqEh2oaOJ9dTi96M0stleeHgud2i862g15iKR9djvLXGaYV50FyT6ZDqaz1y
|
||||
2KVS0fNy/rKKo8exphhKUymLgroTd9+biNFQ701EfqyNzDHbRCyWD0nIJah218tR
|
||||
lCCfYfYzPiPIKDc40wPSn16f7pKxLTxYwMSk6iQ2rrF/uRz/Pn0nIjfFsEih15Bz
|
||||
XibZsToru/SCmJv1T8mYPRccQ+hLfoFpg81pAwcHvOCI8zYkzgNWwTrymlxn65If
|
||||
EhnjexODf3p7EgnvAgMBAAGjUDBOMB0GA1UdDgQWBBSABTfpeRP7nqHmtXaA4Ai8
|
||||
E7IGqzAfBgNVHSMEGDAWgBSABTfpeRP7nqHmtXaA4Ai8E7IGqzAMBgNVHRMEBTAD
|
||||
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA3rtK/vl2bAxCk1aF5ub4KVfsQUru7gRfj
|
||||
UvFZcLGzigAXQ1zHX5TEaivUanDkXmEJ2/sTpHHaZDIDMG6776Jlq7I+rWurVKW3
|
||||
Lsq05KMW095bn0om4nGrPLZRyfhubJ27nmQhri/+zWCaWkTe1kVpAhjqDyWqkYw4
|
||||
/roVk4r9P3hf7M1bB9EK/MZU1OLIAGlSn3MaDUewpgwYZDSdItHm1XS56NL3xKgF
|
||||
r3WtsbRPf71sldL24/YnC/ZLcQq2plrDN7TYv1Xxfo+biI8JWGgQX2bkOSmi7SZ/
|
||||
46uKF1tdJu6xyZdTko62SFPO9A6+KeY1wosmGc+RAiebPQEoeMUC
|
||||
MIIB9TCCAZygAwIBAgIULL8Z8vZACRNgGMqLpwhHds2Z7pcwCgYIKoZIzj0EAwIw
|
||||
QjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNp
|
||||
c2NvMQ4wDAYDVQQDEwUqLnJkYjAeFw0yMTEwMTkwODM1MDBaFw0zMTEwMTcwODM1
|
||||
MDBaMEIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZy
|
||||
YW5jaXNjbzEOMAwGA1UEAxMFKi5yZGIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
|
||||
AAQpjC0yj0kLq8S7XCPI/u0KxSEr5+yP1hkrftHCg1E0aP3Qe3lkltU5C80YTJM1
|
||||
N3ss+7+kuRff9CF6tCo2kPzio3AwbjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw
|
||||
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFE8M
|
||||
ojJx7oQWlevqjIyM2BstneiQMBAGA1UdEQQJMAeCBSoucmRiMAoGCCqGSM49BAMC
|
||||
A0cAMEQCIFfT+vRrnMhhd28YPeG4kGzNs2Y7UTaMiuqxhgOcYsXrAiAZQt3o+Nb3
|
||||
pMcJKFruTkM71e5TFGegFG2wSnhqz/u6gA==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,5 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA+eCvpCkYyh9977GZ/fGGPGxOKfsCezo5VXCnaI5VcUPGZTTP
|
||||
ZIqeIw10CuD/dD3cZE/LdtMcWSahIdqGjifXU4vejNLLZXnh4LndovOtoNeYikfX
|
||||
Y7y1xmmFedBck+mQ6ms9ctilUtHzcv6yiqPHsaYYSlMpi4K6E3ffm4jRUO9NRH6s
|
||||
jcwx20Qslg9JyCWodtfLUZQgn2H2Mz4jyCg3ONMD0p9en+6SsS08WMDEpOokNq6x
|
||||
f7kc/z59JyI3xbBIodeQc14m2bE6K7v0gpib9U/JmD0XHEPoS36BaYPNaQMHB7zg
|
||||
iPM2JM4DVsE68ppcZ+uSHxIZ43sTg396exIJ7wIDAQABAoIBAQCml2riSlfxoY9H
|
||||
t6OQD29MZ3SxPl0IJOhGk0W5SnOigOoLXWsLf/MwMW71Nc56BCgkZKKkxNi4gy2Y
|
||||
MWXV7q/7TlwAjST3sYurVJ90XXubqUFUp9Ls9spFzuIjNYwTPPvVncuo/tEx5zGk
|
||||
sDP+hHTFdpPpMYqYLX67LgdRXaUXjDI7pg9oOAj9Xl8pHi5TP/DXHo+swF0F3r54
|
||||
EqlS9PnObszI7e/ReQzh940nEWzdHle0hHinfeDCpW3S7P5xb39NEUC55ogkFNWX
|
||||
2cbJJtS8dqgcBmnSK+0WetXEhydrk/5GmIu+gnyGLzuidZYOQn3gWb7ZiXJJFVX2
|
||||
xfGji2vZAoGBAP1TfZsxbmcM7i7vxZQuPIbNTAP5qW/6m/DA8e1+ZMe0+UC6gvO9
|
||||
XgYvJ6BGckVTZWCxmDfsNObqvkjvMS8m2/FeDCL6NCVDtS+i8kq+LkR49sYdAvxw
|
||||
DMVqJx77bh6FbO8L5TWuvHZ6/0kbD8JEAZ1p8n4WAYDsyMNM/gVePqLtAoGBAPyD
|
||||
4J64g9549h2qnaNKA9Mph202LhgPgmlctM/DPNM13+su+AXC1S4JSZv2YQMq5nty
|
||||
yHXin1TUy0p8mt4+w75jCatulkOLKbnl3NYM6uzlXP0RSsStA4EycWQ0BBg1DFwW
|
||||
BxOxsnTr0rBzSeFTZav8eCp/VYlJnb9sUlwjbzjLAoGAUPva4L0ZtTnt/vVJ7Ygm
|
||||
c1W4ImEy6IhuR7X24VyRrUJOmIHHkVINd96lRVif+Uei1hmQNvh9JQEQWdKVn6RF
|
||||
ldDiAmCIQQ13I8ZsvLY1plAhW840gSz0+DtqTD5Gwt0WqQjdep7kwt+pMt7C1/DT
|
||||
r1YKXoJ8cpG/0KeRYXfygDUCgYEAxRnfM6UM8ZNzcHajszhrweCRn/KBijBY+Arv
|
||||
65gWmzpbPQUdfcm1gsinF0D6OnG7FDLlO/cXrSyoPc0DSWSuf6ZoftLEIZa3jC5a
|
||||
8Q2GNkFWEwbzWI8/xBHupmtfotGNgzeCcKHsjQ0iGK70xRfGrbdUyL85sf6vTiKs
|
||||
KtVR1H8CgYBifRUqy77A0eaR8SjTOuI7izoxcJH9DwfBQmg4h5g9jorf180R9IH7
|
||||
V8NWqvjLFbNI2kxQ9SbDTex0XRE4gdSmTeFywtCrSBgP594XK/KwKGhDHe96ve1G
|
||||
/CKGwCAhMKBfZcrPccXDGp0CbWLemTTKmWsfO4i4YvUhTCXCRokYYA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIPyX2O9nWTGgRPAWwTX5oxuy1wUcIJCuOYtfjHkWvSTsoAoGCCqGSM49
|
||||
AwEHoUQDQgAEKYwtMo9JC6vEu1wjyP7tCsUhK+fsj9YZK37RwoNRNGj90Ht5ZJbV
|
||||
OQvNGEyTNTd7LPu/pLkX3/QherQqNpD84g==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
rba7O3YGSuScQakjt9mw2Q5ISwImkRHF3qE=
|
||||
BBRHApr7kqsc+nK64kWf307KRqWf4TANBgkqhkiG9w0BAQsFAAOCAgEAg7lggbLA
|
||||
QPl6Ua+utbUGbl/A8hmo0acGcdUCTN1/leAJFza6RHwYVKzNPJJn8OOSxGNRnO7U
|
||||
h+UVcdiJC54iUCeVMQFYMXopTVeA2SAkIXVSytuSy31Hn+sf7augwROtIq08/7k8
|
||||
WpMImLdb7BAOQrTxro4cjvwOIdi5Ep19XmHaNFMUANhjJ9elNYH77ZyX/31zcpiI
|
||||
KrBCYo1FqVgDha11d2Sq/0UCxRBGYhq4gNb6NR9cdKLfY3XkQ0oQJSQW9t4F2137
|
||||
GpVq4KUSHVpKj3TTneL+hCtBGfnYzVXveYVFMJXSz1NVkIMiTDllx7MfhfQ1OBYt
|
||||
eQnIF7axPWgrM5ndioAMPeYGBicbPtIHFjYgNku2LxrTQ9KkOVOgAsnWiurvxNLb
|
||||
9oXg27PtEIaR6wACGLi2iIeZtH5zXyURybFr58nfngP9FCkNJpSKaLLmv77XQCNY
|
||||
fW6UjiaTUd1IlOxVC5+Yl9tnUo69NVOB2FEUK2gUwt7K+R3xuOPcGAdi3uXuTUuE
|
||||
LqPHX3FrPvVFB0AIorv9sbDZsyANGlHiBrnEMgb5bzAv8oylmQ/TnvBIdxi4CHfb
|
||||
SI+z6xZzWeOwGkqinxAPUO9aHqiYBe4reXrLOS+SEit2Al6fgFiZJ+ImX6aAxApt
|
||||
FYeLBznZE854WQV0jmEvPR0u7+EYIny4f/g=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIFADCCAuigAwIBAgIJAPlHYZzp1daJMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEPMA0G
|
||||
A1UEChMGRG9ja2VyMScwJQYDVQQDEx5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp
|
||||
bmcgQ0EwHhcNMTcwMjE3MDA0MzE3WhcNMTkwMzA5MDA0MzE3WjBgMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xDzANBgNV
|
||||
BAoTBkRvY2tlcjEbMBkGA1UEAxMSc2VjdXJlLmV4YW1wbGUuY29tMIIBIjANBgkq
|
||||
MIIFADCCAuigAwIBAgIJAIBGh753nFCyMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0G
|
||||
A1UECgwGRG9ja2VyMScwJQYDVQQDDB5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp
|
||||
bmcgQ0EwHhcNMjEwNDAyMTMwOTMzWhcNMjMwNDIyMTMwOTMzWjBgMQswCQYDVQQG
|
||||
EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNV
|
||||
BAoMBkRvY2tlcjEbMBkGA1UEAwwSc2VjdXJlLmV4YW1wbGUuY29tMIIBIjANBgkq
|
||||
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmLYiYCTAWJBWAuxZLqVmV4FiUdGgEqoQ
|
||||
vCbN73zF/mQfhq0CITo6xSxs1QiGDOzUtkpzXzziSj4J5+et4JkFleeEKaMcHade
|
||||
IsSlHGvVtXDv93oR3ydmfZO+ULRU8xHloqcLr1KrOP1daLfdMRbactd75UQgvw9X
|
||||
TsdeMVX5AlicSENVKV+AQXvVpv8PT10MSvlBFam4reXuY/SkeMbIaW5pFu6AQv3Z
|
||||
mftt2ta0CB9kb1mYd+OKru8Hnnq5aJw6R3GhP0TBd25P1PkiSxM2KGYZZk0W/NZq
|
||||
LK9/LTFKTNCv7VjCbysVo7HxCY0bQe/bDP82v7SnLtb3aZogfva4HQIDAQABo4Gw
|
||||
MIGtMB8GA1UdIwQYMBaAFLqXQxvNV+//052AnZXa39/eg4ndMAwGA1UdEwEB/wQC
|
||||
MIGtMB8GA1UdIwQYMBaAFBdVFn4S5pkOAfcc6F5joN1NqpxVMAwGA1UdEwEB/wQC
|
||||
MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIF
|
||||
oDAuBgNVHREEJzAlghJzZWN1cmUuZXhhbXBsZS5jb22CCWxvY2FsaG9zdIcEfwAA
|
||||
ATAdBgNVHQ4EFgQUDPD4CaXRbu5QBb5e8y8odvTqW4IwDQYJKoZIhvcNAQELBQAD
|
||||
ggIBAFUC3GDxayLiHZoq6uqENrmS/4KcoWXtvoJ0J7jusxAGw8DpIGAXTKjByXnL
|
||||
L64dsOUKUNXigd0lLw9nWq6oAK4alIgbvMeAr5984SHcPjL2VOetkN8spn4nn/2h
|
||||
WTe7MJqCyDJB/6FBokYcybkprsKgi8fV/MXciLwZCfylzh55ennDufeDXV2WyXVl
|
||||
pAWnR8FV4+t6Ue6OVec9637yxWmhne4l8MVSZjkzDOMzNUM/+tzkiCSMW7VP0MpE
|
||||
yHihO8p4+g/hKWdVJldCh6QnnNqz2E+iQGrBY3kO72UF+aaOfA77UzantHE2gkNi
|
||||
ZuFPgTHwUpjTShQxLRkvt1+sRg2xm3oN5cVzEfFyYKAdyH8IhiNTBniKXI2XKuPj
|
||||
+HuIWUu1t5MRVs30Iod9+DR6T6UU6IuAznlWIhMUkoPcpqTGQI8p+WYF+bp3addt
|
||||
i5uBXVWrZ/BLv7E2n1Ly4ZbUt06EzBaOcoRv2Gl5KR/FuYBX03mr5/XY4THANAqP
|
||||
C9HMtN7pZpDKNKBYC+l5u+V7JuFEiz7Tq62oZKvbUILs2GWBCb7pe8KoDJscjP/4
|
||||
Q2uIkOZaEi/58WIvqIATFvqt12OLpY1uavkU7+DwVwsDjIF3CT11iYsnKisdXEtj
|
||||
AJkMIFHWe+nwBIKldfd7RYT5SBdWPii27sW9IUtAb817Z31p
|
||||
ggIBAHtxdiLJKrYPi/ShD93AGDMPzcqa1ghqBcDGga06SUUC7fvoYROdKBXj2SJs
|
||||
my6DIA0xhRCW9d68rUHG9YqIBlt4aODLYTChJHRoZkAL+j1CJ+tEzyRU974jO6cG
|
||||
gUc4SagfAvRo+PWaLn9cKrumEIZGtFTAfWCqm15OgZRdBnPXqTrKNcmBok9sEKla
|
||||
ZQLWSa95KCAyK2oyl5lgCAh9IAzEmuHLUEo62pDLhuKFwpzD/Qbp1f23hkCHH3Qa
|
||||
tQa+9xqBbgLU39TxRyk8CINVtA4PDLkpssKHs3s5necmGcLDpYphuQDQ7vXZW4GZ
|
||||
nd0qtl1vAJfZqtHs2VGAzQdRfLRG/6+x3+/1a0Vp1gZngvOgKpQb8tY/nQOICHSm
|
||||
TbjByhAIHzkPocAwOmZiedbTXdtDTthSqa0PEeEvQyHPDfDvNwnLRChRZG72nptT
|
||||
Emny6wWqQIvgqOcF0o9Ewx+IGsgnbcrV4WuKgpT+yZpg75cChXXnLjo04GR3ElRh
|
||||
XP8Hr98Yb2wFRpMTzlizl3SJDspgeIgBcsQSwqI11VmCpwBmdF8J1ZNUSrALwZI8
|
||||
Q3VtRuuFkjWVLfuNMDOpDM7Cu54vlCrkUkWNsnEfOM735VHor8tyECHvmWvAo5HO
|
||||
5aPbhe6Lzwgr+YQtGuK939qOdcylRg0CpH21bZQkBU89+u+M
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBpDCCAUqgAwIBAgIJAKMU61pdVikDMAkGByqGSM49BAEwLTEPMA0GA1UEChMG
|
||||
RG9ja2VyMRowGAYDVQQDExFkb2NrZXIuY29tL25vdGFyeTAeFw0xNzAyMTcwMDQz
|
||||
MTdaFw0xOTAzMDkwMDQzMTdaMC0xDzANBgNVBAoTBkRvY2tlcjEaMBgGA1UEAxMR
|
||||
ZG9ja2VyLmNvbS9ub3RhcnkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASg0Cmh
|
||||
SHFK/18+NIUaBkgVcWJSCgc6KInu+mTMpSVuWHLXSvVF53oKNjWeA9W2Wk9FDVTz
|
||||
/xEHbdAGSVDVn34Xo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDAT
|
||||
BgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUC25FC+NAuXIFTB62LHa6GtL2
|
||||
ARcwCQYHKoZIzj0EAQNJADBGAiEA7Z4+BKZMbxtkT8WxZ1dSgj0s/zAQXaOyb7Wh
|
||||
wo6nAtgCIQDdyb/8QinrwsaZLeCiCE8LdGfE/+L2qiI3KMlEU0ktEw==
|
||||
MIIBozCCAUqgAwIBAgIJAKgZDYCHWLzvMAkGByqGSM49BAEwLTEPMA0GA1UECgwG
|
||||
RG9ja2VyMRowGAYDVQQDDBFkb2NrZXIuY29tL25vdGFyeTAeFw0yMTA0MDIxMzA5
|
||||
MzNaFw0yMzA0MjIxMzA5MzNaMC0xDzANBgNVBAoMBkRvY2tlcjEaMBgGA1UEAwwR
|
||||
ZG9ja2VyLmNvbS9ub3RhcnkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATBdRsJ
|
||||
b5JBHzEJ5fZn3FzdTkac4zvUIR+cCnCzk7YHTIr3sUXB2FStNwyOSeUJr8tSJ1IY
|
||||
2nI1u3vh5VSYc/f0o1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIFoDAT
|
||||
BgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUzhXSPuUSRCkHQFu6a6O8VjNM
|
||||
1AkwCQYHKoZIzj0EAQNIADBFAiEAsHbg7qOoPdkbttNq5C3Q9hspCEOH4J9KgN/a
|
||||
N5xlsIICIGs4VygKIdx1xiR3aJMhjpOy37qpTR57tf7U7FZTV8lg
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBvjCCAWSgAwIBAgIJAI4W1iagD9wJMAkGByqGSM49BAEwOjEbMBkGA1UEChMS
|
||||
c2VjdXJlLmV4YW1wbGUuY29tMRswGQYDVQQDExJzZWN1cmUuZXhhbXBsZS5jb20w
|
||||
HhcNMTcwMjE3MDA0MzE3WhcNMTkwMzA5MDA0MzE3WjA6MRswGQYDVQQKExJzZWN1
|
||||
cmUuZXhhbXBsZS5jb20xGzAZBgNVBAMTEnNlY3VyZS5leGFtcGxlLmNvbTBZMBMG
|
||||
ByqGSM49AgEGCCqGSM49AwEHA0IABKdTvQvZJoZAQ+9qluOMtwjvxLvg9rVJMMhd
|
||||
0oSjFWD7/mCqxCq0Nvy6jcHLaOflu4/+xPWoXSkHGDJVbc3tXDqjVDBSMAwGA1Ud
|
||||
MIIBvjCCAWSgAwIBAgIJAPMxgMmwlQenMAkGByqGSM49BAEwOjEbMBkGA1UECgwS
|
||||
c2VjdXJlLmV4YW1wbGUuY29tMRswGQYDVQQDDBJzZWN1cmUuZXhhbXBsZS5jb20w
|
||||
HhcNMjEwNDAyMTMwOTMzWhcNMjMwNDIyMTMwOTMzWjA6MRswGQYDVQQKDBJzZWN1
|
||||
cmUuZXhhbXBsZS5jb20xGzAZBgNVBAMMEnNlY3VyZS5leGFtcGxlLmNvbTBZMBMG
|
||||
ByqGSM49AgEGCCqGSM49AwEHA0IABCPF7i8j0b1rmkCosZ8lGBJKAlHXnHK59GmO
|
||||
FeHos2vk+C/oSfByUG+IChg6iT3I+VklK9ZEJSQZh+hLvTzC1sWjVDBSMAwGA1Ud
|
||||
EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB0G
|
||||
A1UdDgQWBBSB6K6DihEBUuioQ00YAG55gST2ITAJBgcqhkjOPQQBA0kAMEYCIQCG
|
||||
+Sk2UhufFp19BxuKO6mlXHz4fGblS6WxSsISesZ3aQIhAMZMXg9CkfNwFUXOxIwW
|
||||
fspZc4rX0tz9Rg9kxts+YZk1
|
||||
A1UdDgQWBBSOqiaAPOOaTRVUboPLriR7+YmoxzAJBgcqhkjOPQQBA0kAMEYCIQDA
|
||||
pUi6zMk0Yt5tRuBsOGys3Kut62wvsa3NCWemfypgvAIhALimGLbBPEYNBkk0hD5H
|
||||
yp6c5DgMqDHzBiMXnMw3DIkY
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
module github.com/theupdateframework/notary
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d
|
||||
github.com/bugsnag/bugsnag-go v1.0.5
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 // 1.3.1
|
||||
github.com/docker/distribution v2.7.1+incompatible
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/gorilla/mux v1.7.0
|
||||
github.com/jinzhu/gorm v1.9.16
|
||||
github.com/lib/pq v1.9.0
|
||||
github.com/mattn/go-sqlite3 v1.14.0
|
||||
github.com/miekg/pkcs11 v1.0.3
|
||||
github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.6.0
|
||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221
|
||||
google.golang.org/grpc v1.47.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bitly/go-simplejson v0.5.0 // indirect
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b // indirect
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 // indirect
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 // indirect
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
|
||||
github.com/gogo/protobuf v1.0.0 // indirect
|
||||
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 // indirect
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.4 // indirect
|
||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/magiconair/properties v1.5.3 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.0.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.1.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 // indirect
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083 // indirect
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7 // indirect
|
||||
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 // indirect
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
|
||||
gopkg.in/cenkalti/backoff.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -0,0 +1,288 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6DKrR4/ljxn6SF6nURyu785wKMuQcjt7H3VCQ=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bitly/go-hostpool v0.1.0 h1:XKmsF6k5el6xHG3WPJ8U0Ku/ye7njX7W81Ng7O2ioR0=
|
||||
github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
|
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y=
|
||||
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/bugsnag/bugsnag-go v1.0.5 h1:NIoY2u+am1/GRgUZa+ata8UUrRBuCK4pLq0/lcvMF7M=
|
||||
github.com/bugsnag/bugsnag-go v1.0.5/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ=
|
||||
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 h1:OGNva6WhsKst5OZf7eZOklDztV3hwtTHovdrLHV+MsA=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
|
||||
github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 h1:yWHOI+vFjEsAakUTSrtqc/SAHrhSkmn48pqjidZX3QA=
|
||||
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b h1:HBah4D48ypg3J7Np4N+HY/ZR76fx3HEUGxDU6Uk39oQ=
|
||||
github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI=
|
||||
github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
|
||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o=
|
||||
github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=
|
||||
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.5.3 h1:C8fxWnhYyME3n0klPOhVM7PtYUB3eV1W3DeFmN3j53Y=
|
||||
github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
|
||||
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06 h1:HfhRu7DulhCtYuCwmHYHdZ0pR/qYrCde5uhuemqD8rI=
|
||||
github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083 h1:BVsJT8+ZbyuL3hypz/HmEiM8h2P6hBQGig4el9/MdjA=
|
||||
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7 h1:hhvfGDVThBnd4kYisSFmYuHYeUhglxcwag7FhVPH9zM=
|
||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk=
|
||||
github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
|
||||
github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI=
|
||||
github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 h1:XTHrT015sxHyJ5FnQ0AeemSspZWaDq7DoTRW0EVsDCE=
|
||||
github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
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/spf13/viper v0.0.0-20150530192845-be5ff3e4840c h1:2EejZtjFjKJGk71ANb+wtFK5EjUzUkEM3R0xnp559xg=
|
||||
github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
|
||||
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=
|
||||
gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM=
|
||||
gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
@ -1,7 +1,7 @@
|
|||
# Database Migrations
|
||||
|
||||
This directory contains database migrations for the server and signer. They
|
||||
are being managed using [this tool](https://github.com/mattes/migrate).
|
||||
are being managed using [this tool](https://github.com/golang-migrate/migrate).
|
||||
Within each of the server and signer directories are directories for different
|
||||
database backends. Notary server and signer use GORM and are therefore
|
||||
capable of running on a number of different databases, however migrations
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# http://stackoverflow.com/q/18497299
|
||||
# https://stackoverflow.com/questions/18497299/psql-fatal-connection-requires-a-valid-client-certificate
|
||||
hostssl all all 0.0.0.0/0 cert clientcert=1
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDajCCAlKgAwIBAgIUHN8eDMtoTOBXOd+RjnCxLYUs4kYwDQYJKoZIhvcNAQEL
|
||||
BQAwTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJh
|
||||
bmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENBMB4XDTE3MDUxMjIyMzcw
|
||||
MFoXDTIyMDUxMTIyMzcwMFowTTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYw
|
||||
FAYDVQQHEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQDExBub3RhcnkncyBUZXN0IENB
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy9811sQcEoe2pH0+jUQP
|
||||
8Jq7RkuUnFtbYpR7H6AyMXfyCsiz4ghpkENFScJlQhFE/Q5XXk0mTVEJD7UEwuQp
|
||||
haqqSbDYMKVXHGY3CESyRF6z/k4jPTpxK0KxqsIXi8MZFvLOMUVGhXp+duFFX365
|
||||
ZXi0GTIhkkbo6/tQLLAYAL5dfAOU7FTOthK6RkPBnPLdb5ZuKJfbSBkIBH+Rdrm5
|
||||
atJYzL6rha3p2Hnm6FFF0eqdd+uqYpBuXcmQsftxPLBMvqbHXaPMov51+WvRXz0K
|
||||
EeluT0Fue0LuYCRYFMlbmALFg85tFAHWXKer6M/ejK4MCWQnpPwalE9Oaetb1/q5
|
||||
MwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
|
||||
HQ4EFgQU30PAjq5cOwlLzi4fxSE3J/v9EPcwDQYJKoZIhvcNAQELBQADggEBAJhV
|
||||
p1Va9r/NdCXaL5Ah+4i+l5m3hcKXT9h3811rmtLtKqcUwwnBbG+V3Ko+arbuCDYV
|
||||
VajGLRnhTjy1thqYZr6KbeG6HZ6BN8Zxhcam86O7JXDBKoWJH4SIGysXO0jXg1n4
|
||||
fM1teEhQ69OUCrCkFGBblL88uHbdgIQGTDkD9F4hFGia6NSII46MTIE6tH0UBrIy
|
||||
L5ZNCgG5Mn5w4D2Su6X6vq5ovE/mXRJLYCQLkvKSi5BQDdM26SwmKFSNk2V+DUeu
|
||||
te3qluUTIFLa+V+U0C6vJMaxgaTB5phzQ1R7HykqBnSrzcqyQKYKnR3aGzvHnb2m
|
||||
VYGGXEToG4TacQ/psn8=
|
||||
MIIDAjCCAeqgAwIBAgIUXVJRkZt3nqfJpaVeEEVNoX5w4bEwDQYJKoZIhvcNAQEL
|
||||
BQAwGTEXMBUGA1UEAxMOVGVzdCBOb3RhcnkgQ0EwHhcNMjEwNDAyMTMwNTAwWhcN
|
||||
MjYwNDAxMTMwNTAwWjAZMRcwFQYDVQQDEw5UZXN0IE5vdGFyeSBDQTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANPxWDzc8fGeC8mNdVbz0L5qatZRAYkG
|
||||
MmhNVrmICPT3S0kS0AzvnHf1ZpqTsUqF3W0ujpGzLDgdmtstQESLYFvBwDMQAu6X
|
||||
axF3HesFd2BqIjiTD4HdTlYSWVhk+YKOrOtF6CpxvTVJpFPjSIPEA79c84wrI6Eu
|
||||
+FgcG5Al8NdkTSu1D1fNk1JGvIDki3+PQQEAjCKGbwjXJe/Zv1rga4xnCFVCx63J
|
||||
7Esj1UWssCQ1RaqPV5xqnIldHzWatiEpfU4Vk7+Hyoep/3H+xTqUP2JNfKblHGCw
|
||||
/DLeU4aXvTDjgRYKHWgSZQBFQYLRz2h2xE6UYeomloNguLvJ4A7xo38CAwEAAaNC
|
||||
MEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEVE
|
||||
JL9mT7Twv0BLNevED4280MPgMA0GCSqGSIb3DQEBCwUAA4IBAQCyIc548I14Es7b
|
||||
i1KDBHOeXmQiM9g1hbMJk7Q9+IjPy+fmbqDcop/9U9pCCdSvEOR3z0zeKwEfqxMI
|
||||
ukLG/tjAn+DB0Wid/RznBMTmTvreghmfAsQfGs/j+PC+B6OyaV4+4lUbvTjmsThu
|
||||
3cOPUQTypytUgy00C1mdQfUXMJbNRFAor6ux6ZIQw358urDWWWdrQ8fSF2bb28GA
|
||||
3cBjZ8X2EtABZs4BYVt/2R+5w9ejeUDz3rSXwV+9DYdZ2dxsK240VTJRskc1UazY
|
||||
p/mM9bSOrgvaGeFJkJXrKII0BCrVUREXk8WwxoKdIBkJrtIjxuBxiiXNHFPYxbV/
|
||||
3TQNaexo
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/theupdateframework/notary"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -29,18 +29,18 @@ way to recover this key. You can find the key in your config directory.`
|
|||
var (
|
||||
// ErrTooShort is returned if the passphrase entered for a new key is
|
||||
// below the minimum length
|
||||
ErrTooShort = errors.New("Passphrase too short")
|
||||
ErrTooShort = errors.New("passphrase too short")
|
||||
|
||||
// ErrDontMatch is returned if the two entered passphrases don't match.
|
||||
// new key is below the minimum length
|
||||
ErrDontMatch = errors.New("The entered passphrases do not match")
|
||||
ErrDontMatch = errors.New("the entered passphrases do not match")
|
||||
|
||||
// ErrTooManyAttempts is returned if the maximum number of passphrase
|
||||
// entry attempts is reached.
|
||||
ErrTooManyAttempts = errors.New("Too many attempts")
|
||||
ErrTooManyAttempts = errors.New("too many attempts")
|
||||
|
||||
// ErrNoInput is returned if we do not have a valid input method for passphrases
|
||||
ErrNoInput = errors.New("Please either use environment variables or STDIN with a terminal to provide key passphrases")
|
||||
ErrNoInput = errors.New("please either use environment variables or STDIN with a terminal to provide key passphrases")
|
||||
)
|
||||
|
||||
// PromptRetriever returns a new Retriever which will provide a prompt on stdin
|
||||
|
@ -49,7 +49,7 @@ var (
|
|||
// Upon successful passphrase retrievals, the passphrase will be cached such that
|
||||
// subsequent prompts will produce the same passphrase.
|
||||
func PromptRetriever() notary.PassRetriever {
|
||||
if !terminal.IsTerminal(int(os.Stdin.Fd())) {
|
||||
if !term.IsTerminal(int(os.Stdin.Fd())) {
|
||||
return func(string, string, bool, int) (string, bool, error) {
|
||||
return "", false, ErrNoInput
|
||||
}
|
||||
|
@ -200,8 +200,8 @@ func GetPassphrase(in *bufio.Reader) ([]byte, error) {
|
|||
err error
|
||||
)
|
||||
|
||||
if terminal.IsTerminal(int(os.Stdin.Fd())) {
|
||||
passphrase, err = terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
if term.IsTerminal(int(os.Stdin.Fd())) {
|
||||
passphrase, err = term.ReadPassword(int(os.Stdin.Fd()))
|
||||
} else {
|
||||
passphrase, err = in.ReadBytes('\n')
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue