From 61a2257854a12ee459e80dd8d2ef7a879e850dcc Mon Sep 17 00:00:00 2001 From: "wuhengyu.why" Date: Tue, 5 Aug 2025 17:45:22 +0800 Subject: [PATCH] refactor with kms3.0 sdk --- README-zh_CN.md | 31 +++-- README.md | 29 ++--- ci/ossutil/go.mod | 6 +- ci/ossutil/go.sum | 3 +- .../main.go | 4 +- go.mod | 17 +-- go.sum | 32 +++-- internal/sm/secret_manager.go | 69 ++++------ plugin/dkms.go | 106 ++++++++++++++++ plugin/kms.go | 89 +++++++++++++ .../plugin.go | 118 +++++++----------- types/types.go | 20 +++ 12 files changed, 343 insertions(+), 181 deletions(-) create mode 100644 plugin/dkms.go create mode 100644 plugin/kms.go rename {cmd/notation-alibabacloud-secret-manager => plugin}/plugin.go (69%) create mode 100644 types/types.go diff --git a/README-zh_CN.md b/README-zh_CN.md index 972362a..dd93301 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -13,13 +13,13 @@ #### 插件规范兼容性 -| Capability | Compatibility | -| ---------------- | ------------------------------------------------------------ | -| keySpec | `RSA-2048`, `RSA-3072`, `EC-256` | -| hashAlgorithm | `SHA-256` | -| signingAlgorithm | `RSASSA-PSS-SHA-256` | +| Capability | Compatibility | +| ---------------- | --------------------------------------------------- | +| keySpec | `RSA-2048`, `EC-256` | +| hashAlgorithm | `SHA-256` | +| signingAlgorithm | `RSASSA-PSS-SHA-256` | | pluginCapability | `SIGNATURE_GENERATOR.RAW`, `SIGNATURE_VERIFIER.TRUSTED_IDENTITY`, `SIGNATURE_VERIFIER.REVOCATION_CHECK` | -| signingScheme | `notary.x509` | +| signingScheme | `notary.x509` | @@ -29,20 +29,17 @@ 下面总结了配置 notation-alibabacloud-secret-manager 插件以及容器镜像签名和验签的步骤。 -- 安装Notation [CLI](https://github.com/notaryproject/notation/releases/tag/v1.1.1)。版本 v1.1.1 已通过测试。请注意,“make install ”会根据 MacOS 环境创建插件目录结构。请根据您的操作系统更新 Makefile。然后,它会根据符号插件目录结构规范将插件复制到适当的位置。 +- 安装Notation [CLI](https://github.com/notaryproject/notation/releases/tag/v1.3.2)。版本 v1.3.2 已通过测试。请注意,“make install ”会根据 MacOS 环境创建插件目录结构。请根据您的操作系统更新 Makefile。然后,它会根据符号插件目录结构规范将插件复制到适当的位置。 -- 本插件使用 [KMS Instance SDK](https://www.alibabacloud.com/help/en/kms/developer-reference/kms-instance-sdk-for-go/),您需要满足以下先决条件并自定义环境变量: +- 使用本插件您需要自定义以下环境变量: -| 环境变量 | 描述 | -| ------------------------------------ | ------------------------------------------------------------ | -| ALIBABA_CLOUD_ACCESS_KEY_ID | 阿里云账户Access Key ID | -| ALIBABA_CLOUD_ACCESS_KEY_SECRET | 阿里云账号Access Secret Key | -| ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT | 指定KMS专属实例的VPC Endpoint,比如:kst-hzxxxxxxxxxx.cryptoservice.kms.aliyuncs.com | -| ALIBABA_CLOUD_KMS_CLIENTKEY_FILEPATH | 访问指定KMS专属实例应用接入点(AAP)的ClientKey凭据文件对应的本地文件路径 | -| ALIBABA_CLOUD_KMS_PASSWORD | 指定KMS专属实例应用接入点(AAP)的密钥 | -| ALIBABA_CLOUD_KMS_CA_FILEPATH | 指定KMS专属实例CA证书对应的本地文件路径 | +| 环境变量 | 描述 | +| ----------------------------------- | ------------------------------------------------------------ | +| ALIBABA_CLOUD_ACCESS_KEY_ID | 阿里云账户Access Key ID | +| ALIBABA_CLOUD_ACCESS_KEY_SECRET | 阿里云账号Access Secret Key | +| ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT | 支持KMS专属实例Endpoint和共享网关Endpoint
专属实例Endpoint实例:kst-hzxxxxxxxxxx.cryptoservice.kms.aliyuncs.com
共享网关Endpoint实例:kms.cn-hangzhou.aliyuncs.com
关于专属网关访问和共享网关访问的更多差异,请参见[共享网关和专属网关的差异](https://www.alibabacloud.com/help/zh/kms/key-management-service/developer-reference/classic-kms-sdkclassic-kms-sdk/#d61514b089my8) | *注意:notation-alibabacloud-secret-manager插件支持多种Credential配置方式。更多的配置方式请参考[credentials](https://aliyuncontainerservice.github.io/ack-ram-tool/#credentials)* @@ -86,7 +83,7 @@ notation plugin add --file ./notation-alibabacloud.secretmanager.plugin 2. 在密钥管理页面,单击用户主密钥页签,实例ID选择软件密钥管理实例,单击创建密钥。 -3. 在创建密钥面板,完成配置项设置,注意这里的密钥规格需要选择**非对称密钥**,密钥用途选择**SIGN/VERIFY**,密钥规则选择上文插件规范兼容性里支持的密钥规格(`RSA-2048`, `RSA-3072`, `EC-256`),然后单击确定。 +3. 在创建密钥面板,完成配置项设置,注意这里的密钥规格需要选择**非对称密钥**,密钥用途选择**SIGN/VERIFY**,密钥规则选择上文插件规范兼容性里支持的密钥规格(`RSA-2048`,`EC-256`),然后单击确定。 diff --git a/README.md b/README.md index 8e70e6f..ece8125 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,13 @@ This document demonstrates how to sign and verify an OCI artifact with Alibaba C #### Plugin Spec Compatibility -| Capability | Compatibility | -| ---------------- | ------------------------------------------------------------ | -| keySpec | `RSA-2048`, `RSA-3072`, `EC-256` | -| hashAlgorithm | `SHA-256` | -| signingAlgorithm | `RSASSA-PSS-SHA-256` | +| Capability | Compatibility | +| ---------------- | ---------------------------------------------------------- | +| keySpec | `RSA-2048`, `EC-256` | +| hashAlgorithm | `SHA-256` | +| signingAlgorithm | `RSASSA-PSS-SHA-256` | | pluginCapability | `SIGNATURE_GENERATOR.RAW`, `SIGNATURE_VERIFIER.TRUSTED_IDENTITY`, `SIGNATURE_VERIFIER.REVOCATION_CHECK` | -| signingScheme | `notary.x509` | +| signingScheme | `notary.x509` | @@ -31,16 +31,13 @@ The following summarizes the steps to configure the notation-alibabacloud-secret - Install notation [CLI](https://github.com/notaryproject/notation/releases/tag/v1.1.1). Version v1.1.1 has been tested. Note that `make install` creates the plugin directory structure based on a MacOS environment. Update the Makefile based on your OS. It then copies the plugin to the appropriate location based on the notation plugin directory structure spec. -- This plugin leverages the [KMS Instance SDK](https://www.alibabacloud.com/help/en/kms/developer-reference/kms-instance-sdk-for-go/), which means you'll need to meet the pre-requisites and customize the environment as follows: +- To use this plugin, you need to define the following environment variables: -| Env | Description | -| ------------------------------------ | ------------------------------------------------------------ | -| ALIBABA_CLOUD_ACCESS_KEY_ID | Alibaba Cloud Account Access Key ID | -| ALIBABA_CLOUD_ACCESS_KEY_SECRET | Alibaba Cloud Account Secret Access Key | -| ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT | VPC Endpoint of the Dedicated KMS Instance, for example, kst-hzxxxxxxxxxx.cryptoservice.kms.aliyuncs.com | -| ALIBABA_CLOUD_KMS_CLIENTKEY_FILEPATH | Local File Path of the ClientKey Credential for the Dedicated KMS Instance Application Access Point (AAP) | -| ALIBABA_CLOUD_KMS_PASSWORD | Password for the Dedicated KMS Instance Application Access Point (AAP) | -| ALIBABA_CLOUD_KMS_CA_FILEPATH | Local Path of the CA Certificate for the Dedicated KMS Instance | +| Env | Description | +| ----------------------------------- | ------------------------------------------------------------ | +| ALIBABA_CLOUD_ACCESS_KEY_ID | Alibaba Cloud Account Access Key ID | +| ALIBABA_CLOUD_ACCESS_KEY_SECRET | Alibaba Cloud Account Secret Access Key | +| ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT | Supports both KMS dedicated instance Endpoint and shared gateway Endpoint.
**Dedicated instance Endpoint example**: kst-hzxxxxxxxxxx.cryptoservice.kms.aliyuncs.com
**Shared gateway Endpoint example**: kms.cn-hangzhou.aliyuncs.com
For more information about the differences between accessing via a dedicated gateway and a shared gateway, please refer to [**Differences between shared and dedicated gateways for accessing KMS**](https://www.alibabacloud.com/help/en/kms/key-management-service/developer-reference/classic-kms-sdkclassic-kms-sdk/#26484656d84ey) | *Note: the notation-alibabacloud-secret-manager plugin supports various Credential configuration methods. For more details, please refer to [credentials](https://aliyuncontainerservice.github.io/ack-ram-tool/#credentials)* @@ -79,7 +76,7 @@ Users can [create a key](https://help.aliyun.com/en/kms/key-management-service/u 2. On the **Keys** page, click the **Default Key** tab. -3. In the Create Keys panel, complete the configuration settings, noting that you need to select **Asymmetric Keys** for Key Type, **SIGN/VERIFY** for Key Usage, and select the key specifications supported by Plugin Spec Compatibility above (`RSA-2048`, `RSA-3072`, `EC-256`), and then click OK. +3. In the Create Keys panel, complete the configuration settings, noting that you need to select **Asymmetric Keys** for Key Type, **SIGN/VERIFY** for Key Usage, and select the key specifications supported by Plugin Spec Compatibility above (`RSA-2048`, `EC-256`), and then click OK. diff --git a/ci/ossutil/go.mod b/ci/ossutil/go.mod index 50c77c7..b7519a1 100644 --- a/ci/ossutil/go.mod +++ b/ci/ossutil/go.mod @@ -1,6 +1,8 @@ module github.com/AliyunContainerService/ack-ram-tool/ci/ossutil -go 1.19 +go 1.23.0 + +toolchain go1.24.0 require ( github.com/alibabacloud-go/tea v1.2.0 @@ -13,7 +15,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - golang.org/x/net v0.9.0 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/time v0.3.0 // indirect gopkg.in/ini.v1 v1.56.0 // indirect ) diff --git a/ci/ossutil/go.sum b/ci/ossutil/go.sum index 3bcb15a..8fddeb7 100644 --- a/ci/ossutil/go.sum +++ b/ci/ossutil/go.sum @@ -50,8 +50,9 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/cmd/notation-alibabacloud-secret-manager/main.go b/cmd/notation-alibabacloud-secret-manager/main.go index a27ce4c..347e2b8 100644 --- a/cmd/notation-alibabacloud-secret-manager/main.go +++ b/cmd/notation-alibabacloud-secret-manager/main.go @@ -19,12 +19,14 @@ import ( "os" "github.com/notaryproject/notation-plugin-framework-go/cli" + + notationplugin "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/plugin" ) func main() { ctx := context.Background() // Initialize plugin - plugin, err := NewAlibabaCloudSecretManagerPlugin() + plugin, err := notationplugin.NewAlibabaCloudSecretManagerPlugin() if err != nil { _, _ = fmt.Fprintf(os.Stderr, "failed to initialize plugin: %v\n", err) os.Exit(2) diff --git a/go.mod b/go.mod index 5fbb49d..5ce1412 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/AliyunContainerService/notation-alibabacloud-secret-manager -go 1.21 +go 1.23.0 + +toolchain go1.24.0 require ( github.com/AliyunContainerService/ack-ram-tool v0.18.1 @@ -65,14 +67,13 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.10.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect golang.org/x/time v0.3.0 // indirect - google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 583d8ed..4b1b5ea 100644 --- a/go.sum +++ b/go.sum @@ -114,7 +114,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -249,8 +248,8 @@ golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -264,7 +263,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -280,11 +278,11 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= -golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -313,8 +311,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -324,8 +322,8 @@ golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/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= @@ -336,8 +334,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -352,16 +350,14 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/internal/sm/secret_manager.go b/internal/sm/secret_manager.go index ea38258..0bae7a8 100644 --- a/internal/sm/secret_manager.go +++ b/internal/sm/secret_manager.go @@ -9,6 +9,7 @@ import ( "encoding/pem" "errors" "fmt" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/types" "io" "math/big" "os" @@ -36,28 +37,30 @@ const ( ) type KmsPrivateKeySigner struct { - client *dedicatedkmssdk.Client - publicKey crypto.PublicKey - keyId string - algorithm string + client types.ClientProvider + publicKey crypto.PublicKey + keyId string + keyVersionId string + algorithm string } func (ks *KmsPrivateKeySigner) Public() crypto.PublicKey { return ks.publicKey } -func (ks *KmsPrivateKeySigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { - request := &dedicatedkmssdk.SignRequest{ - KeyId: tea.String(ks.keyId), - Message: digest, - MessageType: tea.String("DIGEST"), - Algorithm: tea.String(ks.algorithm), +func (ks *KmsPrivateKeySigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) { + request := &types.SignRequest{ + KeyId: ks.keyId, + Payload: digest, + KeyVersionId: ks.keyVersionId, + MessageType: "DIGEST", + Algorithm: ks.algorithm, } - resp, err := ks.client.Sign(request) + sig, err := ks.client.GenerateSignature(request) if err != nil { return nil, err } - return resp.Signature, nil + return sig, nil } func genSerialNum() (*big.Int, error) { @@ -69,7 +72,7 @@ func genSerialNum() (*big.Int, error) { return serialNum, nil } -func GetCertDataFromKey(dkmsClient *dedicatedkmssdk.Client, pub *rsa.PublicKey, keyId string) ([]byte, error) { +func GetCertDataFromKey(clientProvider types.ClientProvider, pub *rsa.PublicKey, keyId, keyVersionId string) ([]byte, error) { //init csr subject subject := pkix.Name{ Country: []string{"CN"}, @@ -80,10 +83,11 @@ func GetCertDataFromKey(dkmsClient *dedicatedkmssdk.Client, pub *rsa.PublicKey, //Create kms service signer object priv := &KmsPrivateKeySigner{ - client: dkmsClient, //kms client - keyId: keyId, //kms instance asymmetric key Id - publicKey: pub, //kms instance asymmetric public key - algorithm: KMS_ALG_RSA_PSS_SHA_256, //kms instance signing algorithm, RSA_PKCS1_SHA_256 is not conform with notation specification + client: clientProvider, //kms client + keyId: keyId, //kms instance asymmetric key Id + keyVersionId: keyVersionId, + publicKey: pub, //kms instance asymmetric public key + algorithm: KMS_ALG_RSA_PSS_SHA_256, //kms instance signing algorithm, RSA_PKCS1_SHA_256 is not conform with notation specification } serialNum, err := genSerialNum() @@ -91,13 +95,13 @@ func GetCertDataFromKey(dkmsClient *dedicatedkmssdk.Client, pub *rsa.PublicKey, log.Logger.Errorf("Failed to generate serail number, err %v", err) return nil, err } - + notBefore := time.Now().Add(-1 * time.Minute) // Create a new certificate template template := x509.Certificate{ SerialNumber: serialNum, Subject: subject, - NotBefore: time.Now(), - NotAfter: time.Now().Add(365 * 24 * time.Hour), // Valid for 1 year + NotBefore: notBefore, + NotAfter: notBefore.Add(365 * 24 * time.Hour), // Valid for 1 year IsCA: false, KeyUsage: x509.KeyUsageDigitalSignature, SignatureAlgorithm: x509.SHA256WithRSAPSS, //only support RSA_PSS_SHA_256 here @@ -112,31 +116,6 @@ func GetCertDataFromKey(dkmsClient *dedicatedkmssdk.Client, pub *rsa.PublicKey, return certBytes, nil } -func GetPublicKey(client *dedicatedkmssdk.Client, keyId string) (*rsa.PublicKey, error) { - request := &dedicatedkmssdk.GetPublicKeyRequest{ - KeyId: tea.String(keyId), - } - response, err := client.GetPublicKey(request) - if err != nil { - return nil, err - } - block, _ := pem.Decode([]byte(*response.PublicKey)) - if block == nil || block.Type != "PUBLIC KEY" { - return nil, errors.New("failed to decode public key") - } - pub, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return nil, err - } - //return rsa public key - rsaPub, ok := pub.(*rsa.PublicKey) - if !ok { - return nil, errors.New(fmt.Sprintf("unsupport public key type %T", pub)) - } - - return rsaPub, nil -} - // CertDataOutput perisist certificate data to file func CertDataOutput(certData []byte, dir string) error { if len(dir) == 0 { diff --git a/plugin/dkms.go b/plugin/dkms.go new file mode 100644 index 0000000..d202b1e --- /dev/null +++ b/plugin/dkms.go @@ -0,0 +1,106 @@ +package plugin + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/sm" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/types" + openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" + kms "github.com/alibabacloud-go/kms-20160120/v3/client" + "github.com/alibabacloud-go/tea/tea" + dedicatedkmsopenapiutil "github.com/aliyun/alibabacloud-dkms-gcs-go-sdk/openapi-util" + dkms "github.com/aliyun/alibabacloud-dkms-gcs-go-sdk/sdk" + "os" +) + +type DKMSClientImpl struct { + client *dkms.Client + kmsClient *kms.Client +} + +func NewDKMSClientImpl(clientKey, kmsPassword, instanceEndpoint string, config openapi.Config) (*DKMSClientImpl, error) { + dkmsClient, err := sm.GetDkmsClientByClientKeyFile(clientKey, kmsPassword, instanceEndpoint) + if err != nil { + return nil, err + } + kmsClient, err := kms.NewClient(&config) + if err != nil { + return nil, err + } + return &DKMSClientImpl{ + client: dkmsClient, + kmsClient: kmsClient, + }, nil +} + +func (d *DKMSClientImpl) GenerateSignature(req *types.SignRequest) ([]byte, error) { + signRequest := &dkms.SignRequest{ + KeyId: tea.String(req.KeyId), + Message: req.Payload, + MessageType: tea.String(req.MessageType), + Algorithm: tea.String(req.Algorithm), + } + runtimeOptions := &dedicatedkmsopenapiutil.RuntimeOptions{ + IgnoreSSL: tea.Bool(true), + } + + //set instance ca from file + caFilePath := sm.GetKMSCAFile() + if caFilePath != "" { + certPEMBlock, err := os.ReadFile(caFilePath) + if err != nil { + return nil, err + } + certDERBlock, _ := pem.Decode(certPEMBlock) + if certDERBlock == nil { + return nil, fmt.Errorf("cert is nil") + } + cert, err := x509.ParseCertificate(certDERBlock.Bytes) + if err != nil { + return nil, fmt.Errorf("failed to parse certificate %s, err: %v", caFilePath, err) + } + if !cert.IsCA { + return nil, fmt.Errorf("the provided certificate is not a CA certificate") + } + runtimeOptions = &dedicatedkmsopenapiutil.RuntimeOptions{ + Verify: tea.String(string(certPEMBlock)), + } + } + sigResp, err := d.client.SignWithOptions(signRequest, runtimeOptions) + if err != nil { + return nil, fmt.Errorf("failed to sign payload %v", err) + } + return sigResp.Signature, nil +} + +func (d *DKMSClientImpl) GetPublicKey(keyId, keyVersionId string) (*rsa.PublicKey, error) { + request := &dkms.GetPublicKeyRequest{ + KeyId: tea.String(keyId), + } + response, err := d.client.GetPublicKey(request) + if err != nil { + return nil, err + } + block, _ := pem.Decode([]byte(*response.PublicKey)) + if block == nil || block.Type != "PUBLIC KEY" { + return nil, errors.New("failed to decode public key") + } + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + //return rsa public key + rsaPub, ok := pub.(*rsa.PublicKey) + if !ok { + return nil, errors.New(fmt.Sprintf("unsupport public key type %T", pub)) + } + + return rsaPub, nil +} + +func (d *DKMSClientImpl) GetKMSClient() *kms.Client { + return d.kmsClient +} diff --git a/plugin/kms.go b/plugin/kms.go new file mode 100644 index 0000000..18d60ef --- /dev/null +++ b/plugin/kms.go @@ -0,0 +1,89 @@ +package plugin + +import ( + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/base64" + "encoding/pem" + "errors" + "fmt" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/log" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/types" + openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" + kms "github.com/alibabacloud-go/kms-20160120/v3/client" + "github.com/alibabacloud-go/tea/tea" +) + +type KMSClientImpl struct { + client *kms.Client +} + +func NewKMSClientImpl(config openapi.Config) (*KMSClientImpl, error) { + kmsClient, err := kms.NewClient(&config) + if err != nil { + return nil, err + } + return &KMSClientImpl{ + client: kmsClient, + }, nil +} + +func (k *KMSClientImpl) GenerateSignature(req *types.SignRequest) ([]byte, error) { + var hashContent = req.Payload + if req.MessageType != "DIGEST" { + hash := sha256.New() + hash.Write(req.Payload) + hashContent = hash.Sum(nil) + } + base64EncodeHash := base64.StdEncoding.EncodeToString(hashContent) + resp, err := k.client.AsymmetricSign(&kms.AsymmetricSignRequest{ + Algorithm: tea.String(req.Algorithm), + Digest: tea.String(base64EncodeHash), + KeyId: tea.String(req.KeyId), + KeyVersionId: tea.String(req.KeyVersionId), + }) + if err != nil { + return nil, fmt.Errorf("failed to sign payload %v", err) + } + if resp.Body == nil || resp.Body.Value == nil { + return nil, fmt.Errorf("failed to sign with key %s, resp body is nil", req.KeyId) + } + decodeSig, err := base64.StdEncoding.DecodeString(tea.StringValue(resp.Body.Value)) + if err != nil { + return nil, fmt.Errorf("failed to decode signature %v", err) + } + return decodeSig, nil +} + +func (k *KMSClientImpl) GetPublicKey(keyId, keyVersionId string) (*rsa.PublicKey, error) { + resp, err := k.client.GetPublicKey(&kms.GetPublicKeyRequest{ + KeyId: tea.String(keyId), + KeyVersionId: tea.String(keyVersionId), + }) + if err != nil { + return nil, fmt.Errorf("failed to get public key %v", err) + } + if resp == nil || resp.Body == nil || resp.Body.PublicKey == nil { + return nil, fmt.Errorf("failed to get public key") + } + block, _ := pem.Decode([]byte(*resp.Body.PublicKey)) + if block == nil || block.Type != "PUBLIC KEY" { + return nil, errors.New("failed to decode public key") + } + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + //return rsa public key + rsaPub, ok := pub.(*rsa.PublicKey) + if !ok { + return nil, errors.New(fmt.Sprintf("unsupport public key type %T", pub)) + } + log.Logger.Infof("rsapub is %v", rsaPub.Size()) + return rsaPub, nil +} + +func (k *KMSClientImpl) GetKMSClient() *kms.Client { + return k.client +} diff --git a/cmd/notation-alibabacloud-secret-manager/plugin.go b/plugin/plugin.go similarity index 69% rename from cmd/notation-alibabacloud-secret-manager/plugin.go rename to plugin/plugin.go index a9a45ef..1f3d1b4 100644 --- a/cmd/notation-alibabacloud-secret-manager/plugin.go +++ b/plugin/plugin.go @@ -11,70 +11,73 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +package plugin import ( "context" "crypto/x509" - "encoding/pem" "errors" "fmt" "os" + "strings" + + openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" + kms "github.com/alibabacloud-go/kms-20160120/v3/client" + "github.com/alibabacloud-go/tea/tea" + "github.com/notaryproject/notation-plugin-framework-go/plugin" "github.com/AliyunContainerService/ack-ram-tool/pkg/ctl/common" "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/crypto" "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/log" "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/sm" "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/internal/version" - openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" - kms "github.com/alibabacloud-go/kms-20160120/v3/client" - "github.com/alibabacloud-go/tea/tea" - dedicatedkmsopenapiutil "github.com/aliyun/alibabacloud-dkms-gcs-go-sdk/openapi-util" - dkms "github.com/aliyun/alibabacloud-dkms-gcs-go-sdk/sdk" - "github.com/notaryproject/notation-plugin-framework-go/plugin" + "github.com/AliyunContainerService/notation-alibabacloud-secret-manager/types" ) const ( PluginName = "notation" CaCerts = "ca_certs" CertOutputDir = "output_cert_dir" + KeyVersionId = "key_version_id" + suffix = "cryptoservice.kms.aliyuncs.com" ) type AlibabaCloudSecretManagerPlugin struct { - DedicatedClient *dkms.Client - KmsClient *kms.Client + clientProvider types.ClientProvider } func NewAlibabaCloudSecretManagerPlugin() (*AlibabaCloudSecretManagerPlugin, error) { + var clientProvider types.ClientProvider + var err error client := common.GetClientOrDie() config := openapi.Config{ RegionId: tea.String(sm.GetKMSRegionId()), Credential: client.Credential(), } - kmsClient, err := kms.NewClient(&config) - if err != nil { - return nil, err - } instanceEndpoint := sm.GetInstanceEndpoint() if instanceEndpoint == "" { - return nil, errors.New("Env ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT MUST be set for kms instance endpoint") + return nil, errors.New("env ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT MUST be set for kms instance endpoint") } clientKey := sm.GetClientKey() - if instanceEndpoint == "" { - return nil, errors.New("Env ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT MUST be set for kms instance endpoint") - } kmsPassword := sm.GetKMSPassword() - if instanceEndpoint == "" { - return nil, errors.New("Env ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT MUST be set for kms instance endpoint") - } - //init DKMS Client - dkmsClient, err := sm.GetDkmsClientByClientKeyFile(clientKey, kmsPassword, instanceEndpoint) - if err != nil { - return nil, err + if clientKey != "" && kmsPassword != "" { + clientProvider, err = NewDKMSClientImpl(clientKey, kmsPassword, instanceEndpoint, config) + if err != nil { + return nil, fmt.Errorf("new dkms client failed: %v", err) + } + } else { + if strings.Contains(instanceEndpoint, suffix) { + config.Ca = tea.String(sm.GetKMSCAFile()) + } + config.Endpoint = tea.String(instanceEndpoint) + clientProvider, err = NewKMSClientImpl(config) + if err != nil { + return nil, fmt.Errorf("new kms client failed: %v", err) + } } + return &AlibabaCloudSecretManagerPlugin{ - dkmsClient, - kmsClient, + clientProvider: clientProvider, }, nil } @@ -83,13 +86,15 @@ func (p *AlibabaCloudSecretManagerPlugin) DescribeKey(_ context.Context, req *pl KeyId: tea.String(req.KeyID), } keyResult := &kms.DescribeKeyResponse{} - response, err := p.KmsClient.DescribeKey(request) + response, err := p.clientProvider.GetKMSClient().DescribeKey(request) if err != nil { return nil, err } keyResult = response smKeySpec := keyResult.Body.KeyMetadata.KeySpec - fmt.Printf("alibaba cloud secret manager key spec is %s\n", smKeySpec) + if keyResult.Body == nil || keyResult.Body.KeyMetadata == nil || keyResult.Body.KeyMetadata.KeySpec == nil { + return nil, errors.New("failed to describe key") + } keySpec, err := sm.SwitchKeySpec(tea.StringValue(smKeySpec)) if err != nil { return nil, err @@ -100,51 +105,19 @@ func (p *AlibabaCloudSecretManagerPlugin) DescribeKey(_ context.Context, req *pl }, nil } -func (p *AlibabaCloudSecretManagerPlugin) GenerateSignature(_ context.Context, req *plugin.GenerateSignatureRequest) (*plugin.GenerateSignatureResponse, error) { - messageType := "RAW" - signRequest := &dkms.SignRequest{ - KeyId: tea.String(req.KeyID), - Message: req.Payload, - MessageType: tea.String(messageType), - } - runtimeOptions := &dedicatedkmsopenapiutil.RuntimeOptions{ - IgnoreSSL: tea.Bool(true), - } - +func (p *AlibabaCloudSecretManagerPlugin) GenerateSignature(ctx context.Context, req *plugin.GenerateSignatureRequest) (*plugin.GenerateSignatureResponse, error) { rawCertChain := make([][]byte, 0) - //set instance ca from file - caFilePath := sm.GetKMSCAFile() - if caFilePath != "" { - certPEMBlock, err := os.ReadFile(caFilePath) - if err != nil { - log.Logger.Errorf("Failed to read certificate file from %s, err %v", caFilePath, err) - return nil, err - } - certDERBlock, _ := pem.Decode(certPEMBlock) - if certDERBlock == nil { - log.Logger.Errorf("Failed to decode PEM block from file %s", caFilePath) - return nil, err - } - cert, err := x509.ParseCertificate(certDERBlock.Bytes) - if err != nil { - log.Logger.Errorf("Failed to parse certificate %s, err: %v", caFilePath, err) - return nil, err - } - if !cert.IsCA { - log.Logger.Errorf("The provided certificate is not a CA certificate") - return nil, err - } - runtimeOptions = &dedicatedkmsopenapiutil.RuntimeOptions{ - Verify: tea.String(string(certPEMBlock)), - } - } - - signResponse, err := p.DedicatedClient.SignWithOptions(signRequest, runtimeOptions) + signature, err := p.clientProvider.GenerateSignature(&types.SignRequest{ + KeyId: req.KeyID, + KeyVersionId: req.PluginConfig[KeyVersionId], + MessageType: "RAW", + Payload: req.Payload, + Algorithm: "RSA_PSS_SHA_256", + }) if err != nil { log.Logger.Errorf("Failed to sign with key %s, err %v", req.KeyID, err) return nil, err } - log.Logger.Infof("sign response is %s", signResponse.String()) var certChain []*x509.Certificate if caCertsPath, ok := req.PluginConfig[CaCerts]; ok { //for imported key @@ -164,13 +137,13 @@ func (p *AlibabaCloudSecretManagerPlugin) GenerateSignature(_ context.Context, r } } else { //for kms self generated key - pub, err := sm.GetPublicKey(p.DedicatedClient, req.KeyID) + pub, err := p.clientProvider.GetPublicKey(req.KeyID, req.PluginConfig[KeyVersionId]) if err != nil { log.Logger.Errorf("Failed to get the public key from the given kms key %s, err %v", req.KeyID, err) return nil, err } //get cert data based on the given key id - certData, err := sm.GetCertDataFromKey(p.DedicatedClient, pub, req.KeyID) + certData, err := sm.GetCertDataFromKey(p.clientProvider, pub, req.KeyID, req.PluginConfig[KeyVersionId]) if err != nil { log.Logger.Errorf("Failed to parse ca_certs from %s, err %v", caCertsPath, err) return nil, err @@ -183,10 +156,9 @@ func (p *AlibabaCloudSecretManagerPlugin) GenerateSignature(_ context.Context, r rawCertChain = append(rawCertChain, certData) } - return &plugin.GenerateSignatureResponse{ KeyID: req.KeyID, - Signature: signResponse.Signature, + Signature: signature, SigningAlgorithm: plugin.SignatureAlgorithmRSASSA_PSS_SHA256, CertificateChain: rawCertChain, }, nil diff --git a/types/types.go b/types/types.go new file mode 100644 index 0000000..67e0279 --- /dev/null +++ b/types/types.go @@ -0,0 +1,20 @@ +package types + +import ( + "crypto/rsa" + kms "github.com/alibabacloud-go/kms-20160120/v3/client" +) + +type ClientProvider interface { + GenerateSignature(req *SignRequest) ([]byte, error) + GetPublicKey(keyId, keyVersionId string) (*rsa.PublicKey, error) + GetKMSClient() *kms.Client +} + +type SignRequest struct { + KeyId string + KeyVersionId string + MessageType string + Payload []byte + Algorithm string +}