remove the notary from backend (#18668)

Since harbor deprecates notary since v2.9.0, this pull request targets to remove the code related with notary.

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2023-05-18 18:47:42 +08:00 committed by GitHub
parent 845bcdb184
commit bf7c82b9a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
201 changed files with 54 additions and 29517 deletions

View File

@ -89,8 +89,8 @@ jobs:
else
build_base_params=" BUILD_BASE=true PUSHBASEIMAGE=true REGISTRYUSER=\"${{ secrets.DOCKER_HUB_USERNAME }}\" REGISTRYPASSWORD=\"${{ secrets.DOCKER_HUB_PASSWORD }}\""
fi
sudo make package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} NOTARYFLAG=true TRIVYFLAG=true HTTPPROXY= ${build_base_params}
sudo make package_online GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} NOTARYFLAG=true TRIVYFLAG=true HTTPPROXY= ${build_base_params}
sudo make package_offline GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} TRIVYFLAG=true HTTPPROXY= ${build_base_params}
sudo make package_online GOBUILDTAGS="include_oss include_gcs" BASEIMAGETAG=${Harbor_Build_Base_Tag} VERSIONTAG=${Harbor_Assets_Version} PKGVERSIONTAG=${Harbor_Package_Version} TRIVYFLAG=true HTTPPROXY= ${build_base_params}
harbor_offline_build_bundle=$(basename harbor-offline-installer-*.tgz)
harbor_online_build_bundle=$(basename harbor-online-installer-*.tgz)
echo "Package name is: $harbor_offline_build_bundle"

View File

@ -77,7 +77,6 @@ CHECKENVCMD=checkenv.sh
REGISTRYSERVER=
REGISTRYPROJECTNAME=goharbor
DEVFLAG=true
NOTARYFLAG=false
TRIVYFLAG=false
HTTPPROXY=
BUILDBIN=true
@ -92,7 +91,7 @@ VERSIONTAG=dev
BUILD_BASE=true
PUSHBASEIMAGE=false
BASEIMAGETAG=dev
BUILDBASETARGET=trivy-adapter core db jobservice log nginx notary-server notary-signer portal prepare redis registry registryctl exporter
BUILDBASETARGET=trivy-adapter core db jobservice log nginx portal prepare redis registry registryctl exporter
IMAGENAMESPACE=goharbor
BASEIMAGENAMESPACE=goharbor
# #input true/false only
@ -105,8 +104,6 @@ PREPARE_VERSION_NAME=versions
#versions
REGISTRYVERSION=v2.8.0-patch-redis
NOTARYVERSION=v0.6.1
NOTARYMIGRATEVERSION=v4.11.0
TRIVYVERSION=v0.39.0
TRIVYADAPTERVERSION=v0.30.10
@ -114,7 +111,6 @@ TRIVYADAPTERVERSION=v0.30.10
REGISTRY_SRC_TAG=v2.8.0
# dependency binaries
NOTARYURL=https://storage.googleapis.com/harbor-builds/bin/notary/release-${NOTARYVERSION}/binary-bundle.tgz
REGISTRYURL=https://storage.googleapis.com/harbor-builds/bin/registry/release-${REGISTRYVERSION}/registry
TRIVY_DOWNLOAD_URL=https://github.com/aquasecurity/trivy/releases/download/$(TRIVYVERSION)/trivy_$(TRIVYVERSION:v%=%)_Linux-64bit.tar.gz
TRIVY_ADAPTER_DOWNLOAD_URL=https://github.com/aquasecurity/harbor-scanner-trivy/releases/download/$(TRIVYADAPTERVERSION)/harbor-scanner-trivy_$(TRIVYADAPTERVERSION:v%=%)_Linux_x86_64.tar.gz
@ -122,7 +118,6 @@ TRIVY_ADAPTER_DOWNLOAD_URL=https://github.com/aquasecurity/harbor-scanner-trivy/
define VERSIONS_FOR_PREPARE
VERSION_TAG: $(VERSIONTAG)
REGISTRY_VERSION: $(REGISTRYVERSION)
NOTARY_VERSION: $(NOTARYVERSION)
TRIVY_VERSION: $(TRIVYVERSION)
TRIVY_ADAPTER_VERSION: $(TRIVYADAPTERVERSION)
endef
@ -175,7 +170,6 @@ GOBUILDMAKEPATH=make
GOBUILDMAKEPATH_CORE=$(GOBUILDMAKEPATH)/photon/core
GOBUILDMAKEPATH_JOBSERVICE=$(GOBUILDMAKEPATH)/photon/jobservice
GOBUILDMAKEPATH_REGISTRYCTL=$(GOBUILDMAKEPATH)/photon/registryctl
GOBUILDMAKEPATH_NOTARY=$(GOBUILDMAKEPATH)/photon/notary
GOBUILDMAKEPATH_STANDALONE_DB_MIGRATOR=$(GOBUILDMAKEPATH)/photon/standalone-db-migrator
GOBUILDMAKEPATH_EXPORTER=$(GOBUILDMAKEPATH)/photon/exporter
@ -186,7 +180,6 @@ JOBSERVICEBINARYPATH=$(BUILDPATH)/$(GOBUILDMAKEPATH_JOBSERVICE)
JOBSERVICEBINARYNAME=harbor_jobservice
REGISTRYCTLBINARYPATH=$(BUILDPATH)/$(GOBUILDMAKEPATH_REGISTRYCTL)
REGISTRYCTLBINARYNAME=harbor_registryctl
MIGRATEPATCHBINARYPATH=$(BUILDPATH)/$(GOBUILDMAKEPATH_NOTARY)
MIGRATEPATCHBINARYNAME=migrate-patch
STANDALONE_DB_MIGRATOR_BINARYPATH=$(BUILDPATH)/$(GOBUILDMAKEPATH_STANDALONE_DB_MIGRATOR)
STANDALONE_DB_MIGRATOR_BINARYNAME=migrate
@ -200,9 +193,6 @@ CONFIGFILE=harbor.yml
PREPAREPATH=$(TOOLSPATH)
PREPARECMD=prepare
PREPARECMD_PARA=--conf $(INSIDE_CONFIGPATH)/$(CONFIGFILE)
ifeq ($(NOTARYFLAG), true)
PREPARECMD_PARA+= --with-notary
endif
ifeq ($(TRIVYFLAG), true)
PREPARECMD_PARA+= --with-trivy
endif
@ -274,9 +264,6 @@ PACKAGE_ONLINE_PARA=-zcvf harbor-online-installer-$(PKGVERSIONTAG).tgz \
DOCKERCOMPOSE_FILE_OPT=-f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
ifeq ($(NOTARYFLAG), true)
DOCKERSAVE_PARA+= $(IMAGENAMESPACE)/notary-server-photon:$(VERSIONTAG) $(IMAGENAMESPACE)/notary-signer-photon:$(VERSIONTAG)
endif
ifeq ($(TRIVYFLAG), true)
DOCKERSAVE_PARA+= $(IMAGENAMESPACE)/trivy-adapter-photon:$(VERSIONTAG)
endif
@ -365,17 +352,12 @@ compile_registryctl:
@$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATHINCONTAINER) -w $(GOBUILDPATH_REGISTRYCTL) $(GOBUILDIMAGE) $(GOIMAGEBUILD_COMMON) -o $(GOBUILDPATHINCONTAINER)/$(GOBUILDMAKEPATH_REGISTRYCTL)/$(REGISTRYCTLBINARYNAME)
@echo "Done."
compile_notary_migrate_patch:
@echo "compiling binary for migrate patch (golang image)..."
@$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATHINCONTAINER) -w $(GOBUILDPATH_MIGRATEPATCH) $(GOBUILDIMAGE) $(GOIMAGEBUILD_COMMON) -o $(GOBUILDPATHINCONTAINER)/$(GOBUILDMAKEPATH_NOTARY)/$(MIGRATEPATCHBINARYNAME)
@echo "Done."
compile_standalone_db_migrator:
@echo "compiling binary for standalone db migrator (golang image)..."
@$(DOCKERCMD) run --rm -v $(BUILDPATH):$(GOBUILDPATHINCONTAINER) -w $(GOBUILDPATH_STANDALONE_DB_MIGRATOR) $(GOBUILDIMAGE) $(GOIMAGEBUILD_COMMON) -o $(GOBUILDPATHINCONTAINER)/$(GOBUILDMAKEPATH_STANDALONE_DB_MIGRATOR)/$(STANDALONE_DB_MIGRATOR_BINARYNAME)
@echo "Done."
compile: check_environment versions_prepare compile_core compile_jobservice compile_registryctl compile_notary_migrate_patch
compile: check_environment versions_prepare compile_core compile_jobservice compile_registryctl
update_prepare_version:
@echo "substitute the prepare version tag in prepare file..."
@ -407,12 +389,11 @@ build:
fi
make -f $(MAKEFILEPATH_PHOTON)/Makefile $(BUILDTARGET) -e DEVFLAG=$(DEVFLAG) -e GOBUILDIMAGE=$(GOBUILDIMAGE) \
-e REGISTRYVERSION=$(REGISTRYVERSION) -e REGISTRY_SRC_TAG=$(REGISTRY_SRC_TAG) \
-e NOTARYVERSION=$(NOTARYVERSION) -e NOTARYMIGRATEVERSION=$(NOTARYMIGRATEVERSION) \
-e TRIVYVERSION=$(TRIVYVERSION) -e TRIVYADAPTERVERSION=$(TRIVYADAPTERVERSION) \
-e VERSIONTAG=$(VERSIONTAG) \
-e BUILDBIN=$(BUILDBIN) \
-e NPM_REGISTRY=$(NPM_REGISTRY) -e BASEIMAGETAG=$(BASEIMAGETAG) -e IMAGENAMESPACE=$(IMAGENAMESPACE) -e BASEIMAGENAMESPACE=$(BASEIMAGENAMESPACE) \
-e NOTARYURL=$(NOTARYURL) -e REGISTRYURL=$(REGISTRYURL) \
-e REGISTRYURL=$(REGISTRYURL) \
-e TRIVY_DOWNLOAD_URL=$(TRIVY_DOWNLOAD_URL) -e TRIVY_ADAPTER_DOWNLOAD_URL=$(TRIVY_ADAPTER_DOWNLOAD_URL) \
-e PULL_BASE_FROM_DOCKERHUB=$(PULL_BASE_FROM_DOCKERHUB) -e BUILD_BASE=$(BUILD_BASE) \
-e REGISTRYUSER=$(REGISTRYUSER) -e REGISTRYPASSWORD=$(REGISTRYPASSWORD) \

View File

@ -6516,10 +6516,6 @@ definitions:
type: boolean
x-omitempty: false
description: The immutable status of the tag
signed:
type: boolean
x-omitempty: false
description: The attribute indicates whether the tag is signed or not
ExtraAttrs:
type: object
additionalProperties:
@ -7693,11 +7689,6 @@ definitions:
x-nullable: true
x-omitempty: true
description: The current time of the server.
with_notary:
type: boolean
x-nullable: true
x-omitempty: true
description: If the Harbor instance is deployed with nested notary.
registry_url:
type: string
x-nullable: true

View File

@ -159,20 +159,6 @@ _version: 2.8.0
# ssl_mode: disable
# max_idle_conns: 2
# max_open_conns: 0
# notary_signer:
# host: notary_signer_db_host
# port: notary_signer_db_port
# db_name: notary_signer_db_name
# username: notary_signer_db_username
# password: notary_signer_db_password
# ssl_mode: disable
# notary_server:
# host: notary_server_db_host
# port: notary_server_db_port
# db_name: notary_server_db_name
# username: notary_server_db_username
# password: notary_server_db_password
# ssl_mode: disable
# Uncomment external_redis if using external Redis server
# external_redis:

View File

@ -8,13 +8,10 @@ source $DIR/common.sh
set +o noglob
usage=$'Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.
Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.yml bacause notary must run under https.
Please set --with-trivy if needs enable Trivy in Harbor.
Please do NOT set --with-chartmuseum, as chartmusuem has been deprecated and removed.'
item=0
# notary is not enabled by default
with_notary=$false
# clair is deprecated
with_clair=$false
# trivy is not enabled by default
@ -28,10 +25,6 @@ while [ $# -gt 0 ]; do
--help)
note "$usage"
exit 0;;
--with-notary)
with_notary=true;;
--with-clair)
with_clair=true;;
--with-trivy)
with_trivy=true;;
*)
@ -41,12 +34,6 @@ while [ $# -gt 0 ]; do
shift || true
done
if [ $with_clair ]
then
error "Clair is deprecated please remove it from installation arguments !!!"
exit 1
fi
workdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $workdir
@ -71,10 +58,6 @@ fi
h2 "[Step $item]: preparing harbor configs ..."; let item+=1
prepare_para=
if [ $with_notary ]
then
prepare_para="${prepare_para} --with-notary"
fi
if [ $with_trivy ]
then
prepare_para="${prepare_para} --with-trivy"
@ -91,14 +74,6 @@ fi
echo ""
h2 "[Step $item]: starting Harbor ..."
if [ $with_notary ]
then
warn "
Notary will be deprecated as of Harbor v2.6.0 and start to be removed in v2.8.0 or later.
You can use cosign for signature instead since Harbor v2.5.0.
Please see discussion here for more details. https://github.com/goharbor/harbor/discussions/16612"
fi
$DOCKER_COMPOSE up -d
success $"----Harbor has been installed and started successfully.----"

View File

@ -93,16 +93,6 @@ DOCKERFILEPATH_REGISTRYCTL=$(DOCKERFILEPATH)/$(REGISTRYCTL)
DOCKERFILENAME_REGISTRYCTL=Dockerfile
DOCKERIMAGENAME_REGISTRYCTL=$(IMAGENAMESPACE)/harbor-$(REGISTRYCTL)
NOTARYSERVER=notary-server
NOTARYSIGNER=notary-signer
DOCKERFILEPATH_NOTARY=$(DOCKERFILEPATH)/notary
DOCKERFILEPATH_NOTARYSERVER=$(DOCKERFILEPATH)/$(NOTARYSERVER)
DOCKERFILENAME_NOTARYSERVER=Dockerfile
DOCKERIMAGENAME_NOTARYSERVER=$(IMAGENAMESPACE)/$(NOTARYSERVER)-photon
DOCKERFILEPATH_NOTARYSIGNER=$(DOCKERFILEPATH)/$(NOTARYSIGNER)
DOCKERFILENAME_NOTARYSIGNER=Dockerfile
DOCKERIMAGENAME_NOTARYSIGNER=$(IMAGENAMESPACE)/$(NOTARYSIGNER)-photon
REDIS=redis
DOCKERFILEPATH_REDIS=$(DOCKERFILEPATH)/$(REDIS)
DOCKERFILENAME_REDIS=Dockerfile
@ -182,24 +172,6 @@ _build_nginx:
@$(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_NGINX)/$(DOCKERFILENAME_NGINX) -t $(DOCKERIMAGENAME_NGINX):$(VERSIONTAG) .
@echo "Done."
_build_notary:
@if [ "$(NOTARYFLAG)" = "true" ] ; then \
$(call _build_base,$(NOTARYSERVER),$(DOCKERFILEPATH_NOTARYSERVER)) ; \
$(call _build_base,$(NOTARYSIGNER),$(DOCKERFILEPATH_NOTARYSIGNER)) ; \
if [ "$(BUILDBIN)" != "true" ] ; then \
rm -rf $(DOCKERFILEPATH_NOTARY)/binary && mkdir -p $(DOCKERFILEPATH_NOTARY)/binary && \
$(call _get_binary, $(NOTARYURL), $(DOCKERFILEPATH_NOTARY)/binary-bundle.tgz); \
cd $(DOCKERFILEPATH_NOTARY) && tar -zvxf binary-bundle.tgz && cd - ; \
else \
cd $(DOCKERFILEPATH_NOTARY) && $(DOCKERFILEPATH_NOTARY)/builder $(NOTARYVERSION) $(NOTARYMIGRATEVERSION) && cd - ; \
fi ; \
echo "building notary container for photon..."; \
chmod 655 $(DOCKERFILEPATH_NOTARY)/binary/notary-signer && $(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_NOTARYSIGNER)/$(DOCKERFILENAME_NOTARYSIGNER) -t $(DOCKERIMAGENAME_NOTARYSIGNER):$(VERSIONTAG) . ; \
chmod 655 $(DOCKERFILEPATH_NOTARY)/binary/notary-server && $(DOCKERBUILD_WITH_PULL_PARA) --build-arg harbor_base_image_version=$(BASEIMAGETAG) --build-arg harbor_base_namespace=$(BASEIMAGENAMESPACE) -f $(DOCKERFILEPATH_NOTARYSERVER)/$(DOCKERFILENAME_NOTARYSERVER) -t $(DOCKERIMAGENAME_NOTARYSERVER):$(VERSIONTAG) . ; \
rm -rf $(DOCKERFILEPATH_NOTARY)/binary; \
echo "Done."; \
fi
_build_registry:
@$(call _build_base,$(REGISTRY),$(DOCKERFILEPATH_REG))
@if [ "$(BUILDBIN)" != "true" ] ; then \
@ -261,7 +233,7 @@ define _build_base
fi
endef
build: _build_prepare _build_db _build_portal _build_core _build_jobservice _build_log _build_nginx _build_registry _build_registryctl _build_notary _build_trivy_adapter _build_redis _compile_and_build_exporter
build: _build_prepare _build_db _build_portal _build_core _build_jobservice _build_log _build_nginx _build_registry _build_registryctl _build_trivy_adapter _build_redis _compile_and_build_exporter
@if [ -n "$(REGISTRYUSER)" ] && [ -n "$(REGISTRYPASSWORD)" ] ; then \
docker logout ; \
fi

View File

@ -8,8 +8,6 @@ COPY ./make/photon/db/docker-entrypoint.sh /docker-entrypoint.sh
COPY ./make/photon/db/initdb.sh /initdb.sh
COPY ./make/photon/db/upgrade.sh /upgrade.sh
COPY ./make/photon/db/docker-healthcheck.sh /docker-healthcheck.sh
COPY ./make/photon/db/initial-notaryserver.sql /docker-entrypoint-initdb.d/
COPY ./make/photon/db/initial-notarysigner.sql /docker-entrypoint-initdb.d/
COPY ./make/photon/db/initial-registry.sql /docker-entrypoint-initdb.d/
RUN chown -R postgres:postgres /docker-entrypoint.sh /docker-healthcheck.sh /docker-entrypoint-initdb.d \
&& chmod u+x /docker-entrypoint.sh /docker-healthcheck.sh

View File

@ -1,4 +0,0 @@
CREATE DATABASE notaryserver;
CREATE USER server;
alter user server with encrypted password 'password';
GRANT ALL PRIVILEGES ON DATABASE notaryserver TO server;

View File

@ -1,4 +0,0 @@
CREATE DATABASE notarysigner;
CREATE USER signer;
alter user signer with encrypted password 'password';
GRANT ALL PRIVILEGES ON DATABASE notarysigner TO signer;

View File

@ -1,13 +0,0 @@
ARG harbor_base_image_version
ARG harbor_base_namespace
FROM ${harbor_base_namespace}/harbor-notary-server-base:${harbor_base_image_version}
COPY ./make/photon/notary/migrate-patch /bin/migrate-patch
COPY ./make/photon/notary/binary/notary-server /bin/notary-server
COPY ./make/photon/notary/binary/migrate /bin/migrate
COPY ./make/photon/notary/binary/migrations/ /migrations/
RUN chmod +x /bin/notary-server /migrations/migrate.sh /bin/migrate /bin/migrate-patch
ENV SERVICE_NAME=notary_server
USER notary
CMD migrate-patch -database=${DB_URL} && /migrations/migrate.sh && /bin/notary-server -config=/etc/notary/server-config.postgres.json -logf=logfmt

View File

@ -1,6 +0,0 @@
FROM photon:4.0
RUN tdnf install -y shadow >> /dev/null \
&& tdnf clean all \
&& groupadd -r -g 10000 notary \
&& useradd --no-log-init -r -g 10000 -u 10000 notary

View File

@ -1,13 +0,0 @@
ARG harbor_base_image_version
ARG harbor_base_namespace
FROM ${harbor_base_namespace}/harbor-notary-signer-base:${harbor_base_image_version}
COPY ./make/photon/notary/migrate-patch /bin/migrate-patch
COPY ./make/photon/notary/binary/notary-signer /bin/notary-signer
COPY ./make/photon/notary/binary/migrate /bin/migrate
COPY ./make/photon/notary/binary/migrations/ /migrations/
RUN chmod +x /bin/notary-signer /migrations/migrate.sh /bin/migrate /bin/migrate-patch
ENV SERVICE_NAME=notary_signer
USER notary
CMD migrate-patch -database=${DB_URL} && /migrations/migrate.sh && /bin/notary-signer -config=/etc/notary/signer-config.postgres.json -logf=logfmt

View File

@ -1,6 +0,0 @@
FROM photon:4.0
RUN tdnf install -y shadow >> /dev/null \
&& tdnf clean all \
&& groupadd -r -g 10000 notary \
&& useradd --no-log-init -r -g 10000 -u 10000 notary

View File

@ -1,27 +0,0 @@
FROM golang:1.14.15
ARG NOTARY_VERSION
ARG MIGRATE_VERSION
RUN test -n "$NOTARY_VERSION"
RUN test -n "$MIGRATE_VERSION"
ENV NOTARYPKG github.com/theupdateframework/notary
ENV MIGRATEPKG github.com/golang-migrate/migrate
RUN git clone -b $NOTARY_VERSION https://github.com/theupdateframework/notary.git /go/src/${NOTARYPKG}
WORKDIR /go/src/${NOTARYPKG}
RUN go install -tags pkcs11 \
-ldflags "-w -X ${NOTARYPKG}/version.GitCommit=`git rev-parse --short HEAD` -X ${NOTARYPKG}/version.NotaryVersion=`cat NOTARY_VERSION`" ${NOTARYPKG}/cmd/notary-server
RUN go install -tags pkcs11 \
-ldflags "-w -X ${NOTARYPKG}/version.GitCommit=`git rev-parse --short HEAD` -X ${NOTARYPKG}/version.NotaryVersion=`cat NOTARY_VERSION`" ${NOTARYPKG}/cmd/notary-signer
RUN cp -r /go/src/${NOTARYPKG}/migrations/ /
RUN git clone -b $MIGRATE_VERSION https://github.com/golang-migrate/migrate /go/src/${MIGRATEPKG}
WORKDIR /go/src/${MIGRATEPKG}
ENV DATABASES="postgres mysql redshift cassandra spanner cockroachdb"
ENV SOURCES="file go_bindata github aws_s3 google_cloud_storage"
RUN go install -tags "$DATABASES $SOURCES" -ldflags="-X main.Version=${MIGRATE_VERSION}" ${MIGRATEPKG}/cli && mv /go/bin/cli /go/bin/migrate

View File

@ -1,31 +0,0 @@
#!/bin/bash
set +e
if [ -z $2 ]; then
error "Please set the notary and migrate version"
exit 1
fi
echo "Building notary and golang-migrate from source, notary version: $1, golang-migrate version: $2"
set -e
# the temp folder to store binary file...
mkdir -p binary
rm -rf binary/* || true
cd `dirname $0`
docker build --build-arg NOTARY_VERSION=$1 --build-arg MIGRATE_VERSION=$2 -f ./binary.Dockerfile -t notary-binary .
echo 'copy the binary files to local...'
ID=$(docker create notary-binary)
docker cp $ID:/go/bin/notary-server binary/
docker cp $ID:/go/bin/notary-signer binary/
docker cp $ID:/go/bin/migrate binary/
docker cp $ID:/migrations binary/
sed -i 's/waiting for $DB_URL/waiting for database/g' binary/migrations/migrate.sh
docker rm -f $ID
docker rmi -f notary-binary

View File

@ -13,7 +13,6 @@ from utils.jobservice import prepare_job_service
from utils.registry import prepare_registry
from utils.registry_ctl import prepare_registry_ctl
from utils.core import prepare_core
from utils.notary import prepare_notary
from utils.log import prepare_log_configs
from utils.docker_compose import prepare_docker_compose
from utils.nginx import prepare_nginx, nginx_confd_dir
@ -27,14 +26,13 @@ old_private_key_pem_path, old_crt_path)
@click.command()
@click.option('--conf', default=input_config_path, help="the path of Harbor configuration file")
@click.option('--with-notary', is_flag=True, help="the Harbor instance is to be deployed with notary")
@click.option('--with-trivy', is_flag=True, help="the Harbor instance is to be deployed with Trivy")
def prepare(conf, with_notary, with_trivy):
def prepare(conf, with_trivy):
delfile(config_dir)
config_dict = parse_yaml_config(conf, with_notary=with_notary, with_trivy=with_trivy)
config_dict = parse_yaml_config(conf, with_trivy=with_trivy)
try:
validate(config_dict, notary_mode=with_notary)
validate(config_dict)
except Exception as e:
click.echo('Error happened in config validation...')
logging.error(e)
@ -43,7 +41,7 @@ def prepare(conf, with_notary, with_trivy):
prepare_portal(config_dict)
prepare_log_configs(config_dict)
prepare_nginx(config_dict)
prepare_core(config_dict, with_notary=with_notary, with_trivy=with_trivy)
prepare_core(config_dict, with_trivy=with_trivy)
prepare_registry(config_dict)
prepare_registry_ctl(config_dict)
prepare_db(config_dict)
@ -64,10 +62,7 @@ def prepare(conf, with_notary, with_trivy):
if config_dict['metric'].enabled:
prepare_exporter(config_dict)
if with_notary:
prepare_notary(config_dict, nginx_confd_dir, SSL_CERT_PATH, SSL_CERT_KEY_PATH)
if with_trivy:
prepare_trivy_adapter(config_dict)
prepare_docker_compose(config_dict, with_trivy, with_notary)
prepare_docker_compose(config_dict, with_trivy)

View File

@ -57,8 +57,6 @@ INTERNAL_NO_PROXY_DN = {
'jobservice',
'registry',
'registryctl',
'notary-server',
'notary-signer',
'trivy-adapter',
'exporter',
}

View File

@ -230,20 +230,6 @@ external_database:
username: {{ external_database.clair.username }}
password: {{ external_database.clair.password }}
ssl_mode: {{ external_database.clair.ssl_mode }}
notary_signer:
host: {{ external_database.notary_signer.host }}
port: {{ external_database.notary_signer.port }}
db_name: {{external_database.notary_signer.db_name }}
username: {{ external_database.notary_signer.username }}
password: {{ external_database.notary_signer.password }}
ssl_mode: {{ external_database.notary_signer.ssl_mode }}
notary_server:
host: {{ external_database.notary_server.host }}
port: {{ external_database.notary_server.port }}
db_name: {{ external_database.notary_server.db_name }}
username: {{ external_database.notary_server.username }}
password: {{ external_database.notary_server.password }}
ssl_mode: {{ external_database.notary_server.ssl_mode }}
{% else %}
# Uncomment external_database if using external database.
# external_database:

View File

@ -24,11 +24,6 @@ class InternalTLS:
'trivy_adapter.crt', 'trivy_adapter.key',
}
notary_certs_filename = {
'notary_signer.crt', 'notary_signer.key',
'notary_server.crt', 'notary_server.key'
}
db_certs_filename = {
'harbor_db.crt', 'harbor_db.key'
}
@ -40,8 +35,6 @@ class InternalTLS:
self.tls_dir = tls_dir
if self.enabled:
self.required_filenames = self.harbor_certs_filename
if kwargs.get('with_notary'):
self.required_filenames.update(self.notary_certs_filename)
if kwargs.get('with_trivy'):
self.required_filenames.update(self.trivy_certs_filename)
if not kwargs.get('external_database'):

View File

@ -94,27 +94,6 @@ echo subjectAltName = DNS.1:trivy-adapter > extfile.cnf
openssl x509 -req -days $DAYS -sha256 -in trivy_adapter.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -extfile extfile.cnf -out trivy_adapter.crt
# generate notary_signer key
openssl req -new \
-newkey rsa:4096 -nodes -sha256 -keyout notary_signer.key \
-out notary_signer.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=notary-signer"
# sign notary_signer csr with CA certificate and key
echo subjectAltName = DNS.1:notary-signer > extfile.cnf
openssl x509 -req -days $DAYS -sha256 -in notary_signer.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -extfile extfile.cnf -out notary_signer.crt
# generate notary_server key
openssl req -new \
-newkey rsa:4096 -nodes -sha256 -keyout notary_server.key \
-out notary_server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=VMware/CN=notary-server"
# sign notary_server csr with CA certificate and key
echo subjectAltName = DNS.1:notary-server > extfile.cnf
openssl x509 -req -days $DAYS -sha256 -in notary_server.csr -CA harbor_internal_ca.crt -CAkey harbor_internal_ca.key -CAcreateserial -extfile extfile.cnf -out notary_server.crt
# generate harbor_db key
openssl req -new \
-newkey rsa:4096 -nodes -sha256 -keyout harbor_db.key \

View File

@ -24,13 +24,11 @@ HARBOR_ADMIN_PASSWORD={{harbor_admin_password}}
MAX_JOB_WORKERS={{max_job_workers}}
CORE_SECRET={{core_secret}}
JOBSERVICE_SECRET={{jobservice_secret}}
WITH_NOTARY={{with_notary}}
WITH_TRIVY={{with_trivy}}
CORE_URL={{core_url}}
CORE_LOCAL_URL={{core_local_url}}
JOBSERVICE_URL={{jobservice_url}}
TRIVY_ADAPTER_URL={{trivy_adapter_url}}
NOTARY_URL={{notary_url}}
REGISTRY_STORAGE_PROVIDER_NAME={{storage_provider_name}}
READ_ONLY=false
RELOAD_KEY={{reload_key}}

View File

@ -126,11 +126,6 @@ services:
- {{data_volume}}/database:/var/lib/postgresql/data:z
networks:
harbor:
{% if with_notary %}
harbor-notary:
aliases:
- harbor-db
{% endif %}
env_file:
- ./common/config/db/env
depends_on:
@ -184,9 +179,6 @@ services:
{% endif %}
networks:
harbor:
{% if with_notary %}
harbor-notary:
{% endif %}
depends_on:
- log
- registry
@ -323,9 +315,6 @@ services:
{% endif %}
networks:
- harbor
{% if with_notary %}
- harbor-notary
{% endif %}
ports:
- {{http_port}}:8080
{% if protocol == 'https' %}
@ -333,9 +322,6 @@ services:
{% endif %}
{% if metric.enabled %}
- {{metric.port}}:9090
{% endif %}
{% if with_notary %}
- 4443:4443
{% endif %}
depends_on:
- registry
@ -347,86 +333,6 @@ services:
options:
syslog-address: "tcp://localhost:1514"
tag: "proxy"
{% if with_notary %}
notary-server:
image: goharbor/notary-server-photon:{{notary_version}}
container_name: notary-server
restart: always
networks:
- notary-sig
- harbor-notary
volumes:
- ./common/config/notary:/etc/notary:z
- type: bind
source: {{data_volume}}/secret/notary/notary-signer-ca.crt
target: /etc/notary/notary-signer-ca.crt
- type: bind
source: {{data_volume}}/secret/registry/root.crt
target: /etc/notary/root.crt
- type: bind
source: ./common/config/shared/trust-certificates
target: /harbor_cust_cert
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.notary_server_crt_path}}
target: /etc/harbor/ssl/notary_server.crt
- type: bind
source: {{internal_tls.notary_server_key_path}}
target: /etc/harbor/ssl/notary_server.key
{% endif %}
env_file:
- ./common/config/notary/server_env
depends_on:
{% if external_database == False %}
- postgresql
{% endif %}
- notary-signer
logging:
driver: "syslog"
options:
syslog-address: "tcp://localhost:1514"
tag: "notary-server"
notary-signer:
image: goharbor/notary-signer-photon:{{notary_version}}
container_name: notary-signer
restart: always
networks:
harbor-notary:
notary-sig:
aliases:
- notarysigner
volumes:
- ./common/config/notary:/etc/notary:z
- type: bind
source: {{data_volume}}/secret/notary/notary-signer.crt
target: /etc/notary/notary-signer.crt
- type: bind
source: {{data_volume}}/secret/notary/notary-signer.key
target: /etc/notary/notary-signer.key
- type: bind
source: ./common/config/shared/trust-certificates
target: /harbor_cust_cert
{%if internal_tls.enabled %}
- type: bind
source: {{internal_tls.notary_signer_crt_path}}
target: /etc/harbor/ssl/notary_signer.crt
- type: bind
source: {{internal_tls.notary_signer_key_path}}
target: /etc/harbor/ssl/notary_signer.key
{% endif %}
env_file:
- ./common/config/notary/signer_env
depends_on:
- log
{% if external_database == False %}
- postgresql
{% endif %}
logging:
driver: "syslog"
options:
syslog-address: "tcp://localhost:1514"
tag: "notary-signer"
{% endif %}
{% if with_trivy %}
trivy-adapter:
container_name: trivy-adapter
@ -494,10 +400,4 @@ services:
networks:
harbor:
external: false
{% if with_notary %}
harbor-notary:
external: false
notary-sig:
external: false
{% endif %}

View File

@ -1,33 +0,0 @@
server {
listen 4443 ssl;
server_tokens off;
# ssl
ssl_certificate {{ssl_cert}};
ssl_certificate_key {{ssl_cert_key}};
# recommendations from https://raymii.org/s/tutorials/strong_ssl_security_on_nginx.html
ssl_protocols tlsv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:ssl:10m;
# disable any limits to avoid http 413 for large image uploads
client_max_body_size 0;
# required to avoid http 411: see issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;
location /v2/ {
proxy_pass http://notary-server/v2/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# When setting up Harbor behind other proxy, such as an Nginx instance, remove the below line if the proxy already has similar settings.
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
}

View File

@ -1,3 +0,0 @@
upstream notary-server {
server notary-server:4443;
}

View File

@ -1,28 +0,0 @@
{
"server": {
"http_addr": ":4443"
},
"trust_service": {
"type": "remote",
"hostname": "notarysigner",
"port": "7899",
"tls_ca_file": "./notary-signer-ca.crt",
"key_algorithm": "ecdsa"
},
"logging": {
"level": "debug"
},
"storage": {
"backend": "postgres",
"db_url": "postgres://{{notary_server_db_username}}:{{notary_server_db_password}}@{{notary_server_db_host}}:{{notary_server_db_port}}/{{notary_server_db_name}}?sslmode={{notary_server_db_sslmode}}"
},
"auth": {
"type": "token",
"options": {
"realm": "{{token_endpoint}}/service/token",
"service": "harbor-notary",
"issuer": "harbor-token-issuer",
"rootcertbundle": "/etc/notary/root.crt"
}
}
}

View File

@ -1,2 +0,0 @@
MIGRATIONS_PATH=migrations/server/postgresql
DB_URL=postgres://{{notary_server_db_username}}:{{notary_server_db_password}}@{{notary_server_db_host}}:{{notary_server_db_port}}/{{notary_server_db_name}}?sslmode={{notary_server_db_sslmode}}

View File

@ -1,15 +0,0 @@
{
"server": {
"grpc_addr": ":7899",
"tls_cert_file": "./notary-signer.crt",
"tls_key_file": "./notary-signer.key"
},
"logging": {
"level": "debug"
},
"storage": {
"backend": "postgres",
"db_url": "postgres://{{notary_signer_db_username}}:{{notary_signer_db_password}}@{{notary_signer_db_host}}:{{notary_signer_db_port}}/{{notary_signer_db_name}}?sslmode={{notary_signer_db_sslmode}}",
"default_alias": "defaultalias"
}
}

View File

@ -1,3 +0,0 @@
NOTARY_SIGNER_DEFAULTALIAS={{alias}}
MIGRATIONS_PATH=migrations/signer/postgresql
DB_URL=postgres://{{notary_signer_db_username}}:{{notary_signer_db_password}}@{{notary_signer_db_host}}:{{notary_signer_db_port}}/{{notary_signer_db_name}}?sslmode={{notary_signer_db_sslmode}}

View File

@ -25,9 +25,6 @@ def validate(conf: dict, **kwargs):
# protocol validate
protocol = conf.get("protocol")
if protocol != "https" and kwargs.get('notary_mode'):
raise Exception(
"Error: the protocol must be https when Harbor is deployed with Notary")
if protocol == "https":
if not conf.get("cert_path") or conf["cert_path"] == default_https_cert_path:
raise Exception("Error: The protocol is https but attribute ssl_cert is not set")
@ -97,7 +94,7 @@ def parse_versions():
return versions
def parse_yaml_config(config_file_path, with_notary, with_trivy):
def parse_yaml_config(config_file_path, with_trivy):
'''
:param configs: config_parser object
:returns: dict of configs
@ -115,7 +112,6 @@ def parse_yaml_config(config_file_path, with_notary, with_trivy):
'token_service_url': 'http://core:8080/service/token',
'jobservice_url': 'http://jobservice:8080',
'trivy_adapter_url': 'http://trivy-adapter:8080',
'notary_url': 'http://notary-server:4443',
}
config_dict['hostname'] = configs["hostname"]
@ -160,22 +156,6 @@ def parse_yaml_config(config_file_path, with_notary, with_trivy):
config_dict['harbor_db_conn_max_lifetime'] = db_configs.get("conn_max_lifetime") or '5m'
config_dict['harbor_db_conn_max_idle_time'] = db_configs.get("conn_max_idle_time") or '0'
if with_notary:
# notary signer
config_dict['notary_signer_db_host'] = 'postgresql'
config_dict['notary_signer_db_port'] = 5432
config_dict['notary_signer_db_name'] = 'notarysigner'
config_dict['notary_signer_db_username'] = 'signer'
config_dict['notary_signer_db_password'] = 'password'
config_dict['notary_signer_db_sslmode'] = 'disable'
# notary server
config_dict['notary_server_db_host'] = 'postgresql'
config_dict['notary_server_db_port'] = 5432
config_dict['notary_server_db_name'] = 'notaryserver'
config_dict['notary_server_db_username'] = 'server'
config_dict['notary_server_db_password'] = 'password'
config_dict['notary_server_db_sslmode'] = 'disable'
# Data path volume
config_dict['data_volume'] = configs['data_volume']
@ -287,21 +267,6 @@ def parse_yaml_config(config_file_path, with_notary, with_trivy):
config_dict['harbor_db_conn_max_lifetime'] = external_db_configs['harbor'].get("conn_max_lifetime") or '5m'
config_dict['harbor_db_conn_max_idle_time'] = external_db_configs['harbor'].get("conn_max_idle_time") or '0'
if with_notary:
# notary signer
config_dict['notary_signer_db_host'] = external_db_configs['notary_signer']['host']
config_dict['notary_signer_db_port'] = external_db_configs['notary_signer']['port']
config_dict['notary_signer_db_name'] = external_db_configs['notary_signer']['db_name']
config_dict['notary_signer_db_username'] = external_db_configs['notary_signer']['username']
config_dict['notary_signer_db_password'] = external_db_configs['notary_signer']['password']
config_dict['notary_signer_db_sslmode'] = external_db_configs['notary_signer']['ssl_mode']
# notary server
config_dict['notary_server_db_host'] = external_db_configs['notary_server']['host']
config_dict['notary_server_db_port'] = external_db_configs['notary_server']['port']
config_dict['notary_server_db_name'] = external_db_configs['notary_server']['db_name']
config_dict['notary_server_db_username'] = external_db_configs['notary_server']['username']
config_dict['notary_server_db_password'] = external_db_configs['notary_server']['password']
config_dict['notary_server_db_sslmode'] = external_db_configs['notary_server']['ssl_mode']
else:
config_dict['external_database'] = False
@ -325,7 +290,6 @@ def parse_yaml_config(config_file_path, with_notary, with_trivy):
False,
internal_tls_config['dir'],
configs['data_volume'],
with_notary=with_notary,
with_trivy=with_trivy,
external_database=config_dict['external_database'])
else:
@ -351,7 +315,6 @@ def parse_yaml_config(config_file_path, with_notary, with_trivy):
config_dict['token_service_url'] = 'https://core:8443/service/token'
config_dict['jobservice_url'] = 'https://jobservice:8443'
config_dict['trivy_adapter_url'] = 'https://trivy-adapter:8443'
# config_dict['notary_url'] = 'http://notary-server:4443'
# purge upload configs
purge_upload_config = configs.get('upload_purging')

View File

@ -13,7 +13,7 @@ core_conf = os.path.join(config_dir, "core", "app.conf")
ca_download_dir = os.path.join(data_dir, 'ca_download')
def prepare_core(config_dict, with_notary, with_trivy):
def prepare_core(config_dict, with_trivy):
prepare_dir(ca_download_dir, uid=DEFAULT_UID, gid=DEFAULT_GID)
prepare_dir(core_config_dir)
# Render Core
@ -21,7 +21,6 @@ def prepare_core(config_dict, with_notary, with_trivy):
render_jinja(
core_env_template_path,
core_conf_env,
with_notary=with_notary,
with_trivy=with_trivy,
csrf_key=generate_random_string(32),
scan_robot_prefix=generate_random_string(8),

View File

@ -8,7 +8,7 @@ docker_compose_template_path = os.path.join(templates_dir, 'docker_compose', 'do
docker_compose_yml_path = '/compose_location/docker-compose.yml'
# render docker-compose
def prepare_docker_compose(configs, with_trivy, with_notary):
def prepare_docker_compose(configs, with_trivy):
versions = parse_versions()
VERSION_TAG = versions.get('VERSION_TAG') or 'dev'
@ -16,7 +16,6 @@ def prepare_docker_compose(configs, with_trivy, with_notary):
'version': VERSION_TAG,
'reg_version': VERSION_TAG,
'redis_version': VERSION_TAG,
'notary_version': VERSION_TAG,
'trivy_adapter_version': VERSION_TAG,
'data_volume': configs['data_volume'],
'log_location': configs['log_location'],
@ -24,7 +23,6 @@ def prepare_docker_compose(configs, with_trivy, with_notary):
'http_port': configs['http_port'],
'external_redis': configs['external_redis'],
'external_database': configs['external_database'],
'with_notary': with_notary,
'with_trivy': with_trivy,
}

View File

@ -19,9 +19,6 @@ def mark_file(path, mode=0o600, uid=DEFAULT_UID, gid=DEFAULT_GID):
def validate(conf, **kwargs):
# Protocol validate
protocol = conf.get("configuration", "ui_url_protocol")
if protocol != "https" and kwargs.get('notary_mode'):
raise Exception(
"Error: the protocol must be https when Harbor is deployed with Notary")
if protocol == "https":
if not conf.has_option("configuration", "ssl_cert"):
raise Exception(

View File

@ -1,144 +0,0 @@
import os, shutil, pathlib
from g import templates_dir, config_dir, secret_key_dir, secret_dir, DEFAULT_UID, DEFAULT_GID
from .cert import openssl_installed, create_cert, create_root_cert, get_alias, create_ext_file, san_existed
from .jinja import render_jinja
from .misc import mark_file, prepare_dir
notary_template_dir = os.path.join(templates_dir, "notary")
notary_signer_pg_template = os.path.join(notary_template_dir, "signer-config.postgres.json.jinja")
notary_server_pg_template = os.path.join(notary_template_dir, "server-config.postgres.json.jinja")
notary_server_nginx_config_template = os.path.join(templates_dir, "nginx", "notary.server.conf.jinja")
notary_signer_env_template = os.path.join(notary_template_dir, "signer_env.jinja")
notary_server_env_template = os.path.join(notary_template_dir, "server_env.jinja")
notary_config_dir = os.path.join(config_dir, 'notary')
notary_signer_pg_config = os.path.join(notary_config_dir, "signer-config.postgres.json")
notary_server_pg_config = os.path.join(notary_config_dir, "server-config.postgres.json")
notary_server_config_path = os.path.join(notary_config_dir, 'notary.server.conf')
notary_signer_env_path = os.path.join(notary_config_dir, "signer_env")
notary_server_env_path = os.path.join(notary_config_dir, "server_env")
def prepare_env_notary(nginx_config_dir):
prepare_dir(notary_config_dir)
old_signer_cert_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer.crt'))
old_signer_key_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer.key'))
old_signer_ca_cert_secret_path = pathlib.Path(os.path.join(config_dir, 'notary-signer-ca.crt'))
notary_secret_dir = prepare_dir(secret_dir ,'notary')
signer_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.crt'))
signer_key_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer.key'))
signer_ca_cert_secret_path = pathlib.Path(os.path.join(notary_secret_dir, 'notary-signer-ca.crt'))
# If openssl installed, using it to check san existed in cert.
# Remove cert file if it not contains san
if signer_cert_secret_path.exists() and openssl_installed():
if not san_existed(signer_cert_secret_path):
try:
signer_cert_secret_path.unlink()
except FileNotFoundError:
pass
if old_signer_cert_secret_path.exists() and openssl_installed():
if not san_existed(old_signer_cert_secret_path):
try:
old_signer_cert_secret_path.unlink()
except FileNotFoundError:
pass
# In version 1.8 the secret path changed
# If all cert, key and ca files are existed in new location don't do anything
# Or we should do the following logic
if not(
signer_cert_secret_path.exists() and
signer_key_secret_path.exists() and
signer_ca_cert_secret_path.exists()
):
# If the certs are exist in old localtion, move them to new location
if old_signer_ca_cert_secret_path.exists() and old_signer_cert_secret_path.exists() and old_signer_key_secret_path.exists():
print("Copying certs for notary signer")
shutil.copy2(old_signer_ca_cert_secret_path, signer_ca_cert_secret_path)
shutil.copy2(old_signer_key_secret_path, signer_key_secret_path)
shutil.copy2(old_signer_cert_secret_path, signer_cert_secret_path)
# If certs neither existed in new location nor in the old place, create it and move it to new location
elif openssl_installed():
try:
temp_cert_dir = os.path.join('/tmp', "cert_tmp")
if not os.path.exists(temp_cert_dir):
os.makedirs(temp_cert_dir)
ca_subj = "/C=US/ST=California/L=Palo Alto/O=GoHarbor/OU=Harbor/CN=Self-signed by GoHarbor"
cert_subj = "/C=US/ST=California/L=Palo Alto/O=GoHarbor/OU=Harbor/CN=notarysigner"
signer_ca_cert = os.path.join(temp_cert_dir, "notary-signer-ca.crt")
signer_ca_key = os.path.join(temp_cert_dir, "notary-signer-ca.key")
signer_cert_path = os.path.join(temp_cert_dir, "notary-signer.crt")
signer_key_path = os.path.join(temp_cert_dir, "notary-signer.key")
create_root_cert(ca_subj, key_path=signer_ca_key, cert_path=signer_ca_cert)
create_ext_file('notarysigner', 'extfile.cnf')
create_cert(cert_subj, signer_ca_key, signer_ca_cert, key_path=signer_key_path, cert_path=signer_cert_path)
print("Copying certs for notary signer")
shutil.copy2(signer_cert_path, signer_cert_secret_path)
shutil.copy2(signer_key_path, signer_key_secret_path)
shutil.copy2(signer_ca_cert, signer_ca_cert_secret_path)
finally:
srl_tmp = os.path.join(os.getcwd(), ".srl")
if os.path.isfile(srl_tmp):
os.remove(srl_tmp)
if os.path.isdir(temp_cert_dir):
shutil.rmtree(temp_cert_dir, True)
else:
raise(Exception("No certs for notary"))
print("Copying nginx configuration file for notary")
render_jinja(
os.path.join(templates_dir, "nginx", "notary.upstream.conf.jinja"),
os.path.join(nginx_config_dir, "notary.upstream.conf"),
gid=DEFAULT_GID,
uid=DEFAULT_UID)
mark_file(os.path.join(notary_secret_dir, "notary-signer.crt"))
mark_file(os.path.join(notary_secret_dir, "notary-signer.key"))
mark_file(os.path.join(notary_secret_dir, "notary-signer-ca.crt"))
def prepare_notary(config_dict, nginx_config_dir, ssl_cert_path, ssl_cert_key_path):
prepare_env_notary(nginx_config_dir)
render_jinja(
notary_server_nginx_config_template,
os.path.join(nginx_config_dir, "notary.server.conf"),
gid=DEFAULT_GID,
uid=DEFAULT_UID,
ssl_cert=ssl_cert_path,
ssl_cert_key=ssl_cert_key_path)
render_jinja(
notary_server_pg_template,
notary_server_pg_config,
uid=DEFAULT_UID,
gid=DEFAULT_GID,
token_endpoint=config_dict['public_url'],
**config_dict)
render_jinja(
notary_server_env_template,
notary_server_env_path,
**config_dict
)
default_alias = get_alias(secret_key_dir)
render_jinja(
notary_signer_env_template,
notary_signer_env_path,
alias=default_alias,
**config_dict)
render_jinja(
notary_signer_pg_template,
notary_signer_pg_config,
uid=DEFAULT_UID,
gid=DEFAULT_GID,
alias=default_alias,
**config_dict)

View File

@ -92,7 +92,6 @@ const (
MaxJobWorkers = "max_job_workers"
TokenExpiration = "token_expiration"
AdminInitialPassword = "admin_initial_password"
WithNotary = "with_notary"
WithTrivy = "with_trivy"
ScanAllPolicy = "scan_all_policy"
UAAEndpoint = "uaa_endpoint"
@ -127,9 +126,7 @@ const (
GroupMember = "g"
ReadOnly = "read_only"
TrivyAdapterURL = "trivy_adapter_url"
NotaryURL = "notary_url"
DefaultCoreEndpoint = "http://core:8080"
DefaultNotaryEndpoint = "http://notary-server:4443"
LDAPGroupType = 1
HTTPGroupType = 2
OIDCGroupType = 3

View File

@ -54,7 +54,6 @@ var defaultConfig = map[string]interface{}{
common.MaxJobWorkers: 3,
common.TokenExpiration: 30,
common.AdminInitialPassword: "password",
common.WithNotary: false,
common.WithTrivy: false,
common.UAAClientID: "testid",
common.UAAClientSecret: "testsecret",
@ -63,7 +62,6 @@ var defaultConfig = map[string]interface{}{
common.CoreURL: "http://myui:8888/",
common.JobServiceURL: "http://myjob:8888/",
common.ReadOnly: false,
common.NotaryURL: "http://notary-server:4443",
common.RobotNamePrefix: "robot$",
}

View File

@ -121,9 +121,7 @@ func GetUnitTestConfig() map[string]interface{} {
common.LDAPGroupAttributeName: "cn",
common.LDAPGroupSearchScope: 2,
common.LDAPGroupAdminDn: "cn=harbor_users,ou=groups,dc=example,dc=com",
common.WithNotary: "false",
common.SelfRegistration: "true",
common.WithTrivy: "true",
common.TokenServiceURL: "http://core:8080/service/token",
common.RegistryURL: fmt.Sprintf("http://%s:5000", ipAddress),
common.ReadOnly: false,

View File

@ -52,7 +52,6 @@ import (
"github.com/goharbor/harbor/src/pkg/notifier/event"
"github.com/goharbor/harbor/src/pkg/registry"
"github.com/goharbor/harbor/src/pkg/repository"
"github.com/goharbor/harbor/src/pkg/signature"
model_tag "github.com/goharbor/harbor/src/pkg/tag/model/tag"
)
@ -122,7 +121,6 @@ func NewController() Controller {
artMgr: pkg.ArtifactMgr,
artrashMgr: artifactrash.Mgr,
blobMgr: blob.Mgr,
sigMgr: signature.GetManager(),
labelMgr: label.Mgr,
immutableMtr: rule.NewRuleMatcher(),
regCli: registry.Cli,
@ -137,7 +135,6 @@ type controller struct {
artMgr artifact.Manager
artrashMgr artifactrash.Manager
blobMgr blob.Manager
sigMgr signature.Manager
labelMgr label.Manager
immutableMtr match.ImmutableTagMatcher
regCli registry.Client

View File

@ -146,14 +146,6 @@ func registryCtlHealthChecker() health.Checker {
return PeriodicHealthChecker(checker, period)
}
func notaryHealthChecker() health.Checker {
url := config.InternalNotaryEndpoint() + "/_notary_server/health"
timeout := 60 * time.Second
period := 10 * time.Second
checker := HTTPStatusCodeHealthChecker(http.MethodGet, url, nil, timeout, http.StatusOK)
return PeriodicHealthChecker(checker, period)
}
func databaseHealthChecker() health.Checker {
period := 10 * time.Second
checker := health.CheckFunc(func() error {
@ -191,9 +183,6 @@ func RegisterHealthCheckers() {
registry["registryctl"] = registryCtlHealthChecker()
registry["database"] = databaseHealthChecker()
registry["redis"] = redisHealthChecker()
if config.WithNotary() {
registry["notary"] = notaryHealthChecker()
}
if config.WithTrivy() {
registry["trivy"] = trivyHealthChecker()
}

View File

@ -65,7 +65,6 @@ var defaultConfigWithVerifyCert = map[string]interface{}{
common.MaxJobWorkers: 3,
common.TokenExpiration: 30,
common.AdminInitialPassword: "password",
common.WithNotary: false,
}
var ldapCfg = models.LdapConf{

View File

@ -26,7 +26,6 @@ import (
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/controller/scan"
"github.com/goharbor/harbor/src/controller/tag"
"github.com/goharbor/harbor/src/core/service/token"
"github.com/goharbor/harbor/src/jobservice/job"
"github.com/goharbor/harbor/src/lib/config"
@ -353,9 +352,6 @@ func (de *defaultEnforcer) getCandidates(ctx context.Context, ps *pol.Schema, p
}, &artifact.Option{
WithLabel: true,
WithTag: true,
TagOption: &tag.Option{
WithSignature: true,
},
})
if err != nil {
return nil, err
@ -517,16 +513,13 @@ func (de *defaultEnforcer) toCandidates(ctx context.Context, p *proModels.Projec
// TODO: Do we need to support untagged artifacts here?
for _, t := range a.Tags {
candidates = append(candidates, &selector.Candidate{
NamespaceID: p.ProjectID,
Namespace: p.Name,
Repository: pureRepository(p.Name, a.RepositoryName),
Kind: pr.SupportedType,
Digest: a.Digest,
Tags: []string{t.Name},
Labels: getLabels(a.Labels),
Signatures: map[string]bool{
t.Name: t.Signed,
},
NamespaceID: p.ProjectID,
Namespace: p.Name,
Repository: pureRepository(p.Name, a.RepositoryName),
Kind: pr.SupportedType,
Digest: a.Digest,
Tags: []string{t.Name},
Labels: getLabels(a.Labels),
VulnerabilitySeverity: sev,
})
}

View File

@ -125,7 +125,6 @@ func (suite *EnforcerTestSuite) SetupSuite() {
Name: "library",
CVEAllowlist: models2.CVEAllowlist{},
Metadata: map[string]string{
proMetaKeyContentTrust: "true",
proMetaKeyVulnerability: "true",
proMetaKeySeverity: "high",
},
@ -260,12 +259,10 @@ func mockArtifacts() []*car.Artifact {
Tag: ta.Tag{
Name: "prod",
},
Signed: true,
}, {
Tag: ta.Tag{
Name: "stage",
},
Signed: false,
},
},
Labels: []*model.Label{
@ -288,12 +285,10 @@ func mockArtifacts() []*car.Artifact {
Tag: ta.Tag{
Name: "latest",
},
Signed: true,
}, {
Tag: ta.Tag{
Name: "stage",
},
Signed: true,
},
},
Labels: []*model.Label{

View File

@ -53,7 +53,6 @@ type Data struct {
type protectedData struct {
CurrentTime time.Time
WithNotary bool
RegistryURL string
ExtURL string
ProjectCreationRestrict string
@ -119,7 +118,6 @@ func (c *controller) GetInfo(ctx context.Context, opt Options) (*Data, error) {
enableCADownload := caStatErr == nil && strings.HasPrefix(extURL, "https://")
res.Protected = &protectedData{
CurrentTime: time.Now(),
WithNotary: config.WithNotary(),
ReadOnly: config.ReadOnly(ctx),
ExtURL: extURL,
RegistryURL: registryURL,

View File

@ -31,7 +31,6 @@ func (s *sysInfoCtlTestSuite) SetupTest() {
common.RegistryStorageProviderName: "filesystem",
common.ReadOnly: false,
common.NotificationEnable: false,
common.WithNotary: true,
}
config.InitWithSettings(conf)
@ -68,7 +67,6 @@ func (s *sysInfoCtlTestSuite) TestGetInfo() {
HarborVersion: "test-fakeid",
SelfRegistration: true,
Protected: &protectedData{
WithNotary: true,
RegistryURL: "test.goharbor.io",
ExtURL: "https://test.goharbor.io",
ProjectCreationRestrict: "everyone",

View File

@ -21,7 +21,6 @@ import (
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/lib/selector"
@ -29,7 +28,6 @@ import (
"github.com/goharbor/harbor/src/pkg/artifact"
"github.com/goharbor/harbor/src/pkg/immutable/match"
"github.com/goharbor/harbor/src/pkg/immutable/match/rule"
"github.com/goharbor/harbor/src/pkg/signature"
"github.com/goharbor/harbor/src/pkg/tag"
model_tag "github.com/goharbor/harbor/src/pkg/tag/model/tag"
)
@ -183,7 +181,6 @@ func (c *controller) Update(ctx context.Context, tag *Tag, props ...string) (err
func (c *controller) Delete(ctx context.Context, id int64) (err error) {
option := &Option{
WithImmutableStatus: true,
WithSignature: true,
}
tag, err := c.Get(ctx, id, option)
if err != nil {
@ -193,10 +190,6 @@ func (c *controller) Delete(ctx context.Context, id int64) (err error) {
return errors.New(nil).WithCode(errors.PreconditionCode).
WithMessage("the tag %s configured as immutable, cannot be deleted", tag.Name)
}
if tag.Signed {
return errors.New(nil).WithCode(errors.PreconditionCode).
WithMessage("the tag %s with signature cannot be deleted", tag.Name)
}
return c.tagMgr.Delete(ctx, id)
}
@ -222,9 +215,6 @@ func (c *controller) assembleTag(ctx context.Context, tag *model_tag.Tag, option
if option.WithImmutableStatus {
c.populateImmutableStatus(ctx, t)
}
if option.WithSignature {
c.populateTagSignature(ctx, t, option)
}
return t
}
@ -244,19 +234,3 @@ func (c *controller) populateImmutableStatus(ctx context.Context, tag *Tag) {
}
tag.Immutable = matched
}
func (c *controller) populateTagSignature(ctx context.Context, tag *Tag, option *Option) {
artifact, err := c.artMgr.Get(ctx, tag.ArtifactID)
if err != nil {
return
}
if option.SignatureChecker == nil {
chk, err := signature.GetManager().GetCheckerByRepo(ctx, artifact.RepositoryName)
if err != nil {
log.Error(err)
return
}
option.SignatureChecker = chk
}
tag.Signed = option.SignatureChecker.IsTagSigned(tag.Name, artifact.Digest)
}

View File

@ -21,8 +21,6 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
pkg_artifact "github.com/goharbor/harbor/src/pkg/artifact"
@ -54,11 +52,6 @@ func (c *controllerTestSuite) SetupTest() {
artMgr: c.artMgr,
immutableMtr: c.immutableMtr,
}
var tagCtlTestConfig = map[string]interface{}{
common.WithNotary: false,
}
config.InitWithSettings(tagCtlTestConfig)
}
func (c *controllerTestSuite) TestEnsureTag() {

View File

@ -15,7 +15,6 @@
package tag
import (
"github.com/goharbor/harbor/src/pkg/signature"
"github.com/goharbor/harbor/src/pkg/tag/model/tag"
)
@ -23,12 +22,9 @@ import (
type Tag struct {
tag.Tag
Immutable bool `json:"immutable"`
Signed bool `json:"signed"`
}
// Option is used to specify the properties returned when listing/getting tags
type Option struct {
WithImmutableStatus bool
WithSignature bool
SignatureChecker *signature.Checker
}

View File

@ -74,7 +74,6 @@ var defaultConfigWithVerifyCert = map[string]interface{}{
common.MaxJobWorkers: 3,
common.TokenExpiration: 30,
common.AdminInitialPassword: "password",
common.WithNotary: false,
}
func (c *controllerTestSuite) TestCRUDUserGroup() {

View File

@ -28,14 +28,12 @@ import (
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
)
var creatorMap map[string]Creator
var registryFilterMap map[string]accessFilter
var notaryFilterMap map[string]accessFilter
var actionScopeMap = map[rbac.Action]string{
// Scopes checked by distribution, see: https://github.com/docker/distribution/blob/master/registry/handlers/app.go
rbac.ActionPull: "pull",
@ -46,8 +44,6 @@ var actionScopeMap = map[rbac.Action]string{
}
const (
// Notary service
Notary = "harbor-notary"
// Registry service
Registry = "harbor-registry"
)
@ -61,23 +57,6 @@ func InitCreators() {
},
"registry": &registryFilter{},
}
ext, err := config.ExtURL()
if err != nil {
log.Warningf("Failed to get ext url, err: %v, the token service will not be functional with notary requests", err)
} else {
notaryFilterMap = map[string]accessFilter{
"repository": &repositoryFilter{
parser: &endpointParser{
endpoint: ext,
},
},
}
creatorMap[Notary] = &generalCreator{
service: Notary,
filterMap: notaryFilterMap,
}
}
creatorMap[Registry] = &generalCreator{
service: Registry,
filterMap: registryFilterMap,
@ -202,15 +181,6 @@ func resourceScopes(ctx context.Context, rc rbac.Resource) map[string]struct{} {
}
}
// "*" is needed in the token for some API in notary server
// see https://github.com/goharbor/harbor/issues/14303#issuecomment-788010900
// and https://github.com/theupdateframework/notary/blob/84287fd8df4f172c9a8289641cdfa355fc86989d/server/server.go#L200
_, ok1 := res["push"]
_, ok2 := res["pull"]
_, ok3 := res["delete"]
if ok1 && ok2 && ok3 {
res["*"] = struct{}{}
}
return res
}

View File

@ -260,7 +260,6 @@ func TestFilterAccess(t *testing.T) {
var err error
s := []string{"registry:catalog:*"}
a1 := GetResourceActions(s)
a2 := GetResourceActions(s)
a3 := GetResourceActions(s)
ra1 := token.ResourceActions{
@ -284,12 +283,6 @@ func TestFilterAccess(t *testing.T) {
assert.Nil(t, err, "Unexpected error: %v", err)
assert.Equal(t, ra1, *a1[0], "Mismatch after registry filter Map")
err = filterAccess(ctx(&fakeSecurityContext{
isAdmin: true,
}), a2, nil, notaryFilterMap)
assert.Nil(t, err, "Unexpected error: %v", err)
assert.Equal(t, ra2, *a2[0], "Mismatch after notary filter Map")
err = filterAccess(ctx(&fakeSecurityContext{
isAdmin: false,
}), a3, nil, registryFilterMap)
@ -342,7 +335,6 @@ func TestResourceScopes(t *testing.T) {
"scanner-pull": {},
"push": {},
"delete": {},
"*": {},
},
},
{

View File

@ -41,17 +41,18 @@ require (
github.com/jackc/pgconn v1.9.0
github.com/jackc/pgx/v4 v4.12.0
github.com/jpillora/backoff v1.0.0
github.com/ncw/swift v1.0.49 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0
github.com/robfig/cron/v3 v3.0.0
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.8.2
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62
github.com/theupdateframework/notary v0.6.1
github.com/vmihailenco/msgpack/v5 v5.0.0-rc.2
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.22.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.22.0
@ -91,18 +92,13 @@ require (
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/Unknwon/goconfig v0.0.0-20160216183935-5f601ca6ef4d // indirect
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bugsnag/bugsnag-go v1.5.2 // indirect
github.com/bugsnag/panicwrap v1.2.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudflare/cfssl v0.0.0-20190510060611-9c027c93ba9e // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dnaeon/go-vcr v1.2.0 // indirect
github.com/docker/go v0.0.0-20160303222718-d30aec9fd63c // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
@ -114,7 +110,6 @@ require (
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/certificate-transparency-go v1.0.21 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
@ -131,7 +126,6 @@ require (
github.com/jackc/pgproto3/v2 v2.1.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.8.0 // indirect
github.com/jinzhu/gorm v1.9.8 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
@ -139,11 +133,9 @@ require (
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ncw/swift v1.0.49 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
@ -179,9 +171,6 @@ require (
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/dancannon/gorethink.v3 v3.0.5 // indirect
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect

View File

@ -1,7 +1,6 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
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=
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
@ -118,15 +117,12 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/Unknwon/goconfig v0.0.0-20160216183935-5f601ca6ef4d h1:RjxaKUAINjr+fYbaYjpdBUZc8R3+wF/Yr2XkDHho4Sg=
github.com/Unknwon/goconfig v0.0.0-20160216183935-5f601ca6ef4d/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -210,14 +206,9 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bugsnag/bugsnag-go v1.5.2 h1:fdaGJJEReigPzSE6HajOhpJwE2IEP/TdHDHXKGeOJtc=
github.com/bugsnag/bugsnag-go v1.5.2/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/panicwrap v1.2.0 h1:OzrKrRvXis8qEvOkfcxNcYbOd2O7xXS2nnKMEMABFQA=
github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/casbin/casbin v1.9.1 h1:ucjbS5zTrmSLtH4XogqOG920Poe6QatdXtz1FEbApeM=
github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZllfog=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
@ -242,8 +233,6 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudevents/sdk-go/v2 v2.13.0 h1:2zxDS8RyY1/wVPULGGbdgniGXSzLaRJVl136fLXGsYw=
github.com/cloudevents/sdk-go/v2 v2.13.0/go.mod h1:xDmKfzNjM8gBvjaF8ijFjM1VYOVUEeUfapHMUX1T5To=
github.com/cloudflare/cfssl v0.0.0-20190510060611-9c027c93ba9e h1:ZtyhUG4s94BMUCdgvRZySr/AXYL5CDcjxhIV/83xJog=
github.com/cloudflare/cfssl v0.0.0-20190510060611-9c027c93ba9e/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
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=
@ -371,7 +360,6 @@ github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjI
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-20190423183735-731ef375ac02/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c h1:ZjNKFQ2pBtbkmtporMvGVu2M7fs3Ip3sSy0Gyqsq8xc=
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
@ -389,8 +377,6 @@ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/docker v20.10.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
github.com/docker/go v0.0.0-20160303222718-d30aec9fd63c h1:Ggg7IiOtghyZzn3ozi31kPHpV6qSjMgmesXaWCijYNM=
github.com/docker/go v0.0.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-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
@ -426,7 +412,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
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/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -553,7 +538,6 @@ github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbN
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@ -623,7 +607,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
@ -657,8 +640,6 @@ github.com/gomodule/redigo v1.8.8 h1:f6cXq6RRfiyrOJEV7p3JhLDlmawGBVBBP1MggY8Mo4E
github.com/gomodule/redigo v1.8.8/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@ -684,7 +665,6 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
@ -699,7 +679,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@ -732,7 +711,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
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/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
@ -840,12 +818,7 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jinzhu/gorm v1.9.8 h1:n5uvxqLepIP2R1XF7pudpt9Rv8I3m7G9trGxJVjLZ5k=
github.com/jinzhu/gorm v1.9.8/go.mod h1:bdqTT3q6dhSph2K3pWxrHP6nqxuAp2yQ3KFtc3U3F84=
github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
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.0/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc=
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@ -878,7 +851,6 @@ github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
@ -951,7 +923,6 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@ -960,8 +931,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -1263,8 +1232,6 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62 h1:Vnr3IqaafEuQUciG6D6EaeLJm26Mg8sjAfbI4OoeauM=
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI=
github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0=
github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@ -1321,7 +1288,6 @@ go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS
go.mongodb.org/mongo-driver v1.7.0 h1:hHrvOBWlWB2c7+8Gh/Xi5jj82AgidK/t7KVXBZ+IyUA=
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@ -1449,7 +1415,6 @@ golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+o
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@ -1662,7 +1627,6 @@ golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -1672,7 +1636,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1688,7 +1651,6 @@ golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGm
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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@ -1772,7 +1734,6 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
@ -1865,16 +1826,10 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/dancannon/gorethink.v3 v3.0.5 h1:/g7PWP7zUS6vSNmHSDbjCHQh1Rqn8Jy6zSMQxAsBSMQ=
gopkg.in/dancannon/gorethink.v3 v3.0.5/go.mod h1:GXsi1e3N2OcKhcP6nsYABTiUejbWMFO4GY5a4pEaeEc=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fatih/pool.v2 v2.0.0 h1:xIFeWtxifuQJGk/IEPKsTduEKcKvPmhoiVDGpC40nKg=
gopkg.in/fatih/pool.v2 v2.0.0/go.mod h1:8xVGeu1/2jr2wm5V9SPuMht2H5AEmf5aFMGSQixtjTY=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/gorethink/gorethink.v3 v3.0.5 h1:e2Uc/Xe+hpcVQFsj6MuHlYog3r0JYpnTzwDj/y2O4MU=
gopkg.in/gorethink/gorethink.v3 v3.0.5/go.mod h1:+3yIIHJUGMBK+wyPH+iN5TP+88ikFDfZdqTlK3Y9q8I=
gopkg.in/h2non/gentleman.v1 v1.0.4/go.mod h1:JYuHVdFzS4MKOXe0o+chKJ4hCe6tqKKw9XH9YP6WFrg=
gopkg.in/h2non/gock.v1 v1.0.16 h1:F11k+OafeuFENsjei5t2vMTSTs9L62AdyTe4E1cgdG8=
gopkg.in/h2non/gock.v1 v1.0.16/go.mod h1:XVuDAssexPLwgxCLMvDTWNU5eqklsydR6I5phZ9oPB8=
@ -1920,7 +1875,6 @@ helm.sh/helm/v3 v3.11.3 h1:n1X5yaQTP5DYywlBOZMl2gX398Gp6YwFp/IAVj6+5D4=
helm.sh/helm/v3 v3.11.3/go.mod h1:S+sOdQc3BLvt09a9rSlKKVs9x0N/yx+No0y3qFw+FQ8=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

View File

@ -94,7 +94,6 @@ var (
{Name: common.LDAPGroupMembershipAttribute, Scope: UserScope, Group: LdapBasicGroup, EnvKey: "LDAP_GROUP_MEMBERSHIP_ATTRIBUTE", DefaultValue: "memberof", ItemType: &StringType{}, Editable: true, Description: `The user attribute to identify the group membership`},
{Name: common.MaxJobWorkers, Scope: SystemScope, Group: BasicGroup, EnvKey: "MAX_JOB_WORKERS", DefaultValue: "10", ItemType: &IntType{}, Editable: false},
{Name: common.NotaryURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "NOTARY_URL", DefaultValue: "http://notary-server:4443", ItemType: &StringType{}, Editable: false},
{Name: common.ScanAllPolicy, Scope: UserScope, Group: BasicGroup, EnvKey: "", DefaultValue: "", ItemType: &MapType{}, Editable: false, Description: `The policy to scan images`},
{Name: common.PostGreSQLDatabase, Scope: SystemScope, Group: DatabaseGroup, EnvKey: "POSTGRESQL_DATABASE", DefaultValue: "registry", ItemType: &StringType{}, Editable: false},
@ -145,7 +144,6 @@ var (
{Name: common.OIDCExtraRedirectParms, Scope: UserScope, Group: OIDCGroup, DefaultValue: "{}", ItemType: &StringToStringMapType{}, Description: `Extra parameters to add when redirect request to OIDC provider`},
{Name: common.WithTrivy, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_TRIVY", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
{Name: common.WithNotary, Scope: SystemScope, Group: BasicGroup, EnvKey: "WITH_NOTARY", DefaultValue: "false", ItemType: &BoolType{}, Editable: true},
// the unit of expiration is days
{Name: common.RobotTokenDuration, Scope: UserScope, Group: BasicGroup, EnvKey: "ROBOT_TOKEN_DURATION", DefaultValue: "30", ItemType: &IntType{}, Editable: true, Description: `The robot account token duration in days`},
{Name: common.RobotNamePrefix, Scope: UserScope, Group: BasicGroup, EnvKey: "ROBOT_NAME_PREFIX", DefaultValue: "robot$", ItemType: &StringType{}, Editable: true, Description: `The robot account name prefix`},

View File

@ -132,11 +132,6 @@ func GetExecutionStatusRefreshIntervalSeconds() int64 {
return DefaultMgr().Get(backgroundCtx, common.ExecutionStatusRefreshIntervalSeconds).GetInt64()
}
// WithNotary returns a bool value to indicate if Harbor's deployed with Notary
func WithNotary() bool {
return DefaultMgr().Get(backgroundCtx, common.WithNotary).GetBool()
}
// WithTrivy returns a bool value to indicate if Harbor's deployed with Trivy.
func WithTrivy() bool {
return DefaultMgr().Get(backgroundCtx, common.WithTrivy).GetBool()
@ -195,12 +190,6 @@ func InternalTokenServiceEndpoint() string {
return InternalCoreURL() + "/service/token"
}
// InternalNotaryEndpoint returns notary server endpoint for internal communication between Harbor containers
// This is currently a conventional value and can be unaccessible when Harbor is not deployed with Notary.
func InternalNotaryEndpoint() string {
return DefaultMgr().Get(backgroundCtx, common.NotaryURL).GetString()
}
// TrivyAdapterURL returns the endpoint URL of a Trivy adapter instance, by default it's the one deployed within Harbor.
func TrivyAdapterURL() string {
return DefaultMgr().Get(backgroundCtx, common.TrivyAdapterURL).GetString()

View File

@ -42,8 +42,7 @@ func TestConfig(t *testing.T) {
dao.PrepareTestData([]string{"delete from properties where k='scan_all_policy'"}, []string{})
defaultCACertPath = path.Join(currPath(), "test", "ca.crt")
c := map[string]interface{}{
common.WithTrivy: false,
common.WithNotary: false,
common.WithTrivy: false,
}
Init()
@ -138,12 +137,6 @@ func TestConfig(t *testing.T) {
defaultConfig := test.GetDefaultConfigMap()
Upload(defaultConfig)
if InternalNotaryEndpoint() != "http://notary-server:4443" {
t.Errorf("Unexpected notary endpoint: %s", InternalNotaryEndpoint())
}
if WithNotary() {
t.Errorf("Withnotary should be false")
}
if WithTrivy() {
t.Errorf("WithTrivy should be false")
}

View File

@ -1,95 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package signature
import (
"golang.org/x/net/context"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/signature/notary"
"github.com/goharbor/harbor/src/pkg/signature/notary/model"
)
// Checker checks the signature status of artifact
type Checker struct {
signatures map[string]string
}
// IsTagSigned checks if the tag of the artifact is signed, it also checks the signed artifact has the same digest as parm.
func (sc Checker) IsTagSigned(tag, digest string) bool {
d, ok := sc.signatures[tag]
if len(digest) == 0 {
return ok
}
return digest == d
}
// IsArtifactSigned checks if the artifact with given digest is signed.
func (sc Checker) IsArtifactSigned(digest string) bool {
for _, v := range sc.signatures {
if v == digest {
return true
}
}
return false
}
// Manager interface for handling signatures of artifacts
type Manager interface {
// GetCheckerByRepo returns a Checker for checking signature
GetCheckerByRepo(ctx context.Context, repo string) (*Checker, error)
}
type mgr struct {
}
// GetCheckerByRepo ...
func (m *mgr) GetCheckerByRepo(ctx context.Context, repo string) (*Checker, error) {
if !config.WithNotary() { // return a checker that always return false
return &Checker{}, nil
}
s := make(map[string]string)
targets, err := m.getTargetsByRepo(ctx, repo)
if err != nil {
return nil, err
}
for _, t := range targets {
if d, err := notary.DigestFromTarget(t); err != nil {
log.Warningf("Failed to get signed digest for tag %s, error: %v, skip", t.Tag, err)
} else {
s[t.Tag] = d
}
}
return &Checker{s}, nil
}
func (m *mgr) getTargetsByRepo(ctx context.Context, repo string) ([]model.Target, error) {
name := "unknown"
if sc, ok := security.FromContext(ctx); !ok || sc == nil {
log.Warningf("Unable to get security context")
} else {
name = sc.GetUsername()
}
return notary.GetInternalTargets(ctx, config.InternalNotaryEndpoint(), name, repo)
}
var instance = &mgr{}
// GetManager ...
func GetManager() Manager {
return instance
}

View File

@ -1,106 +0,0 @@
package signature
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
"github.com/goharbor/harbor/src/common"
testutils "github.com/goharbor/harbor/src/common/utils/test"
"github.com/goharbor/harbor/src/lib/config"
_ "github.com/goharbor/harbor/src/pkg/config/db"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
"github.com/goharbor/harbor/src/pkg/signature/notary/test"
)
func TestMain(m *testing.M) {
testutils.InitDatabaseFromEnv()
// B/C the notary requires private key for signing token, b
// before running locally, please make sure the env var is set as follow:
// export TOKEN_PRIVATE_KEY_PATH="/harbor/tests/private_key.pem"
endpoint := "jt-dev.local.goharbor.io"
// notary-demo/busybox:1.0 is signed, more details in the notary/test pkg
notaryServer := test.NewNotaryServer(endpoint)
defer notaryServer.Close()
conf := map[string]interface{}{
common.WithNotary: "true",
common.NotaryURL: notaryServer.URL,
common.ExtEndpoint: "https://" + endpoint,
}
config.InitWithSettings(conf)
result := m.Run()
if result != 0 {
os.Exit(result)
}
}
func TestGetCheckerByRepo(t *testing.T) {
type in struct {
repo string
tag string
digest string
}
type res struct {
tagSigned bool
artSigned bool
}
m := GetManager()
cases := []struct {
input in
expect res
}{
{
input: in{
repo: "library/busybox",
tag: "latest-signed",
digest: "sha256:dd97a3fe6d721c5cf03abac0f50e2848dc583f7c4e41bf39102ceb42edfd1808",
},
expect: res{
tagSigned: true,
artSigned: true,
},
},
{
input: in{
repo: "library/busybox",
tag: "latest-signed",
digest: "sha256:1359608115b94599e5641638bac5aef1ddfaa79bb96057ebf41ebc8d33acf8a8",
},
expect: res{
tagSigned: false,
artSigned: false,
},
},
{
input: in{
repo: "library/busybox",
tag: "2.0",
digest: "sha256:dd97a3fe6d721c5cf03abac0f50e2848dc583f7c4e41bf39102ceb42edfd1808",
},
expect: res{
tagSigned: false,
artSigned: true,
},
},
{
input: in{
repo: "non-exist",
tag: "1.0",
digest: "sha256:1359608115b94599e5641638bac5aef1ddfaa79bb96057ebf41ebc8d33acf8a7",
},
expect: res{
tagSigned: false,
artSigned: false,
},
},
}
for _, c := range cases {
checker, err := m.GetCheckerByRepo(context.Background(), c.input.repo)
assert.Nil(t, err)
assert.Equal(t, c.expect.tagSigned, checker.IsTagSigned(c.input.tag, c.input.digest),
"Unexpected tagSigned value for input: %#v", c.input)
assert.Equal(t, c.expect.artSigned, checker.IsArtifactSigned(c.input.digest), "Unexpected artSigned value for input: %#v", c.input)
}
}

View File

@ -1,130 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notary
import (
"context"
"encoding/hex"
"fmt"
"net/http"
"os"
"path"
"strings"
"github.com/docker/distribution/registry/auth/token"
digest "github.com/opencontainers/go-digest"
"github.com/theupdateframework/notary"
"github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/trustpinning"
"github.com/theupdateframework/notary/tuf/data"
commonhttp "github.com/goharbor/harbor/src/common/http"
tokenutil "github.com/goharbor/harbor/src/core/service/token"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/log"
model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model"
)
var (
notaryCachePath = "/tmp/notary-cache"
trustPin trustpinning.TrustPinConfig
mockRetriever notary.PassRetriever
)
func init() {
mockRetriever = func(keyName, alias string, createNew bool, attempts int) (passphrase string, giveup bool, err error) {
passphrase = "hardcode"
giveup = false
err = nil
return
}
trustPin = trustpinning.TrustPinConfig{}
}
// GetInternalTargets wraps GetTargets to read config values for getting full-qualified repo from internal notary instance.
func GetInternalTargets(ctx context.Context, notaryEndpoint string, username string, repo string) ([]model2.Target, error) {
ext, err := config.ExtEndpoint()
if err != nil {
log.Errorf("Error while reading external endpoint: %v", err)
return nil, err
}
endpoint := strings.Split(ext, "//")[1]
fqRepo := path.Join(endpoint, repo)
return GetTargets(ctx, notaryEndpoint, username, fqRepo)
}
// GetTargets is a help function called by API to fetch signature information of a given repository.
// Per docker's convention the repository should contain the information of endpoint, i.e. it should look
// like "192.168.0.1/library/ubuntu", instead of "library/ubuntu" (fqRepo for fully-qualified repo)
func GetTargets(ctx context.Context, notaryEndpoint string, username string, fqRepo string) ([]model2.Target, error) {
res := []model2.Target{}
t, err := tokenutil.MakeToken(ctx, username, tokenutil.Notary,
[]*token.ResourceActions{
{
Type: "repository",
Name: fqRepo,
Actions: []string{"pull"},
}})
if err != nil {
return nil, err
}
authorizer := &notaryAuthorizer{
token: t.Token,
}
tr := NewTransport(commonhttp.GetHTTPTransport(), authorizer)
gun := data.GUN(fqRepo)
notaryRepo, err := client.NewFileCachedRepository(notaryCachePath, gun, notaryEndpoint, tr, mockRetriever, trustPin)
if err != nil {
return res, err
}
targets, err := notaryRepo.ListTargets(data.CanonicalTargetsRole)
if _, ok := err.(client.ErrRepositoryNotExist); ok {
log.Debugf("Repository not exist, repo: %s, error: %v, returning empty signature", fqRepo, err)
return res, nil
} else if err != nil {
return res, err
}
// Remove root.json such that when remote repository is removed the local cache can't be reused.
rootJSON := path.Join(notaryCachePath, "tuf", fqRepo, "metadata/root.json")
rmErr := os.Remove(rootJSON)
if rmErr != nil {
log.Warningf("Failed to clear cached root.json: %s, error: %v, when repo is removed from notary the signature status maybe incorrect", rootJSON, rmErr)
}
for _, t := range targets {
res = append(res, model2.Target{
Tag: t.Name,
Hashes: t.Hashes,
})
}
return res, nil
}
// DigestFromTarget get a target and return the value of digest, in accordance to Docker-Content-Digest
func DigestFromTarget(t model2.Target) (string, error) {
sha, ok := t.Hashes["sha256"]
if !ok {
return "", fmt.Errorf("no valid hash, expecting sha256")
}
return digest.NewDigestFromHex("sha256", hex.EncodeToString(sha)).String(), nil
}
type notaryAuthorizer struct {
token string
}
func (n *notaryAuthorizer) Modify(req *http.Request) error {
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", n.token))
return nil
}

View File

@ -1,99 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notary
import (
"encoding/json"
"fmt"
"net/http/httptest"
"os"
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/utils/test"
"github.com/goharbor/harbor/src/lib/config"
"github.com/goharbor/harbor/src/lib/orm"
_ "github.com/goharbor/harbor/src/pkg/config/db"
_ "github.com/goharbor/harbor/src/pkg/config/inmemory"
model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model"
test2 "github.com/goharbor/harbor/src/pkg/signature/notary/test"
)
var endpoint = "jt-dev.local.goharbor.io"
var notaryServer *httptest.Server
func TestMain(m *testing.M) {
notaryServer = test2.NewNotaryServer(endpoint)
defer notaryServer.Close()
var defaultConfig = map[string]interface{}{
common.ExtEndpoint: "https://" + endpoint,
common.WithNotary: true,
common.TokenExpiration: 30,
}
config.Init()
test.InitDatabaseFromEnv()
config.Upload(defaultConfig)
notaryCachePath = "/tmp/notary"
result := m.Run()
if result != 0 {
os.Exit(result)
}
}
func TestGetInternalTargets(t *testing.T) {
targets, err := GetInternalTargets(orm.Context(), notaryServer.URL, "admin", "library/busybox")
assert.Nil(t, err, fmt.Sprintf("Unexpected error: %v", err))
assert.Equal(t, 1, len(targets), "")
assert.Equal(t, "latest-signed", targets[0].Tag, "")
}
func TestGetTargets(t *testing.T) {
targets, err := GetTargets(orm.Context(), notaryServer.URL, "admin", path.Join(endpoint, "library/busybox"))
assert.Nil(t, err, fmt.Sprintf("Unexpected error: %v", err))
assert.Equal(t, 1, len(targets), "")
assert.Equal(t, "latest-signed", targets[0].Tag, "")
targets, err = GetTargets(orm.Context(), notaryServer.URL, "admin", path.Join(endpoint, "library/notexist"))
assert.Nil(t, err, fmt.Sprintf("Unexpected error: %v", err))
assert.Equal(t, 0, len(targets), "Targets list should be empty for non exist repo.")
}
func TestGetDigestFromTarget(t *testing.T) {
str := ` {
"tag": "1.0",
"hashes": {
"sha256": "E1lggRW5RZnlZBY4usWu8d36p5u5YFfr9B68jTOs+Kc="
}
}`
var t1 model2.Target
err := json.Unmarshal([]byte(str), &t1)
if err != nil {
panic(err)
}
hash2 := make(map[string][]byte)
t2 := model2.Target{
Tag: "2.0",
Hashes: hash2,
}
d1, err1 := DigestFromTarget(t1)
assert.Nil(t, err1, "Unexpected error: %v", err1)
assert.Equal(t, "sha256:1359608115b94599e5641638bac5aef1ddfaa79bb96057ebf41ebc8d33acf8a7", d1, "digest mismatch")
_, err2 := DigestFromTarget(t2)
assert.NotNil(t, err2, "")
}

View File

@ -1,25 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package model
import "github.com/theupdateframework/notary/tuf/data"
// Target represents the json object of a target of a docker image in notary.
// The struct will be used when repository is know so it won'g contain the name of a repository.
type Target struct {
Tag string `json:"tag"`
Hashes data.Hashes `json:"hashes"`
// TODO: update fields as needed.
}

View File

@ -1,42 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test
import (
"fmt"
"net/http"
"net/http/httptest"
"path"
"runtime"
)
func currPath() string {
_, f, _, ok := runtime.Caller(0)
if !ok {
panic("Failed to get current directory")
}
return path.Dir(f)
}
// NewNotaryServer creates a notary server for testing.
func NewNotaryServer(endpoint string) *httptest.Server {
mux := http.NewServeMux()
validRoot := fmt.Sprintf("/v2/%s/library/busybox/_trust/tuf/", endpoint)
invalidRoot := fmt.Sprintf("/v2/%s/library/busybox/fail/_trust/tuf/", endpoint)
p := currPath()
mux.Handle(validRoot, http.StripPrefix(validRoot, http.FileServer(http.Dir(path.Join(p, "valid")))))
mux.Handle(invalidRoot, http.StripPrefix(invalidRoot, http.FileServer(http.Dir(path.Join(p, "invalid")))))
return httptest.NewServer(mux)
}

View File

@ -1 +0,0 @@
{"signed":{"_type":"Root","consistent_snapshot":false,"expires":"2040-02-19T10:51:17.538343687Z","keys":{"446d15b6810b7d7a4f0678a3fd1302ca8a45fec900f05588f80a31e98744c54b":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5APVHCLytTo+bbqaVXkvXWly/Gqi6Pj7dtGyyxAqi5Y1Q0Yd02n1sifC3jmAUdf4aDiJ8hiZQMNf3kCl00MZEw=="}},"8fdc4b4cff6c2387e34ecee7568eb1a26fb05ebfb751e99b925a4184243d5648":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENwThOKUnYUoklHEBrX1JUfls/s5LG5sNG9iewiaNUzy2+Xbj5P6cALJzgmcHpDFVHq5QXW/trag4zjQvL6S7sQ=="}},"918b6904ce78ed3134205d3668260d55f9be64c78630da0ab6cbbc1d11db924c":{"keytype":"ecdsa","keyval":{"private":null,"public":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbQKP+f2UCgbJre58NdV1hlaQZ7dZKrQJDxUmMSTTAcCnmj8rhMVN+8BAs+ZCvUSMZR9eFw9COcyYiZ/Oj05o2A=="}},"e958c0333d49fdf7dfba08c54fc01bff7319c6f23c1e3cd2f28bb9946a8ff670":{"keytype":"ecdsa-x509","keyval":{"private":null,"public":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJtVENDQVQrZ0F3SUJBZ0lRY0VVejkvbk9PbzVKRWhuNGNXQjZTekFLQmdncWhrak9QUVFEQWpBek1URXcKTHdZRFZRUURFeWhxZEMxa1pYWXViRzlqWVd3dVoyOW9ZWEppYjNJdWFXOHZiR2xpY21GeWVTOWlkWE41WW05NApNQjRYRFRJd01ESXlOREV3TlRFeE5Gb1hEVE13TURJeU1URXdOVEV4TkZvd016RXhNQzhHQTFVRUF4TW9hblF0ClpHVjJMbXh2WTJGc0xtZHZhR0Z5WW05eUxtbHZMMnhwWW5KaGNua3ZZblZ6ZVdKdmVEQlpNQk1HQnlxR1NNNDkKQWdFR0NDcUdTTTQ5QXdFSEEwSUFCREJhS2V5ZWc3M2prWTlXdEhwYk10c1JqMUpyQXh2WXJEcUIyV1JwUjMrdQoxMnVsbktwb1dpOXFYbzdkbEJQMDk2VkkwdFk5T1ludmlFTEhBajE5dmttak5UQXpNQTRHQTFVZER3RUIvd1FFCkF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQXpBTUJnTlZIUk1CQWY4RUFqQUFNQW9HQ0NxR1NNNDkKQkFNQ0EwZ0FNRVVDSUhUM2JZUTBrdFp5eERIdlZHS0x3eXJVQ1djWGpwZUlLWHR2aE5ocmRzRWZBaUVBc1RTNApKcHNRcVI3UUg4TlYrQ0pRdUVKU3AxN2FJUm1wS0JSZ1puclc1ejQ9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}}},"roles":{"root":{"keyids":["e958c0333d49fdf7dfba08c54fc01bff7319c6f23c1e3cd2f28bb9946a8ff670"],"threshold":1},"snapshot":{"keyids":["8fdc4b4cff6c2387e34ecee7568eb1a26fb05ebfb751e99b925a4184243d5648"],"threshold":1},"targets":{"keyids":["446d15b6810b7d7a4f0678a3fd1302ca8a45fec900f05588f80a31e98744c54b"],"threshold":1},"timestamp":{"keyids":["918b6904ce78ed3134205d3668260d55f9be64c78630da0ab6cbbc1d11db924c"],"threshold":1}},"version":1},"signatures":[{"keyid":"e958c0333d49fdf7dfba08c54fc01bff7319c6f23c1e3cd2f28bb9946a8ff670","method":"ecdsa","sig":"/JrNrI8K6+F4yiq3ZKABrVYLJ7HyPLFkVn2op0ZCTzAVlo+hQo7hffV+wuJ7w44OXVLbmcHdOckVocPWQhyOyA=="}]}

View File

@ -1 +0,0 @@
{"signed":{"_type":"Snapshot","expires":"2030-02-21T10:51:17.590339057Z","meta":{"root":{"hashes":{"sha256":"GeR/crf+6uM8Lzq6tZkcLyvunNAfW0XQqK/s/V6JK68=","sha512":"BnORZz1ECC4wQ+VYHNFeG6jnex0QphHMfEaHDbOYGsNHm0N/yrXvoQoLZEISXuSDmiRe8J9NE2n7uwDb0iYxyQ=="},"length":2448},"targets":{"hashes":{"sha256":"eVFLSe6gU1NqhE4NANnOdJTResuIy/+sDqoroLtaaKA=","sha512":"t8IBbWumWjx9ctAkqrvkAb34UctsAR3sJdA7Wv4mWPfSKC0nbIxX/U5tlKWD0VSYTsN/7M0O7odu7poyiRFuCw=="},"length":438}},"version":1},"signatures":[{"keyid":"8fdc4b4cff6c2387e34ecee7568eb1a26fb05ebfb751e99b925a4184243d5648","method":"ecdsa","sig":"nbYYy7rSCkRdZGmBsGHsXbjhW45Xa89kGzg7L3X/qk8ZZKU2+mGmbRxaL5EU3iFk2EHs85mLmY7Io4nIq4GORw=="}]}

View File

@ -1 +0,0 @@
{"signed":{"_type":"Targets","delegations":{"keys":{},"roles":[]},"expires":"2030-02-21T10:51:17.561005523Z","targets":{"latest-signed":{"hashes":{"sha256":"3Zej/m1yHFzwOrrA9Q4oSNxYP3xOQb85ECzrQu39GAg="},"length":527}},"version":2},"signatures":[{"keyid":"446d15b6810b7d7a4f0678a3fd1302ca8a45fec900f05588f80a31e98744c54b","method":"ecdsa","sig":"2Y9o2dzT/7D8NIUHYMlcILrt29fQC7TyqZCjBRGGRMPexUdQTkONHng+3saLPmixvQrJapP9c2dDoffmdWWFuQ=="}]}

View File

@ -1 +0,0 @@
{"signed":{"_type":"Timestamp","expires":"2030-02-21T10:51:17.618848442Z","meta":{"snapshot":{"hashes":{"sha256":"8OktzV/LWHLYl2N9mRsq+YkUCvNEeXBqdDxgIWsDqTs=","sha512":"rZPSDLEX7kBqBPwU7rf/4buWf6bPGoyARV1rlj9uxbSU8P2b5ltACZscoZuQz+Qj57PgPpj8y8GMcGtk883b5A=="},"length":683}},"version":1},"signatures":[{"keyid":"918b6904ce78ed3134205d3668260d55f9be64c78630da0ab6cbbc1d11db924c","method":"ecdsa","sig":"RUDVZgaQvol/97rkHr6pV8QIC1RZnrZ/3O1eQpMIJSR6BnCADmQFN9NUjoaWORlgjCSp2NH2AfHMNY5cHBn9Pg=="}]}

View File

@ -1,54 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notary
import (
"net/http"
"github.com/goharbor/harbor/src/common/http/modifier"
"github.com/goharbor/harbor/src/lib/log"
)
// Transport holds information about base transport and modifiers
type Transport struct {
transport http.RoundTripper
modifiers []modifier.Modifier
}
// NewTransport ...
func NewTransport(transport http.RoundTripper, modifiers ...modifier.Modifier) *Transport {
return &Transport{
transport: transport,
modifiers: modifiers,
}
}
// RoundTrip ...
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
for _, modifier := range t.modifiers {
if err := modifier.Modify(req); err != nil {
return nil, err
}
}
resp, err := t.transport.RoundTrip(req)
if err != nil {
return nil, err
}
log.Debugf("%d | %s %s", resp.StatusCode, req.Method, req.URL.String())
return resp, err
}

View File

@ -1,59 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package notary
import (
"fmt"
"net/http"
"testing"
"github.com/goharbor/harbor/src/common/utils/test"
)
type simpleModifier struct {
}
func (s *simpleModifier) Modify(req *http.Request) error {
req.Header.Set("Authorization", "token")
return nil
}
func TestRoundTrip(t *testing.T) {
server := test.NewServer(
&test.RequestHandlerMapping{
Method: "GET",
Pattern: "/",
Handler: test.Handler(nil),
})
transport := NewTransport(&http.Transport{}, &simpleModifier{})
client := &http.Client{
Transport: transport,
}
req, err := http.NewRequest("GET", fmt.Sprintf("%s/", server.URL), nil)
if err != nil {
t.Fatalf("failed to create request: %v", err)
}
if _, err := client.Do(req); err != nil {
t.Fatalf("failed to send request: %s", err)
}
header := req.Header.Get("Authorization")
if header != "token" {
t.Errorf("unexpected header: %s != %s", header, "token")
}
}

View File

@ -354,57 +354,30 @@ export class ArtifactTagComponent implements OnInit, OnDestroy {
operMessage.state = OperationState.progressing;
operMessage.data.name = tag.name;
this.operationService.publishInfo(operMessage);
if (tag.signed) {
forkJoin(
this.translateService.get('BATCH.DELETED_FAILURE'),
this.translateService.get(
'REPOSITORY.DELETION_SUMMARY_TAG_DENIED'
)
).subscribe(res => {
const wrongInfo: string =
res[1] +
DeleteTagWithNotoryCommand1 +
this.deletePort(this.registryUrl) +
DeleteTagWithNotoryCommand2 +
this.registryUrl +
'/' +
this.repositoryName +
' ' +
tag.name;
operateChanges(operMessage, OperationState.failure, wrongInfo);
});
return of(null);
} else {
const deleteTagParams: ArtifactService.DeleteTagParams = {
projectName: this.projectName,
repositoryName: dbEncodeURIComponent(this.repositoryName),
reference: this.artifactDetails.digest,
tagName: tag.name,
};
return this.artifactService.deleteTag(deleteTagParams).pipe(
map(response => {
this.translateService
.get('BATCH.DELETED_SUCCESS')
.subscribe(res => {
operateChanges(operMessage, OperationState.success);
});
}),
catchError(error => {
const message = errorHandler(error);
this.translateService
.get(message)
.subscribe(res =>
operateChanges(
operMessage,
OperationState.failure,
res
)
);
return of(error);
})
);
}
const deleteTagParams: ArtifactService.DeleteTagParams = {
projectName: this.projectName,
repositoryName: dbEncodeURIComponent(this.repositoryName),
reference: this.artifactDetails.digest,
tagName: tag.name,
};
return this.artifactService.deleteTag(deleteTagParams).pipe(
map(response => {
this.translateService
.get('BATCH.DELETED_SUCCESS')
.subscribe(res => {
operateChanges(operMessage, OperationState.success);
});
}),
catchError(error => {
const message = errorHandler(error);
this.translateService
.get(message)
.subscribe(res =>
operateChanges(operMessage, OperationState.failure, res)
);
return of(error);
})
);
}
existValid(name) {

View File

@ -1,90 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package contenttrust
import (
"net/http"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/lib"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/pkg/signature"
"github.com/goharbor/harbor/src/server/middleware"
"github.com/goharbor/harbor/src/server/middleware/util"
)
var (
// isArtifactSigned use the sign manager to check the signature, it could handle pull by tag or digtest
// if pull by digest, any tag of the artifact is signed, will return true.
isArtifactSigned = func(req *http.Request, art lib.ArtifactInfo) (bool, error) {
checker, err := signature.GetManager().GetCheckerByRepo(req.Context(), art.Repository)
if err != nil {
return false, err
}
if len(art.Tag) > 0 {
return checker.IsTagSigned(art.Tag, art.Digest), nil
}
return checker.IsArtifactSigned(art.Digest), nil
}
)
// Notary handle docker pull content trust check
func Notary() func(http.Handler) http.Handler {
return middleware.BeforeRequest(func(r *http.Request) error {
ctx := r.Context()
logger := log.G(ctx)
none := lib.ArtifactInfo{}
af := lib.GetArtifactInfo(ctx)
if af == none {
return errors.New("artifactinfo middleware required before this middleware").WithCode(errors.NotFoundCode)
}
pro, err := project.Ctl.GetByName(ctx, af.ProjectName)
if err != nil {
return err
}
if pro.ContentTrustEnabled() {
art, err := artifact.Ctl.GetByReference(ctx, af.Repository, af.Reference, nil)
if err != nil {
return err
}
if len(af.Digest) == 0 {
af.Digest = art.Digest
}
ok, err := util.SkipPolicyChecking(r, pro.ProjectID, art.ID)
if err != nil {
return err
}
if ok {
logger.Debugf("artifact %s@%s is pulling by the scanner/cosign, skip the checking", af.Repository, af.Digest)
return nil
}
match, err := isArtifactSigned(r, af)
if err != nil {
return err
}
if !match {
pkgE := errors.New(nil).WithCode(errors.PROJECTPOLICYVIOLATION).WithMessage("The image is not signed in Notary.")
return pkgE
}
}
return nil
})
}

View File

@ -1,232 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package contenttrust
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/suite"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/controller/artifact"
"github.com/goharbor/harbor/src/controller/artifact/processor/image"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/lib"
"github.com/goharbor/harbor/src/pkg/accessory"
accessorymodel "github.com/goharbor/harbor/src/pkg/accessory/model"
basemodel "github.com/goharbor/harbor/src/pkg/accessory/model/base"
proModels "github.com/goharbor/harbor/src/pkg/project/models"
securitytesting "github.com/goharbor/harbor/src/testing/common/security"
artifacttesting "github.com/goharbor/harbor/src/testing/controller/artifact"
projecttesting "github.com/goharbor/harbor/src/testing/controller/project"
"github.com/goharbor/harbor/src/testing/mock"
accessorytesting "github.com/goharbor/harbor/src/testing/pkg/accessory"
)
type MiddlewareTestSuite struct {
suite.Suite
originalArtifactController artifact.Controller
artifactController *artifacttesting.Controller
originalProjectController project.Controller
projectController *projecttesting.Controller
artifact *artifact.Artifact
project *proModels.Project
originalAccessMgr accessory.Manager
accessMgr *accessorytesting.Manager
isArtifactSigned func(req *http.Request, art lib.ArtifactInfo) (bool, error)
next http.Handler
}
func (suite *MiddlewareTestSuite) SetupTest() {
suite.originalArtifactController = artifact.Ctl
suite.artifactController = &artifacttesting.Controller{}
artifact.Ctl = suite.artifactController
suite.originalProjectController = project.Ctl
suite.projectController = &projecttesting.Controller{}
project.Ctl = suite.projectController
suite.originalAccessMgr = accessory.Mgr
suite.accessMgr = &accessorytesting.Manager{}
accessory.Mgr = suite.accessMgr
suite.isArtifactSigned = isArtifactSigned
suite.artifact = &artifact.Artifact{}
suite.artifact.Type = image.ArtifactTypeImage
suite.artifact.ProjectID = 1
suite.artifact.RepositoryName = "library/photon"
suite.artifact.Digest = "digest"
suite.project = &proModels.Project{
ProjectID: suite.artifact.ProjectID,
Name: "library",
Metadata: map[string]string{
proModels.ProMetaEnableContentTrust: "true",
},
}
suite.next = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
isArtifactSigned = func(req *http.Request, art lib.ArtifactInfo) (bool, error) {
return false, nil
}
}
func (suite *MiddlewareTestSuite) TearDownTest() {
artifact.Ctl = suite.originalArtifactController
project.Ctl = suite.originalProjectController
accessory.Mgr = suite.originalAccessMgr
}
func (suite *MiddlewareTestSuite) makeRequest() *http.Request {
req := httptest.NewRequest("GET", "/v1/library/photon/manifests/2.0", nil)
info := lib.ArtifactInfo{
Repository: "library/photon",
Reference: "2.0",
Tag: "2.0",
Digest: "",
}
return req.WithContext(lib.WithArtifactInfo(req.Context(), info))
}
func (suite *MiddlewareTestSuite) TestGetArtifactFailed() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(nil, fmt.Errorf("error"))
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
req := suite.makeRequest()
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusInternalServerError)
}
func (suite *MiddlewareTestSuite) TestGetProjectFailed() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(nil, fmt.Errorf("err"))
req := suite.makeRequest()
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusInternalServerError)
}
func (suite *MiddlewareTestSuite) TestContentTrustDisabled() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
suite.project.Metadata[proModels.ProMetaEnableContentTrust] = "false"
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
req := suite.makeRequest()
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusOK)
}
func (suite *MiddlewareTestSuite) TestNoneArtifact() {
req := httptest.NewRequest("GET", "/v1/library/photon/manifests/nonexist", nil)
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusNotFound)
}
func (suite *MiddlewareTestSuite) TestAuthenticatedUserPulling() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
mock.OnAnything(suite.accessMgr, "List").Return([]accessorymodel.Accessory{}, nil)
securityCtx := &securitytesting.Context{}
mock.OnAnything(securityCtx, "Name").Return("local")
mock.OnAnything(securityCtx, "Can").Return(true, nil)
mock.OnAnything(securityCtx, "IsAuthenticated").Return(true)
req := suite.makeRequest()
req = req.WithContext(security.NewContext(req.Context(), securityCtx))
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusPreconditionFailed)
}
func (suite *MiddlewareTestSuite) TestScannerPulling() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
mock.OnAnything(suite.accessMgr, "List").Return([]accessorymodel.Accessory{}, nil)
securityCtx := &securitytesting.Context{}
mock.OnAnything(securityCtx, "Name").Return("v2token")
mock.OnAnything(securityCtx, "Can").Return(true, nil)
mock.OnAnything(securityCtx, "IsAuthenticated").Return(true)
req := suite.makeRequest()
req = req.WithContext(security.NewContext(req.Context(), securityCtx))
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusOK)
}
// pull a public project a un-signed image when policy checker is enabled.
func (suite *MiddlewareTestSuite) TestUnAuthenticatedUserPulling() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
mock.OnAnything(suite.accessMgr, "List").Return([]accessorymodel.Accessory{}, nil)
securityCtx := &securitytesting.Context{}
mock.OnAnything(securityCtx, "Name").Return("local")
mock.OnAnything(securityCtx, "Can").Return(true, nil)
mock.OnAnything(securityCtx, "IsAuthenticated").Return(false)
req := suite.makeRequest()
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusPreconditionFailed)
}
// pull cosign signature when policy checker is enabled.
func (suite *MiddlewareTestSuite) TestSignaturePulling() {
mock.OnAnything(suite.artifactController, "GetByReference").Return(suite.artifact, nil)
mock.OnAnything(suite.projectController, "GetByName").Return(suite.project, nil)
acc := &basemodel.Default{
Data: accessorymodel.AccessoryData{
ID: 1,
ArtifactID: 2,
SubArtifactDigest: suite.artifact.Digest,
Type: accessorymodel.TypeCosignSignature,
},
}
mock.OnAnything(suite.accessMgr, "List").Return([]accessorymodel.Accessory{
acc,
}, nil)
req := suite.makeRequest()
rr := httptest.NewRecorder()
Notary()(suite.next).ServeHTTP(rr, req)
suite.Equal(rr.Code, http.StatusOK)
}
func TestMiddlewareTestSuite(t *testing.T) {
suite.Run(t, &MiddlewareTestSuite{})
}

View File

@ -54,7 +54,6 @@ func RegisterRoutes() {
Path("/*/manifests/:reference").
Middleware(metric.InjectOpIDMiddleware(metric.ManifestOperationID)).
Middleware(repoproxy.ManifestMiddleware()).
Middleware(contenttrust.Notary()).
Middleware(contenttrust.Cosign()).
Middleware(vulnerable.Middleware()).
HandlerFunc(getManifest)
@ -63,7 +62,6 @@ func RegisterRoutes() {
Path("/*/manifests/:reference").
Middleware(metric.InjectOpIDMiddleware(metric.ManifestOperationID)).
Middleware(repoproxy.ManifestMiddleware()).
Middleware(contenttrust.Notary()).
Middleware(contenttrust.Cosign()).
Middleware(vulnerable.Middleware()).
HandlerFunc(getManifest)

View File

@ -95,7 +95,7 @@ func (a *artifactAPI) ListArtifacts(ctx context.Context, params operation.ListAr
// set option
option := option(params.WithTag, params.WithImmutableStatus,
params.WithLabel, params.WithSignature, params.WithAccessory)
params.WithLabel, params.WithAccessory)
// get the total count of artifacts
total, err := a.artCtl.Count(ctx, query)
@ -129,7 +129,7 @@ func (a *artifactAPI) GetArtifact(ctx context.Context, params operation.GetArtif
}
// set option
option := option(params.WithTag, params.WithImmutableStatus,
params.WithLabel, params.WithSignature, params.WithAccessory)
params.WithLabel, params.WithAccessory)
// get the artifact
artifact, err := a.artCtl.GetByReference(ctx, fmt.Sprintf("%s/%s", params.ProjectName, params.RepositoryName), params.Reference, option)
@ -336,9 +336,6 @@ func (a *artifactAPI) ListTags(ctx context.Context, params operation.ListTagsPar
// set option
option := &tag.Option{}
if params.WithSignature != nil {
option.WithSignature = *params.WithSignature
}
if params.WithImmutableStatus != nil {
option.WithImmutableStatus = *params.WithImmutableStatus
}
@ -503,7 +500,7 @@ func (a *artifactAPI) RequireLabelInProject(ctx context.Context, projectID, labe
return nil
}
func option(withTag, withImmutableStatus, withLabel, withSignature, withAccessory *bool) *artifact.Option {
func option(withTag, withImmutableStatus, withLabel, withAccessory *bool) *artifact.Option {
option := &artifact.Option{
WithTag: true, // return the tag by default
WithLabel: lib.BoolValue(withLabel),
@ -521,7 +518,6 @@ func option(withTag, withImmutableStatus, withLabel, withSignature, withAccessor
if option.WithTag {
option.TagOption = &tag.Option{
WithImmutableStatus: lib.BoolValue(withImmutableStatus),
WithSignature: lib.BoolValue(withSignature),
}
}

View File

@ -36,7 +36,6 @@ func (t *Tag) ToSwagger() *models.Tag {
PushTime: strfmt.DateTime(t.PushTime),
RepositoryID: t.RepositoryID,
Immutable: t.Immutable,
Signed: t.Signed,
}
}

View File

@ -102,7 +102,6 @@ func (s *sysInfoAPI) convertInfo(d *si.Data) *models.GeneralInfo {
res.ProjectCreationRestriction = &d.Protected.ProjectCreationRestrict
res.ExternalURL = &d.Protected.ExtURL
res.RegistryURL = &d.Protected.RegistryURL
res.WithNotary = &d.Protected.WithNotary
res.ReadOnly = &d.Protected.ReadOnly
res.RegistryStorageProviderName = &d.Protected.RegistryStorageProviderName
res.NotificationEnable = &d.Protected.NotificationEnable

View File

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

View File

@ -1,127 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package ed25519 implements the Ed25519 signature algorithm. See
// http://ed25519.cr.yp.to/.
package ed25519
// This code is a port of the public domain, "ref10" implementation of ed25519
// from SUPERCOP.
import (
"crypto/sha512"
"crypto/subtle"
"io"
"github.com/agl/ed25519/edwards25519"
)
const (
PublicKeySize = 32
PrivateKeySize = 64
SignatureSize = 64
)
// GenerateKey generates a public/private key pair using randomness from rand.
func GenerateKey(rand io.Reader) (publicKey *[PublicKeySize]byte, privateKey *[PrivateKeySize]byte, err error) {
privateKey = new([64]byte)
publicKey = new([32]byte)
_, err = io.ReadFull(rand, privateKey[:32])
if err != nil {
return nil, nil, err
}
h := sha512.New()
h.Write(privateKey[:32])
digest := h.Sum(nil)
digest[0] &= 248
digest[31] &= 127
digest[31] |= 64
var A edwards25519.ExtendedGroupElement
var hBytes [32]byte
copy(hBytes[:], digest)
edwards25519.GeScalarMultBase(&A, &hBytes)
A.ToBytes(publicKey)
copy(privateKey[32:], publicKey[:])
return
}
// Sign signs the message with privateKey and returns a signature.
func Sign(privateKey *[PrivateKeySize]byte, message []byte) *[SignatureSize]byte {
h := sha512.New()
h.Write(privateKey[:32])
var digest1, messageDigest, hramDigest [64]byte
var expandedSecretKey [32]byte
h.Sum(digest1[:0])
copy(expandedSecretKey[:], digest1[:])
expandedSecretKey[0] &= 248
expandedSecretKey[31] &= 63
expandedSecretKey[31] |= 64
h.Reset()
h.Write(digest1[32:])
h.Write(message)
h.Sum(messageDigest[:0])
var messageDigestReduced [32]byte
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
var R edwards25519.ExtendedGroupElement
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
var encodedR [32]byte
R.ToBytes(&encodedR)
h.Reset()
h.Write(encodedR[:])
h.Write(privateKey[32:])
h.Write(message)
h.Sum(hramDigest[:0])
var hramDigestReduced [32]byte
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
var s [32]byte
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
signature := new([64]byte)
copy(signature[:], encodedR[:])
copy(signature[32:], s[:])
return signature
}
// Verify returns true iff sig is a valid signature of message by publicKey.
func Verify(publicKey *[PublicKeySize]byte, message []byte, sig *[SignatureSize]byte) bool {
if sig[63]&224 != 0 {
return false
}
var A edwards25519.ExtendedGroupElement
if !A.FromBytes(publicKey) {
return false
}
edwards25519.FeNeg(&A.X, &A.X)
edwards25519.FeNeg(&A.T, &A.T)
h := sha512.New()
h.Write(sig[:32])
h.Write(publicKey[:])
h.Write(message)
var digest [64]byte
h.Sum(digest[:0])
var hReduced [32]byte
edwards25519.ScReduce(&hReduced, &digest)
var R edwards25519.ProjectiveGroupElement
var b [32]byte
copy(b[:], sig[32:])
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &b)
var checkR [32]byte
R.ToBytes(&checkR)
return subtle.ConstantTimeCompare(sig[:32], checkR[:]) == 1
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,143 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package json
import (
"bytes"
"unicode/utf8"
)
const (
caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
kelvin = '\u212a'
smallLongEss = '\u017f'
)
// foldFunc returns one of four different case folding equivalence
// functions, from most general (and slow) to fastest:
//
// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
// 3) asciiEqualFold, no special, but includes non-letters (including _)
// 4) simpleLetterEqualFold, no specials, no non-letters.
//
// The letters S and K are special because they map to 3 runes, not just 2:
// * S maps to s and to U+017F 'ſ' Latin small letter long s
// * k maps to K and to U+212A '' Kelvin sign
// See https://play.golang.org/p/tTxjOc0OGo
//
// The returned function is specialized for matching against s and
// should only be given s. It's not curried for performance reasons.
func foldFunc(s []byte) func(s, t []byte) bool {
nonLetter := false
special := false // special letter
for _, b := range s {
if b >= utf8.RuneSelf {
return bytes.EqualFold
}
upper := b & caseMask
if upper < 'A' || upper > 'Z' {
nonLetter = true
} else if upper == 'K' || upper == 'S' {
// See above for why these letters are special.
special = true
}
}
if special {
return equalFoldRight
}
if nonLetter {
return asciiEqualFold
}
return simpleLetterEqualFold
}
// equalFoldRight is a specialization of bytes.EqualFold when s is
// known to be all ASCII (including punctuation), but contains an 's',
// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
// See comments on foldFunc.
func equalFoldRight(s, t []byte) bool {
for _, sb := range s {
if len(t) == 0 {
return false
}
tb := t[0]
if tb < utf8.RuneSelf {
if sb != tb {
sbUpper := sb & caseMask
if 'A' <= sbUpper && sbUpper <= 'Z' {
if sbUpper != tb&caseMask {
return false
}
} else {
return false
}
}
t = t[1:]
continue
}
// sb is ASCII and t is not. t must be either kelvin
// sign or long s; sb must be s, S, k, or K.
tr, size := utf8.DecodeRune(t)
switch sb {
case 's', 'S':
if tr != smallLongEss {
return false
}
case 'k', 'K':
if tr != kelvin {
return false
}
default:
return false
}
t = t[size:]
}
if len(t) > 0 {
return false
}
return true
}
// asciiEqualFold is a specialization of bytes.EqualFold for use when
// s is all ASCII (but may contain non-letters) and contains no
// special-folding letters.
// See comments on foldFunc.
func asciiEqualFold(s, t []byte) bool {
if len(s) != len(t) {
return false
}
for i, sb := range s {
tb := t[i]
if sb == tb {
continue
}
if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
if sb&caseMask != tb&caseMask {
return false
}
} else {
return false
}
}
return true
}
// simpleLetterEqualFold is a specialization of bytes.EqualFold for
// use when s is all ASCII letters (no underscores, etc) and also
// doesn't contain 'k', 'K', 's', or 'S'.
// See comments on foldFunc.
func simpleLetterEqualFold(s, t []byte) bool {
if len(s) != len(t) {
return false
}
for i, b := range s {
if b&caseMask != t[i]&caseMask {
return false
}
}
return true
}

View File

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

View File

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

View File

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

View File

@ -1,44 +0,0 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package json
import (
"strings"
)
// tagOptions is the string following a comma in a struct field's "json"
// tag, or the empty string. It does not include the leading comma.
type tagOptions string
// parseTag splits a struct field's json tag into its name and
// comma-separated options.
func parseTag(tag string) (string, tagOptions) {
if idx := strings.Index(tag, ","); idx != -1 {
return tag[:idx], tagOptions(tag[idx+1:])
}
return tag, tagOptions("")
}
// Contains reports whether a comma-separated list of options
// contains a particular substr flag. substr must be surrounded by a
// string boundary or commas.
func (o tagOptions) Contains(optionName string) bool {
if len(o) == 0 {
return false
}
s := string(o)
for s != "" {
var next string
i := strings.Index(s, ",")
if i >= 0 {
s, next = s[:i], s[i+1:]
}
if s == optionName {
return true
}
s = next
}
return false
}

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

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