diff --git a/.gitignore b/.gitignore index f02a524..c0b16a4 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ hs_err_pid* replay_pid* /.idea/ logs +/r-facade/target/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a8cfefc..3143d0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,19 +2,18 @@ ## Branch Strategy -We recommend that developers following the rules [here](https://jeffkreeftmeijer.com/git-flow/git-flow.png). +We recommend that developers following the `Trunk-based development` rules [here](https://trunkbaseddevelopment.com/). -- Branch `main` with stable code and tags on it. -- Branch `develop` for "next release" development. +- Trunk branch `main` with stable code. - Feature branches start with prefix `feat/` - Release branches start with prefix `release/` -- Hotfix branches start with prefix `hotfix/` +- Hotfix branches start with prefix `hotfix/` or `fix/` ## Contributing - Fork the repository or create branches. - Checkout your branch like a feature or bugfix. -- Make a pull request to the `develop` branch of this repository. +- Make a pull request to the `main` branch of this repository. - Wait for review and PR merged. --- diff --git a/README.md b/README.md index 7b88a7a..711f470 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ AntChain Bridge Relayer将功能实现分为两部分,分别为通信和可信 **确保安装了AntChain Bridge Plugin SDK,详情请[见](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK?tab=readme-ov-file#%E6%9E%84%E5%BB%BA)* +> [!IMPORTANT] +> +> 注意当前Relayer要求SDK版本为0.3.0 + ### 编译 在项目根目录运行maven命令即可: @@ -80,7 +84,7 @@ wget -qO- https://get.docker.com/ | bash 然后下载MySQL镜像并启动容器,注意这里指定了时区为`+08:00`,请修改为您的时区。 ``` -docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD='YOUR_PWD' mysql --default-authentication-plugin=mysql_native_password --default_time_zone +08:00 +docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD='YOUR_PWD' mysql:8 --mysql-native-password=ON --default_time_zone +08:00 ``` 然后下载Redis镜像并启动容器: @@ -333,7 +337,37 @@ relayer: {"destDomain":{"domain":"domain.web3.net","domainSpace":false},"destRelayer":{"netAddressList":["https://localhost:8082"],"relayerCert":{"credentialSubject":"AADVAAAAAAAD...hNDRjY2UifV19","credentialSubjectInstance":{"applicant":{"rawId":"ZGlkOmJpZDplZmJ...1b1FHWDZMVUd3Zw==","type":"BID"},"name":"relay","rawSubjectPublicKey":"r2Ze5VBjX...yWnSkTM4=","subject":"eyJwdWJsaWNLZXkiO...jZSJ9XX0=","subjectInfo":"eyJwd...J9XX0=","subjectPublicKey":{"algorithm":"Ed25519","encoded":"MCowBQYDK2V...qJKDyWnSkTM4=","format":"X.509","pointEncoding":"r2Ze5V...ifV19","expirationDate":1733811853,"id":"did:bid:efGeAv4Jr7V2FSyun77m4xTFmTDfG8nh","issuanceDate":1702275853,"issuer":{"rawId":"ZGlkOmJpZDpl...NTdtRENwQw==","type":"BID"},"proof":{"certHash":"Gaw4gcwXzn2i...K6HaPWBxXM=","hashAlgo":"SM3","rawProof":"kMZ/tvT19Tk...TQ4IVYlXkYjSBw==","sigAlgo":"Ed25519"},"type":"RELAYER_CERTIFICATE","version":"1"},"relayerCertId":"did:bid:efGeAv4Jr7V2FSyun77m4xTFmTDfG8nh"}} ``` - + +### 启动Embedded BCDNS + +> [!IMPORTANT] +> Relayer从0.3.0版本开始支持启动内嵌的BCDNS服务,注意Relayer使用的Embedded BCDNS相关依赖的版本。 + +Embedded BCDNS是内嵌在服务内部的BCDNS,提供中心化的权威服务,会使用一把私钥为跨链网络提供认证、准入等功能,按照服务端要求可以通过简单配置接入BCDNS,具体内容可以参考[这里](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/README.md)。 + +通过在中继的配置增加下面一项,重启即可启动Embedded BCDNS,详细的配置可以参考AntChain Bridge SDK关于如何使用Embedded的[README](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/README.md)。 + +```yaml +acb: + bcdns: + embedded: + server-on: true + root-private-key-file: file:/path/to/embedded-bcdns-root-private-key.key + root-cert-file: file:/path/to/embedded-bcdns-root.crt +``` + +上面配置中的`root-private-key-file`和`root-cert-file`,可以通过CLI命令`generate-bcdns-root-cert`来生成,详细用法参考[这里](r-cli/README.md#5.5 生成BCDNS根证书)。 + +需要在DB额外创建一些Embedded BCDNS的表,通过这里的SQL[脚本](https://github.com/AntChainOpenLabs/AntChainBridgePluginSDK/tree/main/bcdns-services/embedded-bcdns/embedded-bcdns-state-jdbc-spring-boot-starter/src/main/resources/ddl/mysql/ddl.sql) + +重新启动Relayer,启动日志中会看到: + +``` +INFO 63164 --- [ main] .EmbeddedBcdnsJdbcStateAutoConfiguration : start jdbc bcdns state +INFO 63164 --- [ main] b.b.e.s.a.EmbeddedBcdnsAutoConfiguration : start embedded bcdns server on 0.0.0.0:8090 +``` + + ## 社区治理 diff --git a/pom.xml b/pom.xml index 5efba75..685ebfe 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 pom r-bootstrap @@ -36,7 +36,8 @@ 3.23.5 2.7.16 8.0.33 - 0.2.3 + 0.3.0 + 0.1.0 5.8.22 4.13.2 2.2.224 @@ -116,9 +117,19 @@ com.alipay.antchain.bridge - antchain-bridge-bcdns + antchain-bridge-bcdns-factory ${acb-sdk.version} + + com.alipay.antchain.bridge + embedded-bcdns-state-jdbc-spring-boot-starter + ${acb-embedded-bcdns.version} + + + com.alipay.antchain.bridge + embedded-bcdns-spring-boot-starter + ${acb-embedded-bcdns.version} + junit junit @@ -198,7 +209,7 @@ com.alipay.antchain.bridge r-facade - ${project.version} + 0.2.0 org.projectlombok diff --git a/r-bootstrap/pom.xml b/r-bootstrap/pom.xml index eb9302f..2eedbe1 100644 --- a/r-bootstrap/pom.xml +++ b/r-bootstrap/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-bootstrap @@ -52,7 +52,7 @@ com.h2database h2 - test + com.baomidou @@ -86,6 +86,14 @@ com.github.ulisesbocchio jasypt-spring-boot-starter + + com.alipay.antchain.bridge + embedded-bcdns-state-jdbc-spring-boot-starter + + + com.alipay.antchain.bridge + embedded-bcdns-spring-boot-starter + diff --git a/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java b/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java index 4c4dadd..15c50c2 100644 --- a/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java +++ b/r-bootstrap/src/main/java/com/alipay/antchain/bridge/relayer/bootstrap/config/RelayerCoreConfig.java @@ -25,6 +25,7 @@ import cn.hutool.core.io.FileUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.PemUtil; import com.alipay.antchain.bridge.commons.bcdns.AbstractCrossChainCertificate; import com.alipay.antchain.bridge.commons.bcdns.CrossChainCertificateFactory; @@ -44,6 +45,7 @@ import com.alipay.antchain.bridge.relayer.server.network.WSRelayerServer; import com.google.common.util.concurrent.ThreadFactoryBuilder; import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.BeanInitializationException; @@ -55,6 +57,7 @@ import org.springframework.core.io.Resource; import org.springframework.transaction.support.TransactionTemplate; +@Slf4j @Configuration public class RelayerCoreConfig { @@ -98,7 +101,15 @@ public class RelayerCoreConfig { private boolean isDiscoveryService; public AbstractCrossChainCertificate getLocalRelayerCrossChainCertificate() { - AbstractCrossChainCertificate relayerCertificate = null; + if (StrUtil.equals("null", relayerCrossChainCert.getFilename())) { + log.warn("your relayer crosschain certificate is not set"); + return null; + } + if (!relayerCrossChainCert.exists()) { + log.error("your relayer crosschain certificate {} not exist", relayerCrossChainCert.getFilename()); + return null; + } + AbstractCrossChainCertificate relayerCertificate; try { relayerCertificate = CrossChainCertificateFactory.createCrossChainCertificateFromPem( FileUtil.readBytes(relayerCrossChainCert.getFile()) @@ -111,7 +122,8 @@ public AbstractCrossChainCertificate getLocalRelayerCrossChainCertificate() { } public RelayerCredentialSubject getLocalRelayerCredentialSubject() { - return RelayerCredentialSubject.decode(getLocalRelayerCrossChainCertificate().getCredentialSubject()); + return ObjectUtil.isNull(getLocalRelayerCrossChainCertificate()) ? + null : RelayerCredentialSubject.decode(getLocalRelayerCrossChainCertificate().getCredentialSubject()); } public String getLocalRelayerIssuerDomainSpace() { @@ -136,7 +148,8 @@ public PrivateKey getLocalPrivateKey() { } public String getLocalRelayerNodeId() { - return RelayerNodeInfo.calculateNodeId(getLocalRelayerCrossChainCertificate()); + return ObjectUtil.isNull(getLocalRelayerCrossChainCertificate()) ? + null : RelayerNodeInfo.calculateNodeId(getLocalRelayerCrossChainCertificate()); } @Bean diff --git a/r-bootstrap/src/main/resources/logback-spring.xml b/r-bootstrap/src/main/resources/logback-spring.xml index 8b0ac18..7d21183 100755 --- a/r-bootstrap/src/main/resources/logback-spring.xml +++ b/r-bootstrap/src/main/resources/logback-spring.xml @@ -62,6 +62,27 @@ ACCEPT + + ${logging.path}/${APP_NAME}/embedded-bcdns.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - + %msg%n + + UTF-8 + + + ${logging.path}/${APP_NAME}/embedded-bcdns.log.%d{yyyy-MM-dd}.%i + 7 + 50MB + 2GB + true + + + INFO + ACCEPT + ACCEPT + + 0 @@ -85,6 +106,10 @@ + + + + diff --git a/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java b/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java index 8f7328c..e400348 100644 --- a/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java +++ b/r-bootstrap/src/test/java/com/alipay/antchain/bridge/relayer/bootstrap/manager/BCDNSManagerTest.java @@ -21,7 +21,7 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; -import com.alipay.antchain.bridge.bcdns.impl.BlockChainDomainNameServiceFactory; +import com.alipay.antchain.bridge.bcdns.factory.BlockChainDomainNameServiceFactory; import com.alipay.antchain.bridge.bcdns.service.BCDNSTypeEnum; import com.alipay.antchain.bridge.bcdns.service.IBlockChainDomainNameService; import com.alipay.antchain.bridge.bcdns.types.base.DomainRouter; diff --git a/r-cli/README.md b/r-cli/README.md index 2ef2d79..516bd07 100644 --- a/r-cli/README.md +++ b/r-cli/README.md @@ -960,9 +960,9 @@ relayer:> query-curr-active-nodes [ { "last_active_time":1704366281000, - "node_ip":"30.75.64.168", + "node_ip":"192.168.0.1", "active":true, - "node_id":"30.75.64.168" + "node_id":"192.168.0.1" } ] ``` @@ -1080,3 +1080,137 @@ relayer:> convert-cross-chain-cert-to-pem --base64Input AAAIAgAAAAABAAAAMQEAKAAA certificate in pem saved here: /path/to/output_1704359604268.crt ``` +### 5.5 生成BCDNS根证书 + +> [!IMPORTANT] +> 本功能要求CLI版本大于等于0.3.0 + +在启动BCDNS时,需要提前准备好BCDNS私钥和自签名的根证书,这里提供一个工具🔧,帮助生成它们,尤其是在Relayer启动Embedded BCDNS的时候,可以用到这个功能。 + +命令:`generate-bcdns-root-cert`,执行命令之后会生成一个BCDNS的PEM格式的根证书,并保存到本地,如果没有指定私钥、公钥,会顺便生成公私钥并保存在本地。 + +参数: + +- `--certVersion`:证书格式版本,默认为1; +- `--certId`:证书的ID,默认为“mybcdns”; +- `--credSubjectName`:跨链证书的凭证主体名称 [可选,默认值 = mybcdns] +- `--hashAlgo` HashAlgoEnum:要生成的 bcdns 根跨链证书的发行证明哈希算法,[可选,默认值 = `KECCAK_256`],支持`SHA2_256`, `KECCAK_256`, `SHA3_256`, `SM3`; +- `--signAlgo` SignAlgoEnum:要生成的跨链证书的签名算法,[可选,默认值 = `KECCAK256_WITH_SECP256K1`],支持`ED25519`, `SHA256_WITH_RSA`, `SHA256_WITH_ECDSA`, `KECCAK256_WITH_SECP256K1`, `SM3_WITH_SM2` +- `--oidType` ObjectIdentityType:拥有跨链证书的对象身份类型,[可选,默认值 = X509_PUBLIC_KEY_INFO],还支持BID,并会保存生成的BID Document +- `--pubkeyFile` String:嵌入式 BCDNS 的根公钥路径,默认生成文件名为“embedded-bcdns-root-pubkey.key”的新公钥 [可选] +- `--privateKeyFile` String:嵌入式 BCDNS 的根私钥路径,默认生成文件名为“embedded-bcdns-root-private-key.key”的新私钥 [可选] +- `--outDir` String:保存文件的目录路径,默认当前目录。证书将保存为“embedded-bcdns-root.crt” [可选] + +用法如下: + +1. 直接运行,不指定任何字段,会生成证书和公私钥并保存。 + +``` +relayer:> generate-bcdns-root-cert +your bcdns root cert is: +-----BEGIN BCDNS TRUST ROOT CERTIFICATE----- +AADdAQAAAAABAAAAMQEABwAAAG15YmNkbnMCAAEAAAAAAwBrAAAAAABlAAAAAAAB +AAAAAAEAWAAAADBWMBAGByqGSM49AgEGBSuBBAAKA0IABLbk30Th9fREt89fOGe3 +fsbUbOFrMjXlSjfbHEwu0RgaEt5+4+VUdVo5mU+pimkrlTXgfKm0e7nWM0+ZLvnF +ce8EAAgAAAAT1rFmAAAAAAUACAAAAJMJk2gAAAAABgCKAAAAAACEAAAAAAAHAAAA +bXliY2RucwEAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUr +gQQACgNCAAS25N9E4fX0RLfPXzhnt37G1GzhazI15Uo32xxMLtEYGhLefuPlVHVa +OZlPqYppK5U14HyptHu51jNPmS75xXHvAgAAAAAABwCfAAAAAACZAAAAAAAKAAAA +S0VDQ0FLLTI1NgEAIAAAAN1JM3fcwS62uLhbhZ7YdoYLTogja+b3GLlGhYRpZ5cT +AgAWAAAAS2VjY2FrMjU2V2l0aFNlY3AyNTZrMQMAQQAAAPxlkECDdlt6O5nTxBlN +PvqUBMIPXL2ya27m5fZms+zdJx/ZSUb2SYpOiKiy99nSxcfnZ1Yvj4YKu8HkTpjJ +MK8A +-----END BCDNS TRUST ROOT CERTIFICATE----- + +your bcdns root cert file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt +your bcdns root private key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-private-key.key +your bcdns root public key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-pubkey.key +``` + +2. 指定部分字段 + +``` +relayer:> generate-bcdns-root-cert --certId test --credSubjectName test --hashAlgo SHA2_256 --signAlgo ED25519 --oidType BID +your bcdns root cert is: +-----BEGIN BCDNS TRUST ROOT CERTIFICATE----- +AADfAQAAAAABAAAAMQEABAAAAHRlc3QCAAEAAAAAAwA7AAAAAAA1AAAAAAABAAAA +AQEAKAAAAGRpZDpiaWQ6ZWZoTHpSaGNaWXhIdXd5THhxRW9iUGl4RUR1NWg0VGUE +AAgAAAAZ2rFmAAAAAAUACAAAAJkNk2gAAAAABgDRAAAAAADLAAAAAAAEAAAAdGVz +dAEAOwAAAAAANQAAAAAAAQAAAAEBACgAAABkaWQ6YmlkOmVmaEx6UmhjWll4SHV3 +eUx4cUVvYlBpeEVEdTVoNFRlAgB6AAAAeyJwdWJsaWNLZXkiOlt7InR5cGUiOiJF +RDI1NTE5IiwicHVibGljS2V5SGV4IjoiYjA2NTY2YjlkNDMyYWU0YTU5OTQ1MmYw +NjA3MjA3YmUwMzM3N2E1NjY4NjlkNmE2ZDY0MDJmMmQ1N2I5Mzg3YzJhZmQ3MSJ9 +XX0HAI0AAAAAAIcAAAAAAAgAAABTSEEyLTI1NgEAIAAAAH8zd6FasjxeGERqh9gg +VngUv3EePrjpiS6rAu3tp29dAgAHAAAARWQyNTUxOQMAQAAAANcgHl5Ujxxn3zoG +RP1pQmM7E/9/IpAcv++//HQM4Md/3NIHG5a3l6USm0yDAc5s4NOQLaoIId7A5dGB +8X8Jxw8= +-----END BCDNS TRUST ROOT CERTIFICATE----- + +your bcdns root cert file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt +your bcdns root private key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-private-key.key +your bcdns root public key file is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-pubkey.key +your bid document is /AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-bid-document.json +``` + +2. 指定特定公私钥运行 + +``` +relayer:> generate-bcdns-root-cert --certId test --credSubjectName test --hashAlgo SHA2_256 --signAlgo ED25519 --oidType BID --privateKeyFile ./embedded-bcdns-root-private-key.key --pubkeyFile ./embedded-bcdns-root-pubkey.key +your bcdns root cert is: +-----BEGIN BCDNS TRUST ROOT CERTIFICATE----- +AADfAQAAAAABAAAAMQEABAAAAHRlc3QCAAEAAAAAAwA7AAAAAAA1AAAAAAABAAAA +AQEAKAAAAGRpZDpiaWQ6ZWZoTHpSaGNaWXhIdXd5THhxRW9iUGl4RUR1NWg0VGUE +AAgAAACK27FmAAAAAAUACAAAAAoPk2gAAAAABgDRAAAAAADLAAAAAAAEAAAAdGVz +dAEAOwAAAAAANQAAAAAAAQAAAAEBACgAAABkaWQ6YmlkOmVmaEx6UmhjWll4SHV3 +eUx4cUVvYlBpeEVEdTVoNFRlAgB6AAAAeyJwdWJsaWNLZXkiOlt7InR5cGUiOiJF +RDI1NTE5IiwicHVibGljS2V5SGV4IjoiYjA2NTY2YjlkNDMyYWU0YTU5OTQ1MmYw +NjA3MjA3YmUwMzM3N2E1NjY4NjlkNmE2ZDY0MDJmMmQ1N2I5Mzg3YzJhZmQ3MSJ9 +XX0HAI0AAAAAAIcAAAAAAAgAAABTSEEyLTI1NgEAIAAAALIrlWoLe34gHQ4hc+M0 +LGzIxwjSh/TSNkvNXf2qS9D1AgAHAAAARWQyNTUxOQMAQAAAADwCG0OukeuUNOhR +9HIyqYHs30IR/fXVnoAvx7L6PE0iOPfd06BxweSLL89jL1qqXVuS+Mqo3zPlJQGH +L0MTzgo= +-----END BCDNS TRUST ROOT CERTIFICATE----- +your bcdns root cert file is /Users/zouxyan/IdeaProjects/AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root.crt +your bid document is /Users/zouxyan/IdeaProjects/AntChainBridgeRelayer/r-cli/target/r-cli/embedded-bcdns-root-bid-document.json +``` + +### 5.6 生成Relayer证书CSR + +证书申请需要申请者构造好`Certificate Signing Request`。 + +命令:`generate-relayer-csr `以 Base64 格式生成中继器证书签名请求 + +参数: + +- `--certVersion` String:要应用的Relayer跨链证书版本 [可选,默认值 = 1] +- `--credSubjectName` String:跨链证书的Relayer凭证主体名称 [可选,默认值 = `myrelayer`] +- `--oidType` ObjectIdentityType:拥有Relayer跨链证书的对象身份类型 [可选,默认值 = `X509_PUBLIC_KEY_INFO`],还支持BID +- `--pubkeyFile` String:应用证书的Relayer公钥的路径 [强制] + +用法如下: + +``` +relayer:> generate-relayer-csr --pubkeyFile ./embedded-bcdns-root-pubkey.key +your CSR is +AADDAAAAAAABAAAAMQIAAQAAAAMEAAgAAAAAAAAAAAAAAAUACAAAAAAAAAAAAAAABgCTAAAAAACNAAAAAAABAAAAMQEACQAAAG15cmVsYXllcgMAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQrcI72jkNt107AeW04b9R4JsunCJ5qPx+XSTqqAiRfkDIB1FK/Sp8hbApRbLp0bT51l0ZJeVtNLlLM2/nhTPpyBAAAAAAA +``` + +### 5.7 生成PTC证书CSR + +证书申请需要申请者构造好`Certificate Signing Request`。 + +命令:`generate-ptc-csr `以 Base64 格式生成PTC证书签名请求。 + +参数: + +- `--certVersion` String:要应用的PTC跨链证书版本 [可选,默认值 = 1] +- `--credSubjectName` String:跨链证书的PTC凭证主体名称 [可选,默认值 = `myrelayer`] +- `--oidType` ObjectIdentityType:拥有PTC跨链证书的对象身份类型 [可选,默认值 = `X509_PUBLIC_KEY_INFO`],还支持BID +- `--pubkeyFile` String:应用证书的PTC公钥的路径 [强制] + +``` +relayer:> generate-ptc-csr --pubkeyFile ./embedded-bcdns-root-pubkey.key --ptcType BLOCKCHAIN +your CSR is +AADGAAAAAAABAAAAMQIAAQAAAAIEAAgAAAAAAAAAAAAAAAUACAAAAAAAAAAAAAAABgCWAAAAAACQAAAAAAABAAAAMQEABQAAAG15cHRjAgABAAAAAQMAawAAAAAAZQAAAAAAAQAAAAABAFgAAAAwVjAQBgcqhkjOPQIBBgUrgQQACgNCAAQrcI72jkNt107AeW04b9R4JsunCJ5qPx+XSTqqAiRfkDIB1FK/Sp8hbApRbLp0bT51l0ZJeVtNLlLM2/nhTPpyBAAAAAAA +``` + diff --git a/r-cli/pom.xml b/r-cli/pom.xml index 24f7280..a46b023 100644 --- a/r-cli/pom.xml +++ b/r-cli/pom.xml @@ -22,7 +22,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-cli @@ -84,7 +84,7 @@ com.alipay.antchain.bridge - antchain-bridge-bcdns + antchain-bridge-bcdns-factory org.bouncycastle diff --git a/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java b/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java index 960ca7a..a95b6dd 100644 --- a/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java +++ b/r-cli/src/main/java/com/alipay/antchain/bridge/relayer/cli/command/UtilsCommands.java @@ -21,11 +21,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.PublicKey; -import java.security.Security; +import java.security.*; import java.security.interfaces.ECPublicKey; +import java.util.Date; import cn.ac.caict.bid.model.BIDDocumentOperation; import cn.ac.caict.bid.model.BIDpublicKeyOperation; @@ -35,6 +33,7 @@ import cn.bif.module.encryption.model.KeyMember; import cn.bif.module.encryption.model.KeyType; import cn.hutool.core.codec.Base64; +import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.ObjectUtil; @@ -48,8 +47,17 @@ import com.alipay.antchain.bridge.bcdns.impl.bif.conf.BifCertificationServiceConfig; import com.alipay.antchain.bridge.bcdns.impl.bif.conf.BifChainConfig; import com.alipay.antchain.bridge.commons.bcdns.AbstractCrossChainCertificate; +import com.alipay.antchain.bridge.commons.bcdns.BCDNSTrustRootCredentialSubject; import com.alipay.antchain.bridge.commons.bcdns.CrossChainCertificateFactory; +import com.alipay.antchain.bridge.commons.bcdns.utils.BIDHelper; import com.alipay.antchain.bridge.commons.bcdns.utils.CrossChainCertificateUtil; +import com.alipay.antchain.bridge.commons.core.base.BIDInfoObjectIdentity; +import com.alipay.antchain.bridge.commons.core.base.ObjectIdentity; +import com.alipay.antchain.bridge.commons.core.base.ObjectIdentityType; +import com.alipay.antchain.bridge.commons.core.base.X509PubkeyInfoObjectIdentity; +import com.alipay.antchain.bridge.commons.core.ptc.PTCTypeEnum; +import com.alipay.antchain.bridge.commons.utils.crypto.HashAlgoEnum; +import com.alipay.antchain.bridge.commons.utils.crypto.SignAlgoEnum; import lombok.Getter; import lombok.SneakyThrows; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; @@ -69,6 +77,14 @@ public class UtilsCommands { Security.addProvider(new BouncyCastleProvider()); } + private static final String EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME = "embedded-bcdns-root-pubkey.key"; + + private static final String EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME = "embedded-bcdns-root-private-key.key"; + + private static final String EMBEDDED_BCDNS_ROOT_CERT = "embedded-bcdns-root.crt"; + + private static final String EMBEDDED_BCDNS_ROOT_BID_DOCUMENT = "embedded-bcdns-root-bid-document.json"; + @ShellMethod(value = "Generate PEM files for the relayer private and public key") public String generateRelayerAccount( @ShellOption(help = "Key algorithm, default Ed25519", defaultValue = "Ed25519") String keyAlgo, @@ -84,22 +100,12 @@ public String generateRelayerAccount( KeyPair keyPair = keyPairGenerator.generateKeyPair(); // dump the private key into pem - StringWriter stringWriter = new StringWriter(256); - JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter); - jcaPEMWriter.writeObject(keyPair.getPrivate()); - jcaPEMWriter.close(); - String privatePem = stringWriter.toString(); Path privatePath = Paths.get(outDir, "private_key.pem"); - Files.write(privatePath, privatePem.getBytes()); + writePrivateKey(keyPair.getPrivate(), privatePath); // dump the public key into pem - stringWriter = new StringWriter(256); - jcaPEMWriter = new JcaPEMWriter(stringWriter); - jcaPEMWriter.writeObject(keyPair.getPublic()); - jcaPEMWriter.close(); - String pubkeyPem = stringWriter.toString(); Path publicPath = Paths.get(outDir, "public_key.pem"); - Files.write(publicPath, pubkeyPem.getBytes()); + writePublicKey(keyPair.getPublic(), publicPath); return StrUtil.format("private key path: {}\npublic key path: {}", privatePath.toAbsolutePath(), publicPath.toAbsolutePath()); } catch (Exception e) { @@ -107,6 +113,128 @@ public String generateRelayerAccount( } } + @ShellMethod(value = "Generate the relayer certificate sign request in Base64 format") + public String generateRelayerCSR( + @ShellOption( + help = "Version of relayer crosschain certificate to apply", + defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION + ) String certVersion, + @ShellOption(help = "Name of relayer credential subject for crosschain certificate", defaultValue = "myrelayer") String credSubjectName, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Type of object identity who owned the relayer crosschain certificate", + defaultValue = "X509_PUBLIC_KEY_INFO" + ) ObjectIdentityType oidType, + @ShellOption( + valueProvider = FileValueProvider.class, + help = "Path to relayer public key who apply the certificate" + ) String pubkeyFile + ) { + try { + ObjectIdentity oid; + byte[] rootSubjectInfo = new byte[]{}; + PublicKey publicKey; + Path pubkeyFilePath = Paths.get(pubkeyFile); + if (Files.isReadable(pubkeyFilePath)) { + publicKey = readPublicKeyFromPem(Files.readAllBytes(pubkeyFilePath)); + } else { + return "please input the path to the correct applicant public key file"; + } + + if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) { + oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded()); + } else { + BIDDocumentOperation bidDocumentOperation = getBid(publicKey); + oid = new BIDInfoObjectIdentity( + BIDHelper.encAddress( + bidDocumentOperation.getPublicKey()[0].getType(), + BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation) + ) + ); + rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes(); + } + + return StrUtil.format( + "your CSR is \n{}", + Base64.encode( + CrossChainCertificateFactory.createRelayerCertificateSigningRequest( + certVersion, + credSubjectName, + oid, + rootSubjectInfo + ).encode() + ) + ); + + } catch (Exception e) { + throw new RuntimeException("unexpected error please input stacktrace to check the detail", e); + } + } + + @ShellMethod(value = "Generate the ptc certificate sign request in Base64 format") + public String generatePtcCSR( + @ShellOption( + help = "Version of ptc crosschain certificate to apply", + defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION + ) String certVersion, + @ShellOption(help = "Name of ptc credential subject for crosschain certificate", defaultValue = "myptc") String credSubjectName, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Type of object identity who owned the ptc crosschain certificate", + defaultValue = "X509_PUBLIC_KEY_INFO" + ) ObjectIdentityType oidType, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Type of ptc to own the crosschain certificate", + defaultValue = "BLOCKCHAIN" + ) PTCTypeEnum ptcType, + @ShellOption( + valueProvider = FileValueProvider.class, + help = "Path to ptc public key who apply the certificate" + ) String pubkeyFile + ) { + try { + ObjectIdentity oid; + byte[] rootSubjectInfo = new byte[]{}; + PublicKey publicKey; + Path pubkeyFilePath = Paths.get(pubkeyFile); + if (Files.isReadable(pubkeyFilePath)) { + publicKey = readPublicKeyFromPem(Files.readAllBytes(pubkeyFilePath)); + } else { + return "please input the path to the correct applicant public key file"; + } + + if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) { + oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded()); + } else { + BIDDocumentOperation bidDocumentOperation = getBid(publicKey); + oid = new BIDInfoObjectIdentity( + BIDHelper.encAddress( + bidDocumentOperation.getPublicKey()[0].getType(), + BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation) + ) + ); + rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes(); + } + + return StrUtil.format( + "your CSR is \n{}", + Base64.encode( + CrossChainCertificateFactory.createPTCCertificateSigningRequest( + certVersion, + credSubjectName, + ptcType, + oid, + rootSubjectInfo + ).encode() + ) + ); + + } catch (Exception e) { + throw new RuntimeException("unexpected error please input stacktrace to check the detail", e); + } + } + @ShellMethod(value = "Generate the BID document file containing the raw public key") public String generateBidDocument( @ShellOption(valueProvider = FileValueProvider.class, help = "The path to public key in PEM") String publicKeyPath, @@ -212,6 +340,120 @@ public String convertCrossChainCertToPem( } } + @ShellMethod(value = "Generate self-signed BCDNS root crosschain certificate in PEM") + public String generateBcdnsRootCert( + @ShellOption( + help = "Version of crosschain certificate to generate", + defaultValue = CrossChainCertificateFactory.DEFAULT_VERSION + ) String certVersion, + @ShellOption(help = "ID for crosschain certificate", defaultValue = "mybcdns") String certId, + @ShellOption(help = "Name of credential subject for crosschain certificate", defaultValue = "mybcdns") String credSubjectName, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Hash algorithm of issue proof for bcdns root crosschain certificate to generate", + defaultValue = "KECCAK_256" + ) HashAlgoEnum hashAlgo, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Signature algorithm of crosschain certificate to generate", + defaultValue = "KECCAK256_WITH_SECP256K1" + ) SignAlgoEnum signAlgo, + @ShellOption( + valueProvider = EnumValueProvider.class, + help = "Type of object identity who owned the crosschain certificate", + defaultValue = "X509_PUBLIC_KEY_INFO" + ) ObjectIdentityType oidType, + @ShellOption( + valueProvider = FileValueProvider.class, + help = "Path to root public key for embedded BCDNS, default generate new public key with filename \"embedded-bcdns-root-pubkey.key\"", + defaultValue = "" + ) String pubkeyFile, + @ShellOption( + valueProvider = FileValueProvider.class, + help = "Path to root private key for embedded BCDNS, default generate new private key with filename \"embedded-bcdns-root-private-key.key\"", + defaultValue = "" + ) String privateKeyFile, + @ShellOption( + valueProvider = FileValueProvider.class, + help = "Directory path to save the files default current directory. Certificate would save as \"embedded-bcdns-root.crt\"", + defaultValue = "" + ) String outDir + ) { + try { + if (oidType == ObjectIdentityType.BID && SignAlgoEnum.ED25519 != signAlgo) { + return "BID object identity only support Ed25519 for now"; + } + + ObjectIdentity oid; + byte[] rootSubjectInfo = new byte[]{}; + PrivateKey privateKey; + PublicKey publicKey; + if (StrUtil.isAllNotEmpty(pubkeyFile, privateKeyFile)) { + privateKey = signAlgo.getSigner().readPemPrivateKey(Files.readAllBytes(Paths.get(privateKeyFile))); + publicKey = readPublicKeyFromPem(Files.readAllBytes(Paths.get(pubkeyFile))); + } else { + KeyPair keyPair = signAlgo.getSigner().generateKeyPair(); + privateKey = keyPair.getPrivate(); + publicKey = keyPair.getPublic(); + writePrivateKey(privateKey, Paths.get(outDir, EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME)); + writePublicKey(publicKey, Paths.get(outDir, EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME)); + } + + if (oidType == ObjectIdentityType.X509_PUBLIC_KEY_INFO) { + oid = new X509PubkeyInfoObjectIdentity(publicKey.getEncoded()); + } else { + BIDDocumentOperation bidDocumentOperation = getBid(publicKey); + oid = new BIDInfoObjectIdentity( + BIDHelper.encAddress( + bidDocumentOperation.getPublicKey()[0].getType(), + BIDHelper.getRawPublicKeyFromBIDDocument(bidDocumentOperation) + ) + ); + rootSubjectInfo = JsonUtils.toJSONString(bidDocumentOperation).getBytes(); + Files.write(Paths.get(outDir, EMBEDDED_BCDNS_ROOT_BID_DOCUMENT), rootSubjectInfo); + } + + AbstractCrossChainCertificate certificate = CrossChainCertificateFactory.createCrossChainCertificate( + certVersion, + certId, + oid, + DateUtil.currentSeconds(), + DateUtil.offsetDay(new Date(), 365).getTime() / 1000, + new BCDNSTrustRootCredentialSubject( + credSubjectName, oid, rootSubjectInfo + ) + ); + + certificate.setProof( + new AbstractCrossChainCertificate.IssueProof( + hashAlgo.getName(), + hashAlgo.hash(certificate.getEncodedToSign()), + signAlgo.getName(), + signAlgo.getSigner().sign(privateKey, certificate.getEncodedToSign()) + ) + ); + String rootCertPem = CrossChainCertificateUtil.formatCrossChainCertificateToPem(certificate); + Files.write(Paths.get(outDir, EMBEDDED_BCDNS_ROOT_CERT), rootCertPem.getBytes()); + return StrUtil.format( + "your bcdns root cert is:\n{}{}{}", + rootCertPem, + StrUtil.format( + "your bcdns root cert file is {}{}", + Paths.get(outDir, EMBEDDED_BCDNS_ROOT_CERT).toAbsolutePath().toString(), + StrUtil.isAllEmpty(pubkeyFile, privateKeyFile) ? StrUtil.format( + "\nyour bcdns root private key file is {}\n" + + "your bcdns root public key file is {}", + Paths.get(outDir, EMBEDDED_BCDNS_PRIVATE_KEY_DEFAULT_FILENAME).toAbsolutePath().toString(), + Paths.get(outDir, EMBEDDED_BCDNS_PUBKEY_DEFAULT_FILENAME).toAbsolutePath().toString() + ) : "" + ), oidType == ObjectIdentityType.BID ? + StrUtil.format("\nyour bid document is {}", Paths.get(outDir, EMBEDDED_BCDNS_ROOT_BID_DOCUMENT).toAbsolutePath().toString()) : "" + ); + } catch (Exception e) { + throw new RuntimeException("unexpected error please input stacktrace to check the detail", e); + } + } + private String convertToBIFAddress(byte[] rawPublicKey) { PublicKeyManager publicKeyManager = new PublicKeyManager(); publicKeyManager.setRawPublicKey(rawPublicKey); @@ -280,4 +522,26 @@ private BIDDocumentOperation getBid(PublicKey publicKey) { return bidDocumentOperation; } + + @SneakyThrows + private void writePrivateKey(PrivateKey privateKey, Path outputFile) { + // dump the private key into pem + StringWriter stringWriter = new StringWriter(256); + JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter); + jcaPEMWriter.writeObject(privateKey); + jcaPEMWriter.close(); + String privatePem = stringWriter.toString(); + Files.write(outputFile, privatePem.getBytes()); + } + + @SneakyThrows + private void writePublicKey(PublicKey publicKey, Path outputFile) { + // dump the public key into pem + StringWriter stringWriter = new StringWriter(256); + JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(stringWriter); + jcaPEMWriter.writeObject(publicKey); + jcaPEMWriter.close(); + String pubkeyPem = stringWriter.toString(); + Files.write(outputFile, pubkeyPem.getBytes()); + } } diff --git a/r-commons/pom.xml b/r-commons/pom.xml index a2f55bd..0535609 100644 --- a/r-commons/pom.xml +++ b/r-commons/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-commons @@ -36,7 +36,7 @@ com.alipay.antchain.bridge - antchain-bridge-bcdns + antchain-bridge-bcdns-factory org.bouncycastle diff --git a/r-core/pom.xml b/r-core/pom.xml index 3e73462..d11cf9f 100644 --- a/r-core/pom.xml +++ b/r-core/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-core @@ -64,9 +64,9 @@ protobuf-maven-plugin ${protobuf-plugin.version} - com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + com.google.protobuf:protoc:${protobuf.version}:exe:osx-x86_64 grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:osx-x86_64 diff --git a/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java b/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java index b844fe1..cb556c5 100644 --- a/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java +++ b/r-core/src/main/java/com/alipay/antchain/bridge/relayer/core/manager/bcdns/BCDNSWrapper.java @@ -18,7 +18,7 @@ import java.util.concurrent.locks.Lock; -import com.alipay.antchain.bridge.bcdns.impl.BlockChainDomainNameServiceFactory; +import com.alipay.antchain.bridge.bcdns.factory.BlockChainDomainNameServiceFactory; import com.alipay.antchain.bridge.bcdns.service.IBlockChainDomainNameService; import com.alipay.antchain.bridge.bcdns.types.base.DomainRouter; import com.alipay.antchain.bridge.bcdns.types.exception.AntChainBridgeBCDNSException; diff --git a/r-dal/pom.xml b/r-dal/pom.xml index f6b5a2a..fdebcdc 100644 --- a/r-dal/pom.xml +++ b/r-dal/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-dal diff --git a/r-engine/pom.xml b/r-engine/pom.xml index 0576346..064e3d9 100644 --- a/r-engine/pom.xml +++ b/r-engine/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-engine diff --git a/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java b/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java index 0255d4f..8fa55dc 100644 --- a/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java +++ b/r-engine/src/main/java/com/alipay/antchain/bridge/relayer/engine/DistributedTaskEngine.java @@ -59,7 +59,7 @@ public class DistributedTaskEngine implements ApplicationRunner { @Value("${relayer.engine.schedule.duty.period:100}") private long dutyPeriod; - @Value("${relayer.engine.schedule.duty.period:3000}") + @Value("${relayer.engine.schedule.duty.biz-period:3000}") private long bizDutyPeriod; @Value("${relayer.engine.schedule.marker.period:300}") diff --git a/r-server/pom.xml b/r-server/pom.xml index 9f12a06..94d71a7 100644 --- a/r-server/pom.xml +++ b/r-server/pom.xml @@ -6,7 +6,7 @@ com.alipay.antchain.bridge antchain-bridge-relayer - 0.2.0 + 0.3.0 r-server