diff --git a/.travis.yml b/.travis.yml index ed5bf0fc8..1b262feda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,10 +34,10 @@ jobs: script: - chmod u+x .ci/script/build-ci.sh - .ci/script/build-ci.sh - - travis_wait 45 ./gradlew check - - ./gradlew jacocoTestReport - after_success: - - bash <(curl -s https://codecov.io/bash) + #- travis_wait 45 ./gradlew check + #- ./gradlew jacocoTestReport + #after_success: + #- bash <(curl -s https://codecov.io/bash) - stage: "dependency pipeline" script: - chmod u+x .ci/script/weid-http-service/build-ci.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 613951bac..144a87461 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +### V1.5.2 (2020-02-24) +- Features: +1. PDF Transportation now forbids content tampering during transportation. +2. Evidence now returns evidence hash instead of address (see API doc for details). +3. Evidence creation and query efficiency is greatly improved. + + ### V1.5.1 (2020-01-22) - Features: 1. Queried CPT can be cached to local machine (require MySQL setup). diff --git a/build.gradle b/build.gradle index beedb95cd..7125afe14 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ if (!gradle.startParameter.isOffline()) { group 'com.webank' -version = "1.5.1" +version = "1.5.2" // Specify JDK version - may vary in different scenarios sourceCompatibility = 1.8 @@ -128,7 +128,7 @@ dependencies { if (gradleVer.startsWith("4")) { if (!gradle.startParameter.isOffline()) { compile logger, lombok, apache_commons, json, mysql_driver, zxing, rpc, pdfbox, protobuf, caffeine - compile("com.webank:weid-contract-java:1.2.12") { + compile("com.webank:weid-contract-java:1.2.14") { exclude group: "org.slf4j", module: "slf4j-log4j12" } compile files("lib/WeDPR-Java-SDK.jar") @@ -144,7 +144,7 @@ dependencies { testAnnotationProcessor 'org.projectlombok:lombok:1.18.10' testCompileOnly 'org.projectlombok:lombok:1.18.10' compile logger, apache_commons, json, mysql_driver, zxing, rpc, pdfbox, protobuf, caffeine - compile("com.webank:weid-contract-java:1.2.12") { + compile("com.webank:weid-contract-java:1.2.14") { exclude group: "org.slf4j", module: "slf4j-log4j12" } compile files("lib/WeDPR-Java-SDK.jar") diff --git a/docs/zh_CN/docs/weidentity-java-sdk-doc.rst b/docs/zh_CN/docs/weidentity-java-sdk-doc.rst index 487cb1496..d3ecc07f6 100644 --- a/docs/zh_CN/docs/weidentity-java-sdk-doc.rst +++ b/docs/zh_CN/docs/weidentity-java-sdk-doc.rst @@ -7824,7 +7824,7 @@ EvidenceService ^^^^^^^^^^^^^^^^^ 1. createEvidence -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~ **基本信息** @@ -7832,7 +7832,7 @@ EvidenceService 接口名称:com.webank.weid.rpc.EvidenceService.createEvidence 接口定义:ResponseData createEvidence(Hashable object, WeIdPrivateKey weIdPrivateKey) - 接口描述: 将传入Object计算Hash值生成存证上链,返回存证地址。传入的私钥将会成为链上存证的签名方。此签名方和凭证的Issuer可以不是同一方。当传入的object为null时,则会创建一个空的存证并返回其地址,空存证中仅包含签名方,不含Hash值。可以随后调用SetHashValue()方法,为空存证添加Hash值和签名。 + 接口描述: 将传入Object计算Hash值生成存证上链,返回存证hash值。传入的私钥将会成为链上存证的签名方。此签名方和凭证的Issuer可以不是同一方。此接口返回的Hash值和generateHash()接口返回值一致。同样的传入Object可以由不同的私钥注册存证,它们的链上存证值将会共存。 **接口入参**\ : @@ -7886,7 +7886,7 @@ com.webank.weid.protocol.base.WeIdPrivateKey - * - result - String - - 创建的凭证合约地址 + - 创建的凭证hash值 - 业务数据 * - transactionInfo - TransactionInfo @@ -7950,49 +7950,6 @@ com.webank.weid.protocol.response.TransactionInfo - 500401 - Evidence参数非法 - -**调用示例** - -.. code-block:: java - - CredentialService credentialService = new CredentialServiceImpl(); - EvidenceService evidenceService = new EvidenceServiceImpl(); - - HashMap claim = new HashMap(3); - claim.put("name", "zhang san"); - claim.put("gender", "F"); - claim.put("age", 18); - - CreateCredentialArgs createCredentialArgs = new CreateCredentialArgs(); - createCredentialArgs.setClaim(claim); - createCredentialArgs.setCptId(1017); - createCredentialArgs.setExpirationDate(1561448312461L); - createCredentialArgs.setIssuer("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - - WeIdPrivateKey weIdPrivateKey = new WeIdPrivateKey(); - weIdPrivateKey.setPrivateKey("60866441986950167911324536025850958917764441489874006048340539971987791929772"); - - createCredentialArgs.setWeIdPrivateKey(weIdPrivateKey); - - // 创建Credential - ResponseData response = credentialService.createCredential(createCredentialArgs); - - //创建Evidence Address - ResponseData responseCreateEvidence = evidenceService.createEvidence(response.getResult().getCredential(), weIdPrivateKey); - - -.. code-block:: text - - 返回结果如: - result: 0xa3203e054bb7a7f0dec134c7510299869e343e8d - errorCode: 0 - errorMessage: success - transactionInfo:(com.webank.weid.protocol.response.TransactionInfo) - blockNumber: 30014 - transactionHash: 0x1f9e62fa152eb5fce859dcf81c7c0eddcbcab63c40629d1c745058c227693dae - transactionIndex: 0 - - **时序图** .. mermaid:: @@ -8017,16 +7974,16 @@ com.webank.weid.protocol.response.TransactionInfo ---- -2. createEvidence (多个签名方) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +2. createEvidence (传入额外记录) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **基本信息** .. code-block:: text 接口名称:com.webank.weid.rpc.EvidenceService.createEvidence - 接口定义:ResponseData createEvidence(Hashable object, List signers, WeIdPrivateKey weIdPrivateKey) - 接口描述: 将传入Object计算Hash值生成存证上链。此方法允许在创建存证时传入多个签名方的WeID;但是,必须传入一个这些签名方WeID所对应持有的私钥进行签名。同样地,此签名方和凭证的Issuer可以不是同一方。当传入的object为null时,则会创建一个空的存证并返回其地址,空存证中仅包含签名方,不含Hash值。可以随后调用SetHashValue()方法,为空存证添加Hash值和签名。 + 接口定义:ResponseData createEvidence(Hashable object, WeIdPrivateKey weIdPrivateKey, Map extra) + 接口描述: 将传入Object计算Hash值生成存证上链。此方法允许在创建存证时写入额外信息。额外信息为一个blob形式的Key-Value映射。不同私钥发交易方的额外信息也是共存且相互独立存储的。如果您重复调用此接口,那么新写入的额外值会以per-key的方式覆盖过去写入的。 **接口入参**\ : @@ -8046,7 +8003,7 @@ Hashable java.lang.Object - 实现了Hashable接口的任意Object - 当前支持Credential,CredentialWrapper,CredentialPojo -java.util.ArrayList +java.util.Map .. list-table:: :header-rows: 1 @@ -8056,11 +8013,11 @@ java.util.ArrayList - 非空 - 说明 - 备注 - * - signers - - List + * - extra + - Map - Y - - 声明的签名者的WeID - - 至少有一个签名者需要传入自己的私钥(在下个参数中) + - 额外信息blob + - com.webank.weid.protocol.base.WeIdPrivateKey @@ -8096,7 +8053,7 @@ com.webank.weid.protocol.base.WeIdPrivateKey - * - result - String - - 创建的凭证合约地址 + - 创建的凭证hash值 - 业务数据 * - transactionInfo - TransactionInfo @@ -8160,52 +8117,6 @@ com.webank.weid.protocol.response.TransactionInfo - 500401 - Evidence参数非法 - -**调用示例** - -.. code-block:: java - - CredentialService credentialService = new CredentialServiceImpl(); - EvidenceService evidenceService = new EvidenceServiceImpl(); - - HashMap claim = new HashMap(3); - claim.put("name", "zhang san"); - claim.put("gender", "F"); - claim.put("age", 18); - - CreateCredentialArgs createCredentialArgs = new CreateCredentialArgs(); - createCredentialArgs.setClaim(claim); - createCredentialArgs.setCptId(1017); - createCredentialArgs.setExpirationDate(1561448312461L); - createCredentialArgs.setIssuer("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - - WeIdPrivateKey weIdPrivateKey = new WeIdPrivateKey(); - weIdPrivateKey.setPrivateKey("60866441986950167911324536025850958917764441489874006048340539971987791929772"); - createCredentialArgs.setWeIdPrivateKey(weIdPrivateKey); - - // 创建Credential - ResponseData response = credentialService.createCredential(createCredentialArgs); - - List signer = new ArrayList<>(); - signer.add("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - signer.add("did:weid:101:0x48f6f6f663ef77409144014ceb063713b65611f8"); - - //创建Evidence Address - ResponseData responseCreateEvidence = evidenceService.createEvidence(response.getResult().getCredential(), signer, weIdPrivateKey); - - -.. code-block:: text - - 返回结果如: - result: 0xa3203e054bb7a7f0dec134c7510299869e343e8d - errorCode: 0 - errorMessage: success - transactionInfo:(com.webank.weid.protocol.response.TransactionInfo) - blockNumber: 30014 - transactionHash: 0x1f9e62fa152eb5fce859dcf81c7c0eddcbcab63c40629d1c745058c227693dae - transactionIndex: 0 - - **时序图** .. mermaid:: @@ -8221,7 +8132,7 @@ com.webank.weid.protocol.response.TransactionInfo end EvidenceService->>EvidenceService: 生成凭证Hash EvidenceService->>EvidenceService: 基于凭证Hash生成签名值 - EvidenceService->>区块链节点: 调用智能合约,创建并上传凭证存证 + EvidenceService->>区块链节点: 调用智能合约,创建并上传凭证存证及额外值 区块链节点-->>EvidenceService: 返回创建结果 opt 创建失败 EvidenceService-->>调用者: 报错并退出 @@ -8240,8 +8151,8 @@ com.webank.weid.protocol.response.TransactionInfo .. code-block:: text 接口名称:com.webank.weid.rpc.EvidenceService.getEvidence - 接口定义:ResponseData getEvidence(String evidenceAddress) - 接口描述: 根据传入的凭证存证地址,在链上查找凭证存证信息。 + 接口定义:ResponseData getEvidence(String evidenceKey) + 接口描述: 根据传入的凭证存证hash值,在链上查找凭证在链上是否存在。如果存在,则返回所有为此hash值创建过存证的创建方,及其创建时间、额外信息。 **接口入参**\ : String @@ -8309,15 +8220,33 @@ com.webank.weid.protocol.base.EvidenceInfo - String - 凭证Hash值 - 是一个66个字节的字符串,以0x开头 - * - signers - - List - - 凭证签发者 - - 链上允许存在多个凭证签发者 - * - signatures - - List - - 签发者生成签名 - - 和每个签发者一一按序对应的签名值 + * - signInfo + - Map + - 存证创建者信息 + - 链上允许一个存证存在多个创建者 +com.webank.weid.protocol.base.EvidenceSignInfo + +.. list-table:: + :header-rows: 1 + + * - 名称 + - 类型 + - 说明 + - 备注 + * - signature + - String + - 存证的签名 + - 以Base64编码的存证签名值 + * - timestamp + - String + - 存证创建时间 + - + * - extra + - Map + - 额外信息的blob映射存储 + - + **此方法返回code** @@ -8343,29 +8272,6 @@ com.webank.weid.protocol.base.EvidenceInfo - 160004 - 参数为空 - -**调用示例** - -.. code-block:: java - - EvidenceService evidenceService = new EvidenceServiceImpl(); - ResponseData response = evidenceService.getEvidence("0xa3203e054bb7a7f0dec134c7510299869e343e8d"); - - -.. code-block:: text - - 返回结果如: - result:(com.webank.weid.protocol.base.EvidenceInfo) - credentialHash: 0x31c2db44db19ec1af69ed6ad2dc36c7a8068c9871cf1a2bd0e67cb6264531f35 - signers:(java.util.ArrayList) - [0]:0x39e5e6f663ef77409144014ceb063713b65600e7 - signatures:(java.util.ArrayList) - [0]:HJoVLhynrqekQWjMEHubd0e5E/J3LLfnWtq3CXpjFaA/Tfj3i0+dDGfa76OqoZhqSuNucXW8f4BZn/Lkd6SPQ/I= - errorCode: 0 - errorMessage: success - transactionInfo:null - - **时序图** .. mermaid:: @@ -8388,35 +8294,36 @@ com.webank.weid.protocol.base.EvidenceInfo ---- - -4. addSignature -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +4. verifySigner +~~~~~~~~~~~~~~~~~~~~~ **基本信息** .. code-block:: text - 接口名称:com.webank.weid.rpc.EvidenceService.addSignature - 接口定义:ResponseData addSignature(Hashable object, String evidenceAddress, WeIdPrivateKey weIdPrivateKey) - 接口描述: 对传入的Object及链上地址,加一个签名存入链上的存证。要求:传入的签名方必须隶属于在创建存证时传入多个签名方的WeID之一。 + 接口名称:com.webank.weid.rpc.EvidenceService.verifySigner + 接口定义:ResponseData verify(EvidenceInfo evidenceInfo, String weId) + 接口描述: 根据传入的存证信息和WeID,从链上根据WeID的公钥,判断此存证是否合法。 **接口入参**\ : -Hashable java.lang.Object +com.webank.weid.protocol.base.EvidenceInfo .. list-table:: :header-rows: 1 * - 名称 - 类型 - - 非空 - 说明 - 备注 - * - Object - - Hashable object - - Y - - 实现了Hashable接口的任意Object - - 当前支持Credential,CredentialWrapper,CredentialPojo + * - credentialHash + - String + - 凭证Hash值 + - 是一个66个字节的字符串,以0x开头 + * - signInfo + - Map + - 存证创建者信息 + - 链上允许一个存证存在多个创建者 java.lang.String @@ -8428,28 +8335,13 @@ java.lang.String - 非空 - 说明 - 备注 - * - evidenceAddress + * - weId - String - Y - - 存证地址 + - 用户WeID - -com.webank.weid.protocol.base.WeIdPrivateKey - -.. list-table:: - :header-rows: 1 - - * - 名称 - - 类型 - - 说明 - - 备注 - * - privateKey - - String - - 私钥 - - 使用十进制数字表示 - - -**接口返回**\ : com.webank.weid.protocol.response.ResponseData\; +**接口返回**\ : com.webank.weid.protocol.response.ResponseData\; .. list-table:: :header-rows: 1 @@ -8461,43 +8353,15 @@ com.webank.weid.protocol.base.WeIdPrivateKey * - errorCode - Integer - 返回结果码 - - + - * - errorMessage - String - 返回结果描述 - - + - * - result - - String - - 创建的凭证合约地址 - - 业务数据 - * - transactionInfo - - TransactionInfo - - 交易信息 - - - - -com.webank.weid.protocol.response.TransactionInfo - -.. list-table:: - :header-rows: 1 - - * - 名称 - - 类型 - - 说明 - - 备注 - * - blockNumber - - BigInteger - - 交易块高 - - - * - transactionHash - - String - - 交易hash - - - * - transactionIndex - - BigInteger - - 交易索引 - - - + - Boolean + - 是否验证成功 + - **此方法返回code** @@ -8510,12 +8374,9 @@ com.webank.weid.protocol.response.TransactionInfo * - SUCCESS - 0 - 成功 - * - CREDENTIAL_PRIVATE_KEY_NOT_EXISTS - - 100415 - - 私钥为空 - * - CREDENTIAL_ISSUER_INVALID - - 100418 - - WeIdentity DID无效 + * - CREDENTIAL_EVIDENCE_SIGNATURE_BROKEN + - 100431 + - 存证签名异常 * - CREDENTIAL_EVIDENCE_BASE_ERROR - 100500 - Evidence标准错误 @@ -8528,47 +8389,6 @@ com.webank.weid.protocol.response.TransactionInfo * - ILLEGAL_INPUT - 160004 - 参数为空 - * - CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT - - 500401 - - Evidence参数非法 - - -**调用示例** - -.. code-block:: java - - CredentialService credentialService = new CredentialServiceImpl(); - EvidenceService evidenceService = new EvidenceServiceImpl(); - - HashMap claim = new HashMap(3); - claim.put("name", "zhang san"); - claim.put("gender", "F"); - claim.put("age", 18); - - CreateCredentialArgs createCredentialArgs = new CreateCredentialArgs(); - createCredentialArgs.setClaim(claim); - createCredentialArgs.setCptId(1017); - createCredentialArgs.setExpirationDate(1561448312461L); - createCredentialArgs.setIssuer("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - - WeIdPrivateKey weIdPrivateKey = new WeIdPrivateKey(); - weIdPrivateKey.setPrivateKey("60866441986950167911324536025850958917764441489874006048340539971987791929772"); - createCredentialArgs.setWeIdPrivateKey(weIdPrivateKey); - - // 创建Credential - ResponseData response = credentialService.createCredential(createCredentialArgs); - - List signer = new ArrayList<>(); - signer.add("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - signer.add("did:weid:101:0x48f6f6f663ef77409144014ceb063713b65611f8"); - - //创建Evidence Address - ResponseData responseCreateEvidence = evidenceService.createEvidence(response.getResult().getCredential(), signer, weIdPrivateKey); - - String eviAddr = responseCreateEvidence.getResult(); - weIdPrivateKey.setPrivateKey("3171324536025850958917764441489874006048340539971987768716844") - ResponseData resp = evidenceService.addSignature(response.getResult().getCredential, eviAddr, weIdPrivateKey); - .. code-block:: text @@ -8576,10 +8396,7 @@ com.webank.weid.protocol.response.TransactionInfo result: true errorCode: 0 errorMessage: success - transactionInfo:(com.webank.weid.protocol.response.TransactionInfo) - blockNumber: 30014 - transactionHash: 0x1f9e62fa152eb5fce859dcf81c7c0eddcbcab63c40629d1c745058c227693dae - transactionIndex: 0 + transactionInfo:null **时序图** @@ -8589,50 +8406,53 @@ com.webank.weid.protocol.response.TransactionInfo sequenceDiagram participant 调用者 participant EvidenceService + participant WeIdService participant 区块链节点 - 调用者->>EvidenceService: 调用addSignature() + 调用者->>EvidenceService: 调用VerifySi EvidenceService->>EvidenceService: 入参非空、格式及合法性检查 opt 入参校验失败 EvidenceService-->>调用者: 报错,提示参数不合法并退出 end - EvidenceService->>EvidenceService: 根据凭证Hash计算签名值 - EvidenceService->>区块链节点: 调用智能合约,上传签名值 - 区块链节点-->>EvidenceService: 返回创建结果 - opt 创建失败 - EvidenceService-->>调用者: 报错并退出 + EvidenceService->>WeIdService: 根据存证中签名方信息,调用GetWeIdDocument()查询WeID公钥 + WeIdService->>区块链节点: 调用智能合约,查询WeID公钥 + 区块链节点-->>WeIdService: 返回查询结果 + EvidenceService->>EvidenceService: 验证存证中签名是否为与凭证Hash一致 + opt 验签失败 + EvidenceService-->>调用者: 返回验证失败,报错并退出 end - EvidenceService-->>调用者: 返回成功 + EvidenceService-->>调用者: 返回验证成功 ----- -5. verify +4. verifySigner ~~~~~~~~~~~~~~~~~~~~~ **基本信息** .. code-block:: text - 接口名称:com.webank.weid.rpc.EvidenceService.verify - 接口定义:ResponseData verify(Hashable object, String evidenceAddress) - 接口描述: 根据传入的Object计算存证Hash值和链上值对比,验证其是否遭到篡改。当存证包含多个签名时,将会依次验证每个签名,必须确实由签名者列表中的某个WeID所签发才算验证成功。 + 接口名称:com.webank.weid.rpc.EvidenceService.verifySigner + 接口定义:ResponseData verify(EvidenceInfo evidenceInfo, String weId) + 接口描述: 根据传入的存证信息和WeID,从链上根据WeID的公钥,判断此WeID是否为该存证的合法创建者。 **接口入参**\ : -java.lang.Object +com.webank.weid.protocol.base.EvidenceInfo .. list-table:: :header-rows: 1 * - 名称 - 类型 - - 非空 - 说明 - 备注 - * - Object - - Hashable object - - Y - - 实现了Hashable接口的任意Object - - 当前支持Credential,CredentialWrapper,CredentialPojo + * - credentialHash + - String + - 凭证Hash值 + - 是一个66个字节的字符串,以0x开头 + * - signInfo + - Map + - 存证创建者信息 + - 链上允许一个存证存在多个创建者 java.lang.String @@ -8644,14 +8464,12 @@ java.lang.String - 非空 - 说明 - 备注 - * - evidenceAddress + * - weId - String - Y - - 存证地址 + - 用户WeID - - - **接口返回**\ : com.webank.weid.protocol.response.ResponseData\; .. list-table:: @@ -8664,43 +8482,15 @@ java.lang.String * - errorCode - Integer - 返回结果码 - - + - * - errorMessage - String - 返回结果描述 - - + - * - result - Boolean - - 是否set成功 - - - * - transactionInfo - - TransactionInfo - - 交易信息 - - - - -com.webank.weid.protocol.response.TransactionInfo - -.. list-table:: - :header-rows: 1 - - * - 名称 - - 类型 - - 说明 - - 备注 - * - blockNumber - - BigInteger - - 交易块高 - - - * - transactionHash - - String - - 交易hash - - - * - transactionIndex - - BigInteger - - 交易索引 - - - + - 是否验证成功 + - **此方法返回code** @@ -8713,54 +8503,12 @@ com.webank.weid.protocol.response.TransactionInfo * - SUCCESS - 0 - 成功 - * - CPT_ID_ILLEGAL - - 100303 - - cptId无效 - * - CREDENTIAL_EXPIRED - - 100402 - - 过期 - * - CREDENTIAL_ISSUER_MISMATCH - - 100403 - - issuer与签名不匹配 - * - CREDENTIAL_SIGNATURE_BROKEN - - 100405 - - 签名破坏 - * - CREDENTIAL_CREATE_DATE_ILLEGAL - - 100408 - - 创建日期格式非法 - * - CREDENTIAL_EXPIRE_DATE_ILLEGAL - - 100409 - - 到期日期格式非法 - * - CREDENTIAL_CLAIM_NOT_EXISTS - - 100410 - - Claim数据不能为空 - * - CREDENTIAL_ID_NOT_EXISTS - - 100412 - - ID为空 - * - CREDENTIAL_CONTEXT_NOT_EXISTS - - 100413 - - context为空 - * - CREDENTIAL_WEID_DOCUMENT_ILLEGAL - - 100417 - - WeIdentity Document为空 - * - CREDENTIAL_ISSUER_INVALID - - 100418 - - WeIdentity DID无效 - * - CREDENTIAL_EXCEPTION_VERIFYSIGNATURE - - 100419 - - 验证签名异常 - * - CREDENTIAL_SIGNATURE_TYPE_ILLEGAL - - 100429 - - 验证签名类型异常 * - CREDENTIAL_EVIDENCE_SIGNATURE_BROKEN - 100431 - 存证签名异常 * - CREDENTIAL_EVIDENCE_BASE_ERROR - 100500 - Evidence标准错误 - * - CREDENTIAL_EVIDENCE_HASH_MISMATCH - - 100501 - - Evidence Hash不匹配 * - TRANSACTION_TIMEOUT - 160001 - 超时 @@ -8771,44 +8519,6 @@ com.webank.weid.protocol.response.TransactionInfo - 160004 - 参数为空 - -**调用示例** - -.. code-block:: java - - CredentialService credentialService = new CredentialServiceImpl(); - EvidenceService evidenceService = new EvidenceServiceImpl(); - - HashMap claim = new HashMap(3); - claim.put("name", "zhang san"); - claim.put("gender", "F"); - claim.put("age", 18); - - CreateCredentialArgs createCredentialArgs = new CreateCredentialArgs(); - createCredentialArgs.setClaim(claim); - createCredentialArgs.setCptId(1017); - createCredentialArgs.setExpirationDate(1561448312461L); - createCredentialArgs.setIssuer("did:weid:0x30404b47c6c5811d49e28ea2306c804d16618017"); - - WeIdPrivateKey weIdPrivateKey = new WeIdPrivateKey(); - weIdPrivateKey.setPrivateKey("60866441986950167911324536025850958917764441489874006048340539971987791929772"); - - createCredentialArgs.setWeIdPrivateKey(weIdPrivateKey); - - //创建Credential - ResponseData response = credentialService.createCredential(createCredentialArgs); - - Credential credential = response.getResult().getCredential(); - - //创建Evidence Address - ResponseData responseCreateEvidence = evidenceService.createEvidence(credential, weIdPrivateKey); - - String evidenceAddress = responseCreateEvidence.getResult(); - - //验证Credential by evidenceAddress - ResponseData responseVerify = evidenceService.verify(credential, evidenceAddress); - - .. code-block:: text 返回结果如: @@ -8827,62 +8537,50 @@ com.webank.weid.protocol.response.TransactionInfo participant EvidenceService participant WeIdService participant 区块链节点 - 调用者->>EvidenceService: 调用VerifyEvidence() + 调用者->>EvidenceService: 调用VerifySigner() EvidenceService->>EvidenceService: 入参非空、格式及合法性检查 opt 入参校验失败 EvidenceService-->>调用者: 报错,提示参数不合法并退出 end - EvidenceService->>EvidenceService: 调用GetEvidence()查询凭证内容 - EvidenceService->>区块链节点: 调用智能合约,查询凭证存证内容 - 区块链节点-->>EvidenceService: 返回查询结果 - opt 查询出错 - EvidenceService-->>调用者: 返回验证失败,报错并退出 - end - EvidenceService->>EvidenceService: 生成凭证Hash,与链上凭证Hash对比是否一致 - opt Hash不一致 - EvidenceService-->>调用者: 返回验证失败,报错并退出 - end EvidenceService->>WeIdService: 根据存证中签名方信息,调用GetWeIdDocument()查询WeID公钥 WeIdService->>区块链节点: 调用智能合约,查询WeID公钥 区块链节点-->>WeIdService: 返回查询结果 - EvidenceService->>EvidenceService: 验证存证中签名是否为与凭证Hash一致 + EvidenceService->>EvidenceService: 验证存证中签名是否合法,WeID是否存在 opt 验签失败 EvidenceService-->>调用者: 返回验证失败,报错并退出 end EvidenceService-->>调用者: 返回验证成功 - -6. setHashValue -~~~~~~~~~~~~~~~~~ - +5. verifySigner(传入公钥) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **基本信息** .. code-block:: text - 接口名称:com.webank.weid.rpc.EvidenceService.setHashValue - 接口定义:ResponseData setHashValue(String hashValue, String evidenceAddress, WeIdPrivateKey weIdPrivateKey) - 接口描述: 对指定的空存证地址,将其链上的Hash值设定为所传入的Hash值。传入的私钥必须是创建存证时所声明的签名者之一。注意:当存证非空时,接口将返回失败。 + 接口名称:com.webank.weid.rpc.EvidenceService.verifySigner + 接口定义:ResponseData verify(EvidenceInfo evidenceInfo, String weId, String publicKey) + 接口描述: 根据传入的存证信息和WeID,及传入的公钥,判断此WeID是否为存证的合法创建者。不需要链上交互。 **接口入参**\ : -Hashable java.lang.Object - -java.lang.String +com.webank.weid.protocol.base.EvidenceInfo .. list-table:: :header-rows: 1 * - 名称 - 类型 - - 非空 - 说明 - 备注 - * - hashValue + * - credentialHash - String - - Y - - 存证Hash值 - - SHA3算法生成,符合SECP256K1规范,共64个字节,以“0x”开头 + - 凭证Hash值 + - 是一个66个字节的字符串,以0x开头 + * - signInfo + - Map + - 存证创建者信息 + - 链上允许一个存证存在多个创建者 java.lang.String @@ -8894,28 +8592,29 @@ java.lang.String - 非空 - 说明 - 备注 - * - evidenceAddress + * - weId - String - Y - - 存证地址 + - 用户WeID - -com.webank.weid.protocol.base.WeIdPrivateKey +java.lang.String .. list-table:: :header-rows: 1 * - 名称 - 类型 + - 非空 - 说明 - 备注 - * - privateKey + * - publicKey - String - - 私钥 - - 使用十进制数字表示 - + - Y + - 传入公钥 + - -**接口返回**\ : com.webank.weid.protocol.response.ResponseData\; +**接口返回**\ : com.webank.weid.protocol.response.ResponseData\; .. list-table:: :header-rows: 1 @@ -8933,37 +8632,121 @@ com.webank.weid.protocol.base.WeIdPrivateKey - 返回结果描述 - * - result - - String - - 创建的凭证合约地址 - - 业务数据 - * - transactionInfo - - TransactionInfo - - 交易信息 + - Boolean + - 是否验证成功 - +**此方法返回code** -com.webank.weid.protocol.response.TransactionInfo +.. list-table:: + :header-rows: 1 + + * - enum + - code + - desc + * - SUCCESS + - 0 + - 成功 + * - CREDENTIAL_EVIDENCE_SIGNATURE_BROKEN + - 100431 + - 存证签名异常 + * - CREDENTIAL_EVIDENCE_BASE_ERROR + - 100500 + - Evidence标准错误 + * - WEID_PUBLICKEY_INVALID + - 100102 + - 公钥格式非法 + * - TRANSACTION_TIMEOUT + - 160001 + - 超时 + * - TRANSACTION_EXECUTE_ERROR + - 160002 + - 交易错误 + * - ILLEGAL_INPUT + - 160004 + - 参数为空 + +.. code-block:: text + + 返回结果如: + result: true + errorCode: 0 + errorMessage: success + transactionInfo:null + + +**时序图** + +.. mermaid:: + + sequenceDiagram + participant 调用者 + participant EvidenceService + participant WeIdService + participant 区块链节点 + 调用者->>EvidenceService: 调用VerifySigner() + EvidenceService->>EvidenceService: 入参非空、格式及合法性检查 + opt 入参校验失败 + EvidenceService-->>调用者: 报错,提示参数不合法并退出 + end + EvidenceService->>EvidenceService: 验证存证中签名是否合法且WeID存在 + opt 验签失败 + EvidenceService-->>调用者: 返回验证失败,报错并退出 + end + EvidenceService-->>调用者: 返回验证成功 + + +6. generateHash +~~~~~~~~~~~~~~~~~~~ + +**基本信息** + +.. code-block:: text + + 接口名称: com.webank.weid.rpc.EvidenceService.generateHash + 接口定义: ResponseData generateHash(T object) + 接口描述: 将传入的任意Object计算Hash值,不需网络。可以接受**任意Hashable对象**(如凭证)、**File**(Java里的文件实例)、**String**(字符串)。对于不符合类型的入参,将返回类型不支持错误。返回值为HashString,可以直接传入CreateEvidence接口用于存证创建。 + +**接口入参**\ : + +T java.lang.Object .. list-table:: :header-rows: 1 * - 名称 - 类型 + - 非空 - 说明 - 备注 - * - blockNumber - - BigInteger - - 交易块高 + * - Object + - T object + - N + - 任意Object + - 当前支持Hashable,File, String + + +**接口返回**\ : com.webank.weid.protocol.response.ResponseData\; + +.. list-table:: + :header-rows: 1 + + * - 名称 + - 类型 + - 说明 + - 备注 + * - errorCode + - Integer + - 返回结果码 - - * - transactionHash + * - errorMessage - String - - 交易hash - - - * - transactionIndex - - BigInteger - - 交易索引 + - 返回结果描述 - - + * - result + - HashString + - 创建的符合Hashable接口的存证值对象 + - 存证值,可以直接传入createEvidence用于存证上链 **此方法返回code** @@ -8976,60 +8759,51 @@ com.webank.weid.protocol.response.TransactionInfo * - SUCCESS - 0 - 成功 - * - CREDENTIAL_PRIVATE_KEY_NOT_EXISTS - - 100415 - - 私钥为空 - * - CREDENTIAL_ISSUER_INVALID - - 100418 - - WeIdentity DID无效 - * - CREDENTIAL_EVIDENCE_BASE_ERROR - - 100500 - - Evidence标准错误 - * - TRANSACTION_TIMEOUT - - 160001 - - 超时 - * - TRANSACTION_EXECUTE_ERROR - - 160002 - - 交易错误 * - ILLEGAL_INPUT - 160004 - - 参数为空 - * - CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT - - 500401 - - Evidence参数非法 + - 入参非法 **调用示例** .. code-block:: java + CredentialService credentialService = new CredentialServiceImpl(); EvidenceService evidenceService = new EvidenceServiceImpl(); + HashMap claim = new HashMap(3); + claim.put("name", "zhang san"); + claim.put("gender", "F"); + claim.put("age", 18); + + CreateCredentialArgs createCredentialArgs = new CreateCredentialArgs(); + createCredentialArgs.setClaim(claim); + createCredentialArgs.setCptId(1017); + createCredentialArgs.setExpirationDate(1561448312461L); + createCredentialArgs.setIssuer("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); + WeIdPrivateKey weIdPrivateKey = new WeIdPrivateKey(); weIdPrivateKey.setPrivateKey("60866441986950167911324536025850958917764441489874006048340539971987791929772"); - List signer = new ArrayList<>(); - signer.add("did:weid:101:0x39e5e6f663ef77409144014ceb063713b65600e7"); - signer.add("did:weid:101:0x48f6f6f663ef77409144014ceb063713b65611f8"); + createCredentialArgs.setWeIdPrivateKey(weIdPrivateKey); - //创建空Evidence - ResponseData emptyEvidenceResp = evidenceService.createEvidence(null, signer, weIdPrivateKey); + // 创建Credential + ResponseData response = credentialService.createCredential(createCredentialArgs); - String eviAddr = emptyEvidenceResp.getResult(); - weIdPrivateKey.setPrivateKey("3171324536025850958917764441489874006048340539971987768716844"); - String hash = "0x1f9e62fa152eb5fce859dcf81c7c0eddcbcab63c40629d1c745058c227693dae"; - ResponseData resp = evidenceService.setHashValue(hash, eviAddr, weIdPrivateKey); + // 直接将凭证传入generateHash + HashString hashString = evidenceService.generateHash(response.getResult().getCredential()).getResult(); + ResponseData responseCreateEvidence = evidenceService.createEvidence(hashString, weIdPrivateKey); .. code-block:: text 返回结果如: - result: true + result: 0xa3203e054bb7a7f0dec134c7510299869e343e8d errorCode: 0 errorMessage: success transactionInfo:(com.webank.weid.protocol.response.TransactionInfo) blockNumber: 30014 - transactionHash: 0x3e8f711b236fc6fce859dcf81c7c0eddcbcab63c40629d1c745058c338704fbf + transactionHash: 0x1f9e62fa152eb5fce859dcf81c7c0eddcbcab63c40629d1c745058c227693dae transactionIndex: 0 @@ -9041,36 +8815,19 @@ com.webank.weid.protocol.response.TransactionInfo participant 调用者 participant EvidenceService participant 区块链节点 - 调用者->>EvidenceService: 调用setHashValue() - EvidenceService->>EvidenceService: 入参非空、格式及合法性检查 + 调用者->>EvidenceService: 调用generateHash() + EvidenceService->>EvidenceService: 入参非空、格式及合法性检查(Hashable, File, String) opt 入参校验失败 EvidenceService-->>调用者: 报错,提示参数不合法并退出 end - EvidenceService->>区块链节点: 检查存证是否为空存证 - 区块链节点-->>EvidenceService: 返回检查结果 - opt 非空 - EvidenceService-->>调用者: 报错并退出 - end - EvidenceService->>区块链节点: 设置Hash值 - 区块链节点-->>EvidenceService: 返回结果 - opt 失败 - EvidenceService-->>调用者: 报错并退出 - end - EvidenceService->>区块链节点: 设置根据Hash值生成签名值并设置存证签名 - 区块链节点-->>EvidenceService: 返回结果 - opt 失败 - EvidenceService-->>调用者: 报错并退出 - end - EvidenceService-->>调用者: 返回成功 - ----- + EvidenceService-->>调用者: 返回HashString及成功 CredentialPojoService -^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^ 1. createCredential -~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~ **基本信息** diff --git a/lib/WeDPR-Java-SDK.jar b/lib/WeDPR-Java-SDK.jar index c41104b00..3d3ee6bb9 100644 Binary files a/lib/WeDPR-Java-SDK.jar and b/lib/WeDPR-Java-SDK.jar differ diff --git a/src/main/java/com/webank/weid/constant/CptType.java b/src/main/java/com/webank/weid/constant/CptType.java new file mode 100644 index 000000000..60048387e --- /dev/null +++ b/src/main/java/com/webank/weid/constant/CptType.java @@ -0,0 +1,74 @@ +/* + * Copyright© (2018-2020) WeBank Co., Ltd. + * + * This file is part of weid-java-sdk. + * + * weid-java-sdk is free software: you can redistribute it and/or modify it under the terms of + * the GNU Lesser General Public License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * weid-java-sdk is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * weid-java-sdk. If not, see . + */ + +package com.webank.weid.constant; + +/** + * CPT type enum. + * + * @author tonychen 2020年2月17日 + */ +public enum CptType { + + /** + * original type, used to create original type credential. + */ + ORIGINAL(0, "original"), + + /** + * zkp type, used to create zkp type credential. + */ + ZKP(1, "zkp"); + + /** + * type code. + */ + private Integer code; + /** + * type name. + */ + private String name; + + /** + * constructor. + * + * @param code cpt type code + * @param name cpt type name + */ + CptType(Integer code, String name) { + this.code = code; + this.name = name; + } + + /** + * get type code. + * + * @return type code + */ + public Integer getCode() { + return this.code; + } + + /** + * get type name. + * + * @return type name + */ + public String getName() { + return this.name; + } +} diff --git a/src/main/java/com/webank/weid/constant/CredentialConstant.java b/src/main/java/com/webank/weid/constant/CredentialConstant.java index 8f2d4597a..69dba07fb 100644 --- a/src/main/java/com/webank/weid/constant/CredentialConstant.java +++ b/src/main/java/com/webank/weid/constant/CredentialConstant.java @@ -43,6 +43,10 @@ public final class CredentialConstant { */ public static final String DEFAULT_CREDENTIAL_TYPE = "VerifiableCredential"; + /** + * cpt type. + */ + public static final String CPT_TYPE_KEY = "cptType"; /** * The Constant zkp Credential type. @@ -145,6 +149,7 @@ public final class CredentialConstant { */ public static final Integer ZKP_USER_NONCE_CPT = 111; + public static final String PRESENTATION_PDF = "presentationFromPDF"; /** * CPT key words. */ diff --git a/src/main/java/com/webank/weid/constant/ErrorCode.java b/src/main/java/com/webank/weid/constant/ErrorCode.java index 75963c0ae..482e4f6b0 100644 --- a/src/main/java/com/webank/weid/constant/ErrorCode.java +++ b/src/main/java/com/webank/weid/constant/ErrorCode.java @@ -276,6 +276,10 @@ public enum ErrorCode { TIMESTAMP_CREATION_FAILED_FOR_SELECTIVELY_DISCLOSED(100438, "timestamp creation does not support selectively disclosed credential"), + CREDENTIAL_USE_VERIFY_FUNCTION_ERROR(100439, + "presentation from pdf transportation, please use verifyPresentationFromPDF function"), + + /** * The credential evidence contract failure: illegal input. */ @@ -295,7 +299,12 @@ public enum ErrorCode { /** * The credential evidence hash mismatch. */ - CREDENTIAL_EVIDENCE_HASH_MISMATCH(100501, "credential evidence hash mismatch"), + CREDENTIAL_EVIDENCE_HASH_MISMATCH(100501, "evidence hash mismatch"), + + /** + * The credential evidence hash mismatch. + */ + CREDENTIAL_EVIDENCE_NOT_EXIST(100502, "evidence does not exist on chain"), /** * The challenge is invalid. @@ -449,6 +458,11 @@ public enum ErrorCode { */ TRANSPORTATION_PDF_TRANSFER_ERROR(100808, "pdf transfer error, please check the error log."), + /** + * pdf transfer error. + */ + TRANSPORTATION_PDF_VERIFY_ERROR(100809, "pdf verify error, please check the error log."), + /** * Authority issuer main error code. */ diff --git a/src/main/java/com/webank/weid/constant/ResolveEventLogStatus.java b/src/main/java/com/webank/weid/constant/ResolveEventLogStatus.java index 7a4d427a1..ccddb8ea0 100644 --- a/src/main/java/com/webank/weid/constant/ResolveEventLogStatus.java +++ b/src/main/java/com/webank/weid/constant/ResolveEventLogStatus.java @@ -5,7 +5,7 @@ public enum ResolveEventLogStatus { STATUS_SUCCESS(0), STATUS_EVENTLOG_NULL(-1), STATUS_RES_NULL(-2), - STATUS_WEID_NOT_MATCH(-3), + STATUS_KEY_NOT_MATCH(-3), STATUS_EVENT_NULL(-4); private Integer value; diff --git a/src/main/java/com/webank/weid/contract/deploy/v1/DeployContractV1.java b/src/main/java/com/webank/weid/contract/deploy/v1/DeployContractV1.java index 86e7a5e58..12694f9e1 100644 --- a/src/main/java/com/webank/weid/contract/deploy/v1/DeployContractV1.java +++ b/src/main/java/com/webank/weid/contract/deploy/v1/DeployContractV1.java @@ -43,6 +43,7 @@ import com.webank.weid.contract.v1.CommitteeMemberData; import com.webank.weid.contract.v1.CptController; import com.webank.weid.contract.v1.CptData; +import com.webank.weid.contract.v1.EvidenceContract; import com.webank.weid.contract.v1.EvidenceFactory; import com.webank.weid.contract.v1.RoleController; import com.webank.weid.contract.v1.SpecificIssuerController; @@ -98,11 +99,10 @@ private static boolean initCredentials() { /** * Inits the web3j. - * */ protected static void initWeb3j() { if (web3j == null) { - web3j = (Web3j)BaseService.getWeb3j(); + web3j = (Web3j) BaseService.getWeb3j(); } } @@ -123,7 +123,7 @@ public static void deployContract() { roleControllerAddress ); } - deployEvidenceContracts(); + deployEvidenceContractsNew(); } private static String deployWeIdContract() { @@ -369,6 +369,7 @@ private static Map deployIssuerContracts(String roleControllerAd return issuerAddressList; } + @Deprecated private static String deployEvidenceContracts() { if (web3j == null) { initWeb3j(); @@ -393,4 +394,28 @@ private static String deployEvidenceContracts() { } return StringUtils.EMPTY; } + + private static String deployEvidenceContractsNew() { + if (web3j == null) { + initWeb3j(); + } + try { + Future f = + EvidenceContract.deploy( + web3j, + credentials, + WeIdConstant.GAS_PRICE, + WeIdConstant.GAS_LIMIT, + WeIdConstant.INILITIAL_VALUE + ); + EvidenceContract evidenceContract = f + .get(DEFAULT_DEPLOY_CONTRACTS_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); + String evidenceContractAddress = evidenceContract.getContractAddress(); + writeAddressToFile(evidenceContractAddress, "evidenceController.address"); + return evidenceContractAddress; + } catch (Exception e) { + logger.error("EvidenceFactory deploy exception", e); + } + return StringUtils.EMPTY; + } } diff --git a/src/main/java/com/webank/weid/contract/deploy/v2/DeployContractV2.java b/src/main/java/com/webank/weid/contract/deploy/v2/DeployContractV2.java index 65db46990..fc5206bf7 100644 --- a/src/main/java/com/webank/weid/contract/deploy/v2/DeployContractV2.java +++ b/src/main/java/com/webank/weid/contract/deploy/v2/DeployContractV2.java @@ -42,6 +42,7 @@ import com.webank.weid.contract.v2.CommitteeMemberData; import com.webank.weid.contract.v2.CptController; import com.webank.weid.contract.v2.CptData; +import com.webank.weid.contract.v2.EvidenceContract; import com.webank.weid.contract.v2.EvidenceFactory; import com.webank.weid.contract.v2.RoleController; import com.webank.weid.contract.v2.SpecificIssuerController; @@ -92,11 +93,10 @@ private static boolean initCredentials() { /** * Inits the web3j. - * */ protected static void initWeb3j() { if (web3j == null) { - web3j = (Web3j)BaseService.getWeb3j(); + web3j = (Web3j) BaseService.getWeb3j(); } } @@ -117,7 +117,7 @@ public static void deployContract() { roleControllerAddress ); } - deployEvidenceContracts(); + deployEvidenceContractsNew(); } private static String deployRoleControllerContracts() { @@ -322,6 +322,7 @@ private static Map deployIssuerContracts(String roleControllerAd return issuerAddressList; } + @Deprecated private static String deployEvidenceContracts() { if (web3j == null) { initWeb3j(); @@ -343,4 +344,24 @@ private static String deployEvidenceContracts() { } return StringUtils.EMPTY; } + + private static String deployEvidenceContractsNew() { + if (web3j == null) { + initWeb3j(); + } + try { + EvidenceContract evidenceContract = + EvidenceContract.deploy( + web3j, + credentials, + new StaticGasProvider(WeIdConstant.GAS_PRICE, WeIdConstant.GAS_LIMIT) + ).send(); + String evidenceContractAddress = evidenceContract.getContractAddress(); + writeAddressToFile(evidenceContractAddress, "evidenceController.address"); + return evidenceContractAddress; + } catch (Exception e) { + logger.error("EvidenceFactory deploy exception", e); + } + return StringUtils.EMPTY; + } } \ No newline at end of file diff --git a/src/main/java/com/webank/weid/protocol/base/EvidenceInfo.java b/src/main/java/com/webank/weid/protocol/base/EvidenceInfo.java index 640dac158..c1c09a7be 100644 --- a/src/main/java/com/webank/weid/protocol/base/EvidenceInfo.java +++ b/src/main/java/com/webank/weid/protocol/base/EvidenceInfo.java @@ -1,5 +1,5 @@ /* - * Copyright© (2018-2019) WeBank Co., Ltd. + * Copyright© (2018-2020) WeBank Co., Ltd. * * This file is part of weid-java-sdk. * @@ -19,7 +19,10 @@ package com.webank.weid.protocol.base; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import lombok.Data; @@ -32,19 +35,38 @@ public class EvidenceInfo { /** - * Required: The full Credential hash. + * Required: full Credential hash. */ private String credentialHash; /** - * Required: The signers of this Credential. + * Required: sign info mapping (key: signer WeID, value: evidenceSignInfo). */ - private List signers; + private Map signInfo = new HashMap<>(); /** - * Required: The signatures of each signers with the same order. In JavaBean object, the - * signatures will be encoded in Base64. On the blockchain, the signatures will be stored in its - * r, s, v. + * Get all signers info. + * + * @return signers list */ - private List signatures; + public List getSigners() { + List signers = new ArrayList<>(); + for (Map.Entry entry : signInfo.entrySet()) { + signers.add(entry.getKey()); + } + return signers; + } + + /** + * Get all signatures info. + * + * @return signatures list + */ + public List getSignatures() { + List signatures = new ArrayList<>(); + for (Map.Entry entry : signInfo.entrySet()) { + signatures.add(entry.getValue().getSignature()); + } + return signatures; + } } diff --git a/src/main/java/com/webank/weid/protocol/base/EvidenceSignInfo.java b/src/main/java/com/webank/weid/protocol/base/EvidenceSignInfo.java new file mode 100644 index 000000000..aef3fb61b --- /dev/null +++ b/src/main/java/com/webank/weid/protocol/base/EvidenceSignInfo.java @@ -0,0 +1,51 @@ +/* + * Copyright© (2018-2020) WeBank Co., Ltd. + * + * This file is part of weid-java-sdk. + * + * weid-java-sdk is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * weid-java-sdk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with weid-java-sdk. If not, see . + */ + +package com.webank.weid.protocol.base; + +import java.util.List; +import java.util.Map; + +import lombok.Data; + +/** + * The sign information of evidence's each signer's sign attempt. Used as a mapped info against + * each individual signer. + * + * @author chaoxinhu 2020.2 + * @since v1.6.0 + */ +@Data +public class EvidenceSignInfo { + + /** + * The signature of the signer onto this evidence. + */ + private String signature; + + /** + * The timestamp at which this evidence is signed. + */ + private String timestamp; + + /** + * The extra value this signer records on chain. + */ + private Map extraValue; +} diff --git a/src/main/java/com/webank/weid/protocol/request/CptMapArgs.java b/src/main/java/com/webank/weid/protocol/request/CptMapArgs.java index d18fed836..cbd344b78 100644 --- a/src/main/java/com/webank/weid/protocol/request/CptMapArgs.java +++ b/src/main/java/com/webank/weid/protocol/request/CptMapArgs.java @@ -23,6 +23,7 @@ import lombok.Data; +import com.webank.weid.constant.CptType; import com.webank.weid.protocol.base.WeIdAuthentication; /** @@ -37,8 +38,14 @@ public class CptMapArgs { * Required: weId authority for this CPT. */ private WeIdAuthentication weIdAuthentication; + /** * Required: The json schema content defined for this CPT. */ private Map cptJsonSchema; + + /** + * cpt type, "ORIGINAL" or "ZKP". default:"ORIGINAL". + */ + private CptType cptType = CptType.ORIGINAL; } diff --git a/src/main/java/com/webank/weid/protocol/request/CptStringArgs.java b/src/main/java/com/webank/weid/protocol/request/CptStringArgs.java index e7d1fb710..f54440f31 100644 --- a/src/main/java/com/webank/weid/protocol/request/CptStringArgs.java +++ b/src/main/java/com/webank/weid/protocol/request/CptStringArgs.java @@ -21,6 +21,7 @@ import lombok.Data; +import com.webank.weid.constant.CptType; import com.webank.weid.protocol.base.WeIdAuthentication; /** @@ -41,4 +42,8 @@ public class CptStringArgs { */ private String cptJsonSchema; + /** + * cpt type, "ORIGINAL" or "ZKP". default:"ORIGINAL". + */ + private CptType cptType = CptType.ORIGINAL; } diff --git a/src/main/java/com/webank/weid/rpc/CredentialPojoService.java b/src/main/java/com/webank/weid/rpc/CredentialPojoService.java index 1d51b94be..5967b65cd 100644 --- a/src/main/java/com/webank/weid/rpc/CredentialPojoService.java +++ b/src/main/java/com/webank/weid/rpc/CredentialPojoService.java @@ -128,6 +128,24 @@ ResponseData verify( PresentationE presentationE ); + /** + * verify the presentation and pdf information. + * @param pdfTemplatePath path of pdf template + * @param serializePdf byte[] of serialize by pdf transportation + * @param presenterWeId the presenter's weid + * @param presentationPolicyE policy of the presentation + * @param challenge challenge + * @param presentationE the presentation + * @return the verification result. True if yes, false otherwise with exact verify error codes + */ + ResponseData verifyPresentationFromPdf( + String pdfTemplatePath, + byte[] serializePdf, + String presenterWeId, + PresentationPolicyE presentationPolicyE, + Challenge challenge, + PresentationE presentationE + ); /** * packing according to original vouchers and disclosure strategies. diff --git a/src/main/java/com/webank/weid/rpc/EvidenceService.java b/src/main/java/com/webank/weid/rpc/EvidenceService.java index e7a835426..252461cfe 100644 --- a/src/main/java/com/webank/weid/rpc/EvidenceService.java +++ b/src/main/java/com/webank/weid/rpc/EvidenceService.java @@ -19,7 +19,7 @@ package com.webank.weid.rpc; -import java.util.List; +import java.util.Map; import com.webank.weid.protocol.base.EvidenceInfo; import com.webank.weid.protocol.base.HashString; @@ -35,84 +35,64 @@ public interface EvidenceService { /** - * Create a new evidence to blockchain, and return the evidence address on-chain. Supports - * following types of input: Credential, CredentialWrapper, CredentialPojo, plain hash value. - * This also supports to create an empty evidence if the passed-in object is null. Afterwards, - * setHashValue() must be called to set a valid hash value. + * Create a new evidence to blockchain, and return the evidence's hash value on-chain. Supports + * following types of input: Credential, CredentialWrapper, CredentialPojo, plain hash String, + * After a successful creation, the hash value will be recorded onto blockchain, and this hash + * value can be used as key to lookup on blockchain. * * @param object the given Java object * @param weIdPrivateKey the signer WeID's private key - * @return evidence address. Return empty string if failed due to any reason. + * @return evidence hash value. Return empty string if failed due to any reason. */ ResponseData createEvidence(Hashable object, WeIdPrivateKey weIdPrivateKey); /** - * Create a new evidence with multiple signers to blockchain, and return the evidence address - * on-chain. Supports following types input: Credential, CredentialWrapper, CredentialPojo, and - * plain hash value. This allows multiple WeIDs to be declared as signers. Here, one signer must - * provide his/her private key to create evidence. The rest of signers can append their - * signature via AddSignature() in future. This also supports to create an empty evidence if the - * passed-in object is null. + * Create a new evidence together with uploaded extra values. * * @param object the given Java object - * @param signers declared signers WeID - * @param weIdPrivateKey the signer WeID's private key - must belong to one of the signers - * @return evidence address. Return empty string if failed due to any reason. - */ - ResponseData createEvidence(Hashable object, List signers, - WeIdPrivateKey weIdPrivateKey); - - /** - * Add new signatures to an existing evidence to increase its credibility. Supports following - * types of input: Credential, CredentialWrapper, CredentialPojo, and plain hash value. Succeeds - * if and only if the sender is one of the signer WeID defined in this evidence. - * - * @param object the given Java object - * @param evidenceAddress the evidence address on chain * @param weIdPrivateKey the signer WeID's private key - * @return true if succeed, false otherwise + * @param extra the extra value blob + * @return evidence hash value */ - ResponseData addSignature(Hashable object, String evidenceAddress, - WeIdPrivateKey weIdPrivateKey); + ResponseData createEvidence( + Hashable object, + WeIdPrivateKey weIdPrivateKey, + Map extra + ); /** - * Set a hash value to an empty evidence, and append a valid signature. Note that if the - * evidence already has a valid hash value, this will always fail. Empty evidence can be created - * via invoking createEvidence() with a null passed-in object. + * Get the evidence info from blockchain. * - * @param hashValue the hash value - * @param evidenceAddress the evidence address on chain - * @param weIdPrivateKey the signer WeID's private key - * @return true if succeed, false otherwise + * @param evidenceKey the hash, on chain + * @return The EvidenceInfo */ - ResponseData setHashValue(String hashValue, String evidenceAddress, - WeIdPrivateKey weIdPrivateKey); + ResponseData getEvidence(String evidenceKey); /** - * Get the evidence from blockchain. + * Generate hash value of any passed-in param. * - * @param evidenceAddress the evidence address on chain - * @return The EvidenceInfo + * @param object param to be hashed + * @param type of param + * @return the hash string */ - ResponseData getEvidence(String evidenceAddress); + ResponseData generateHash(T object); /** - * Verify an object based against the provided Evidence info. Supports following types of input: - * Credential, CredentialWrapper, CredentialPojo, and plain hash value. This will traverse all - * the listed signatures against its singers. + * Validate whether an evidence is signed by this WeID - will perform on-Chain key check. * - * @param object the given Java object - * @param evidenceAddress the evidence address to be verified - * @return true if succeeds, false otherwise + * @param evidenceInfo the evidence info fetched from chain + * @param weId the WeID + * @return true if yes, false otherwise */ - ResponseData verify(Hashable object, String evidenceAddress); + ResponseData verifySigner(EvidenceInfo evidenceInfo, String weId); /** - * Generate hash value of any passed-in param. + * Validate whether an evidence is signed by this WeID with passed-in public key. * - * @param object param to be hashed - * @param type of param - * @return the hash string + * @param evidenceInfo the evidence info fetched from chain + * @param weId the WeID + * @param publicKey the public key + * @return true if yes, false otherwise */ - ResponseData generateHash(T object); + ResponseData verifySigner(EvidenceInfo evidenceInfo, String weId, String publicKey); } diff --git a/src/main/java/com/webank/weid/service/BaseService.java b/src/main/java/com/webank/weid/service/BaseService.java index 7c0d5743f..dd0efc923 100644 --- a/src/main/java/com/webank/weid/service/BaseService.java +++ b/src/main/java/com/webank/weid/service/BaseService.java @@ -62,16 +62,6 @@ public abstract class BaseService { if (StringUtils.isEmpty(fiscoConfig.getCurrentOrgId())) { logger.error("[BaseService] the blockchain orgId is blank."); } - String osName = System.getProperty("os.name").toLowerCase(); - if (osName.contains("windows")) { - - try { - NativeUtils.loadLibraryFromJar("/WeDPR_dynamic_lib/libeay32md.dll"); - NativeUtils.loadLibraryFromJar("/WeDPR_dynamic_lib/ssleay32md.dll"); - } catch (IOException e) { - logger.error("[BaseService] Cannot find SSL libraries (in Windows)."); - } - } } /** diff --git a/src/main/java/com/webank/weid/service/impl/AmopServiceImpl.java b/src/main/java/com/webank/weid/service/impl/AmopServiceImpl.java index f16642525..621684772 100644 --- a/src/main/java/com/webank/weid/service/impl/AmopServiceImpl.java +++ b/src/main/java/com/webank/weid/service/impl/AmopServiceImpl.java @@ -77,13 +77,19 @@ public class AmopServiceImpl extends BaseService implements AmopService { /** * persistence service. */ - private static Persistence dataDriver = new MysqlDriver(); - + private static Persistence dataDriver; /** * credentialpojo service. */ private static CredentialPojoService credentialPojoService = new CredentialPojoServiceImpl(); + private static Persistence getDataDriver() { + if (dataDriver == null) { + dataDriver = new MysqlDriver(); + } + return dataDriver; + } + @Override public ResponseData getPolicyAndChallenge( String targetOrgId, @@ -368,7 +374,7 @@ private void blindCredentialSignature(RequestIssueCredentialResponse response, S CredentialTemplateEntity template = resp1.getResult(); String id = new StringBuffer().append(userId).append("_").append(cptId) .toString(); - ResponseData dbResp = dataDriver + ResponseData dbResp = getDataDriver() .get(DataDriverConstant.DOMAIN_USER_MASTER_SECRET, id); if (dbResp.getErrorCode().intValue() != ErrorCode.SUCCESS.getCode()) { throw new DatabaseException("database error!"); @@ -392,7 +398,7 @@ private void blindCredentialSignature(RequestIssueCredentialResponse response, S // .get(CredentialConstant.CREDENTIAL_META_KEY_ID); String dbKey = credentialPojo.getId(); ResponseData dbResponse = - dataDriver.saveOrUpdate( + getDataDriver().saveOrUpdate( DataDriverConstant.DOMAIN_USER_CREDENTIAL_SIGNATURE, dbKey, newCredentialSignature); diff --git a/src/main/java/com/webank/weid/service/impl/CptServiceImpl.java b/src/main/java/com/webank/weid/service/impl/CptServiceImpl.java index 99fb5595f..1fdfd3dce 100644 --- a/src/main/java/com/webank/weid/service/impl/CptServiceImpl.java +++ b/src/main/java/com/webank/weid/service/impl/CptServiceImpl.java @@ -28,6 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.webank.weid.constant.CredentialConstant; import com.webank.weid.constant.ErrorCode; import com.webank.weid.constant.JsonSchemaConstant; import com.webank.weid.constant.WeIdConstant; @@ -56,12 +57,10 @@ public class CptServiceImpl extends BaseService implements CptService { private static final Logger logger = LoggerFactory.getLogger(CptServiceImpl.class); - - private CptServiceEngine cptServiceEngine = EngineFactory.createCptServiceEngine(); - //获取CPT缓存节点 - private static CacheNode> cptCahceNode = + private static CacheNode> cptCahceNode = CacheManager.registerCacheNode("SYS_CPT", 1000 * 3600 * 24L); + private CptServiceEngine cptServiceEngine = EngineFactory.createCptServiceEngine(); /** * Register a new CPT with a pre-set CPT ID, to the blockchain. @@ -141,7 +140,7 @@ public ResponseData registerCpt(CptMapArgs args, Integer cptId) { String weId = args.getWeIdAuthentication().getWeId(); WeIdPrivateKey weIdPrivateKey = args.getWeIdAuthentication().getWeIdPrivateKey(); - String cptJsonSchemaNew = this.cptSchemaToString(args.getCptJsonSchema()); + String cptJsonSchemaNew = this.cptSchemaToString(args); RsvSignature rsvSignature = sign( weId, cptJsonSchemaNew, @@ -180,7 +179,7 @@ public ResponseData registerCpt(CptMapArgs args) { String weId = args.getWeIdAuthentication().getWeId(); WeIdPrivateKey weIdPrivateKey = args.getWeIdAuthentication().getWeIdPrivateKey(); - String cptJsonSchemaNew = this.cptSchemaToString(args.getCptJsonSchema()); + String cptJsonSchemaNew = this.cptSchemaToString(args); RsvSignature rsvSignature = sign( weId, cptJsonSchemaNew, @@ -275,14 +274,18 @@ public ResponseData updateCpt(CptMapArgs args, Integer cptId) { String weId = args.getWeIdAuthentication().getWeId(); WeIdPrivateKey weIdPrivateKey = args.getWeIdAuthentication().getWeIdPrivateKey(); - String cptJsonSchemaNew = this.cptSchemaToString(args.getCptJsonSchema()); + String cptJsonSchemaNew = this.cptSchemaToString(args); RsvSignature rsvSignature = sign( weId, cptJsonSchemaNew, weIdPrivateKey); String address = WeIdUtils.convertWeIdToAddress(weId); - ResponseData result = cptServiceEngine.updateCpt(cptId, address, - cptJsonSchemaNew, rsvSignature, weIdPrivateKey.getPrivateKey()); + ResponseData result = cptServiceEngine.updateCpt( + cptId, + address, + cptJsonSchemaNew, + rsvSignature, + weIdPrivateKey.getPrivateKey()); if (result.getErrorCode().intValue() == ErrorCode.SUCCESS.getCode()) { cptCahceNode.remove(String.valueOf(cptId)); } @@ -369,12 +372,15 @@ private ErrorCode validateCptJsonSchemaMap( * @param cptJsonSchema Map * @return String */ - private String cptSchemaToString(Map cptJsonSchema) throws Exception { + private String cptSchemaToString(CptMapArgs args) throws Exception { + Map cptJsonSchema = args.getCptJsonSchema(); Map cptJsonSchemaNew = new HashMap(); cptJsonSchemaNew.put(JsonSchemaConstant.SCHEMA_KEY, JsonSchemaConstant.SCHEMA_VALUE); cptJsonSchemaNew.put(JsonSchemaConstant.TYPE_KEY, JsonSchemaConstant.DATA_TYPE_OBJECT); cptJsonSchemaNew.putAll(cptJsonSchema); + String cptType = args.getCptType().getName(); + cptJsonSchemaNew.put(CredentialConstant.CPT_TYPE_KEY, cptType); return DataToolUtils.serialize(cptJsonSchemaNew); } diff --git a/src/main/java/com/webank/weid/service/impl/CredentialPojoServiceImpl.java b/src/main/java/com/webank/weid/service/impl/CredentialPojoServiceImpl.java index a94c5ad94..c194d5c18 100644 --- a/src/main/java/com/webank/weid/service/impl/CredentialPojoServiceImpl.java +++ b/src/main/java/com/webank/weid/service/impl/CredentialPojoServiceImpl.java @@ -73,6 +73,8 @@ import com.webank.weid.service.BaseService; import com.webank.weid.suite.api.persistence.Persistence; import com.webank.weid.suite.persistence.sql.driver.MysqlDriver; +import com.webank.weid.suite.transportation.pdf.impl.PdfTransportationImpl; +import com.webank.weid.suite.transportation.pdf.protocol.PdfAttributeInfo; import com.webank.weid.util.CredentialPojoUtils; import com.webank.weid.util.CredentialUtils; import com.webank.weid.util.DataToolUtils; @@ -98,7 +100,15 @@ public class CredentialPojoServiceImpl extends BaseService implements Credential CredentialFieldDisclosureValue.EXISTED.getStatus().toString(); private static WeIdService weIdService = new WeIdServiceImpl(); private static CptService cptService = new CptServiceImpl(); - private static Persistence dataDriver = new MysqlDriver(); + private static Persistence dataDriver; + PdfTransportationImpl pdfTransportation = new PdfTransportationImpl(); + + private static Persistence getDataDriver() { + if (dataDriver == null) { + dataDriver = new MysqlDriver(); + } + return dataDriver; + } /** * Salt generator. Automatically fillin the map structure in a recursive manner. @@ -621,7 +631,7 @@ private static ErrorCode verifyCptFormat(Integer cptId, Map clai if (cpt == null) { logger.error(ErrorCode.CREDENTIAL_CPT_NOT_EXISTS.getCodeDesc()); return ErrorCode.CREDENTIAL_CPT_NOT_EXISTS; - } + } //String cptJsonSchema = JsonUtil.objToJsonStr(cpt.getCptJsonSchema()); String cptJsonSchema = DataToolUtils.serialize(cpt.getCptJsonSchema()); @@ -654,6 +664,7 @@ private static ResponseData verifyZkpCredential(CredentialPojo credenti if (verifierResult.wedprErrorMessage == null) { return new ResponseData(true, ErrorCode.SUCCESS); } + return new ResponseData(false, ErrorCode.CREDENTIAL_ERROR); } @@ -697,7 +708,7 @@ private static UserResult makeCredential( //String id=(String)preCredential.getClaim().get(CredentialConstant.CREDENTIAL_META_KEY_ID); //save masterSecret and credentialSecretsBlindingFactors to persistence. - ResponseData dbResp = dataDriver + ResponseData dbResp = getDataDriver() .saveOrUpdate(DataDriverConstant.DOMAIN_USER_MASTER_SECRET, id, json); if (dbResp.getErrorCode().intValue() != ErrorCode.SUCCESS.getCode()) { logger.error( @@ -1179,6 +1190,12 @@ public ResponseData verify( Challenge challenge, PresentationE presentationE) { + List typeList = presentationE.getType(); + if (typeList.contains(CredentialConstant.PRESENTATION_PDF)) { + logger.error("[verify] please use verifyPresentationFromPDF function."); + return new ResponseData<>(false, ErrorCode.CREDENTIAL_USE_VERIFY_FUNCTION_ERROR); + } + ErrorCode errorCode = checkInputArgs(presenterWeId, presentationPolicyE, challenge, presentationE); if (errorCode.getCode() != ErrorCode.SUCCESS.getCode()) { @@ -1228,6 +1245,41 @@ public ResponseData verify( } } + @Override + public ResponseData verifyPresentationFromPdf( + String pdfTemplatePath, + byte[] serializePdf, + String presenterWeId, + PresentationPolicyE presentationPolicyE, + Challenge challenge, + PresentationE presentationE) { + + //verify pdf + PdfAttributeInfo pdfAttributeInfo = pdfTransportation.getBaseData(serializePdf); + if (pdfAttributeInfo == null) { + logger.error("[verifyPresentationFromPDF] get pdf base data error."); + } + Boolean retVerifyPdf = pdfTransportation.verifyPdf( + presentationE, + pdfTemplatePath, + pdfAttributeInfo, + serializePdf + ); + + if (!retVerifyPdf) { + logger.error("[verifyPresentationFromPDF] verify pdf error."); + return new ResponseData<>(false, ErrorCode.TRANSPORTATION_PDF_VERIFY_ERROR); + } + + List typeList = presentationE.getType(); + if (typeList.contains(CredentialConstant.PRESENTATION_PDF)) { + typeList.remove(CredentialConstant.PRESENTATION_PDF); + } + presentationE.setType(typeList); + + return this.verify(presenterWeId, presentationPolicyE, challenge, presentationE); + } + private ErrorCode checkInputArgs( String presenterWeId, PresentationPolicyE presentationPolicyE, @@ -1722,8 +1774,7 @@ public ResponseData prepareZkpCredential( * * @param weIdAuthentication auth * @param cptId cpt id - * @param credentialSignatureRequest credentialSignatureRequest - * @param userNonce userNoce made by user + * @param userResult user result * @return credential signed by user. */ private ResponseData generateCpt111Credential( @@ -1776,14 +1827,14 @@ private ResponseData createZkpCredential( .build(); String encodedVerificationRule = Utils.protoToEncodedString(verificationRule); ResponseData dbResp = - dataDriver.get( + getDataDriver().get( DataDriverConstant.DOMAIN_USER_CREDENTIAL_SIGNATURE, credential.getId()); Integer cptId = credentialClone.getCptId(); String id = new StringBuffer().append(userId).append("_").append(cptId).toString(); String newCredentialSignature = dbResp.getResult(); ResponseData masterKeyResp = - dataDriver.get( + getDataDriver().get( DataDriverConstant.DOMAIN_USER_MASTER_SECRET, id); HashMap userCredentialInfo = DataToolUtils diff --git a/src/main/java/com/webank/weid/service/impl/EvidenceServiceImpl.java b/src/main/java/com/webank/weid/service/impl/EvidenceServiceImpl.java index b4fe54ab8..6c2a0de4c 100644 --- a/src/main/java/com/webank/weid/service/impl/EvidenceServiceImpl.java +++ b/src/main/java/com/webank/weid/service/impl/EvidenceServiceImpl.java @@ -21,10 +21,12 @@ import java.io.File; import java.math.BigInteger; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -43,6 +45,7 @@ import com.webank.weid.constant.WeIdConstant; import com.webank.weid.exception.WeIdBaseException; import com.webank.weid.protocol.base.EvidenceInfo; +import com.webank.weid.protocol.base.EvidenceSignInfo; import com.webank.weid.protocol.base.HashString; import com.webank.weid.protocol.base.WeIdDocument; import com.webank.weid.protocol.base.WeIdPrivateKey; @@ -54,6 +57,7 @@ import com.webank.weid.service.impl.engine.EngineFactory; import com.webank.weid.service.impl.engine.EvidenceServiceEngine; import com.webank.weid.util.DataToolUtils; +import com.webank.weid.util.DateUtils; import com.webank.weid.util.WeIdUtils; /** @@ -79,40 +83,12 @@ public class EvidenceServiceImpl extends BaseService implements EvidenceService */ @Override public ResponseData createEvidence(Hashable object, WeIdPrivateKey weIdPrivateKey) { - ResponseData hashResp = getHashValue(object); - if (StringUtils.isEmpty(hashResp.getResult())) { - return new ResponseData<>(StringUtils.EMPTY, hashResp.getErrorCode(), - hashResp.getErrorMessage()); - } - if (!WeIdUtils.isPrivateKeyValid(weIdPrivateKey)) { - return new ResponseData<>(StringUtils.EMPTY, - ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS); - } - return hashToNewEvidence(hashResp.getResult(), weIdPrivateKey.getPrivateKey(), null); + return createEvidence(object, weIdPrivateKey, null); } - /** - * Create a new evidence with multiple signers to blockchain, and return the evidence address - * on-chain. This allows multiple WeIDs to be declared as signers. Here, one signer must provide - * his/her private key to create evidence. The rest of signers can append their signature via - * AddSignature() in future. - * - * @param object the given Java object - * @param signers declared signers WeID - * @param weIdPrivateKey the signer WeID's private key - must belong to one of the signers - * @return evidence address. Return empty string if failed due to any reason. - */ @Override - public ResponseData createEvidence(Hashable object, List signers, - WeIdPrivateKey weIdPrivateKey) { - if (signers == null || signers.size() == 0) { - return createEvidence(object, weIdPrivateKey); - } - for (String signer : signers) { - if (!WeIdUtils.isWeIdValid(signer)) { - return new ResponseData<>(StringUtils.EMPTY, ErrorCode.WEID_INVALID); - } - } + public ResponseData createEvidence(Hashable object, WeIdPrivateKey weIdPrivateKey, + Map extra) { ResponseData hashResp = getHashValue(object); if (StringUtils.isEmpty(hashResp.getResult())) { return new ResponseData<>(StringUtils.EMPTY, hashResp.getErrorCode(), @@ -122,136 +98,17 @@ public ResponseData createEvidence(Hashable object, List signers return new ResponseData<>(StringUtils.EMPTY, ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS); } - // remove duplicates in the signers list - Set hashSet = new LinkedHashSet<>(signers); - signers.clear(); - signers.addAll(hashSet); - String signer = getSignerFromPrivKey(signers, weIdPrivateKey.getPrivateKey()); - if (StringUtils.isEmpty(signer)) { - return new ResponseData<>(StringUtils.EMPTY, - ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS); - } - return hashToNewEvidence(hashResp.getResult(), weIdPrivateKey.getPrivateKey(), signers); - } - - private String getSignerFromPrivKey(List signers, String privateKey) { - ECKeyPair keyPair = ECKeyPair.create(new BigInteger(privateKey)); - String keyWeId = WeIdUtils - .convertAddressToWeId(new Address(Keys.getAddress(keyPair)).toString()); - for (String weId : signers) { - if (weId.equalsIgnoreCase(keyWeId)) { - return keyWeId; + String extraValue = StringUtils.EMPTY; + if (extra != null && !extra.isEmpty()) { + try { + extraValue = URLEncoder.encode(DataToolUtils.stringMapToCompactJson(extra), + StandardCharsets.UTF_8.name()); + } catch (Exception e) { + logger.error("extra value illegal: {}", extra.toString()); + return new ResponseData<>(StringUtils.EMPTY, ErrorCode.ILLEGAL_INPUT); } } - return StringUtils.EMPTY; - } - - /** - * Add new signatures to an existing evidence to increase its credibility. Succeeds only if the - * sender is one of the signer WeID defined in this evidence. - * - * @param object the given Java object - * @param evidenceAddress the evidence address on chain - * @param weIdPrivateKey the signer WeID's private key - * @return true if succeed, false otherwise - */ - @Override - public ResponseData addSignature(Hashable object, String evidenceAddress, - WeIdPrivateKey weIdPrivateKey) { - ResponseData hashResp = getHashValue(object); - if (StringUtils.isEmpty(hashResp.getResult())) { - return new ResponseData<>(false, hashResp.getErrorCode(), hashResp.getErrorMessage()); - } - if (!WeIdUtils.isPrivateKeyValid(weIdPrivateKey)) { - return new ResponseData<>(false, ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS); - } - if (StringUtils.isEmpty(evidenceAddress) || !WeIdUtils.isValidAddress(evidenceAddress)) { - logger.error("Evidence argument illegal input: address. "); - return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT); - } - EvidenceInfo eviInfo = getEvidence(evidenceAddress).getResult(); - if (eviInfo == null || StringUtils.isEmpty(eviInfo.getCredentialHash()) || !eviInfo - .getCredentialHash().equalsIgnoreCase(hashResp.getResult())) { - return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); - } - List onChainSignerAddrs = eviInfo.getSigners(); - String privateKey = weIdPrivateKey.getPrivateKey(); - String signerAddr = - WeIdUtils.convertAddressToWeId( - Keys.getAddress(ECKeyPair.create(new BigInteger(privateKey)))); - if (!onChainSignerAddrs.contains(signerAddr)) { - return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); - } - Sign.SignatureData sigData = DataToolUtils.signMessage(hashResp.getResult(), privateKey); - try { - return evidenceServiceEngine.addSignature(sigData, privateKey, evidenceAddress); - } catch (Exception e) { - logger.error("create evidence failed due to system error. ", e); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } - } - - /** - * Set a hash value to an empty evidence and append the signature. Note that if the evidence - * already has a valid non-empty hash value, this will always fail. Empty evidence can be - * created via invoking createEvidence() with a null passed-in object. - * - * @param hashValue the hash value - * @param evidenceAddress the evidence address on chain - * @param weIdPrivateKey the signer WeID's private key - * @return true if succeed, false otherwise - */ - @Override - public ResponseData setHashValue(String hashValue, String evidenceAddress, - WeIdPrivateKey weIdPrivateKey) { - if (!verifyHashValueFormat(hashValue)) { - return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); - } - if (!WeIdUtils.isPrivateKeyValid(weIdPrivateKey)) { - return new ResponseData<>(false, ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS); - } - if (StringUtils.isEmpty(evidenceAddress) || !WeIdUtils.isValidAddress(evidenceAddress)) { - logger.error("Evidence argument illegal input: address. "); - return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT); - } - String onChainHash = getEvidence(evidenceAddress).getResult().getCredentialHash(); - if (!StringUtils.isEmpty(onChainHash)) { - logger.error("On Chain hash value is not empty, canceling."); - return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); - } - String credentialHashOnChain = hashValue - .replaceAll(WeIdConstant.HEX_PREFIX, StringUtils.EMPTY); - List hashAttributes = new ArrayList<>(); - hashAttributes.add( - credentialHashOnChain.substring(0, WeIdConstant.BYTES32_FIXED_LENGTH)); - hashAttributes.add( - credentialHashOnChain.substring( - WeIdConstant.BYTES32_FIXED_LENGTH, - WeIdConstant.BYTES32_FIXED_LENGTH * 2 - )); - String privateKey = weIdPrivateKey.getPrivateKey(); - try { - ResponseData innerResp = evidenceServiceEngine - .setHashValue(hashAttributes, privateKey, evidenceAddress); - if (!innerResp.getResult()) { - return innerResp; - } - } catch (Exception e) { - logger.error("create evidence failed due to system error. ", e); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } - onChainHash = getEvidence(evidenceAddress).getResult().getCredentialHash(); - if (!onChainHash.equalsIgnoreCase(hashValue)) { - logger.error("Failed to update hash on chain for unknown reasons."); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } - Sign.SignatureData sigData = DataToolUtils.signMessage(hashValue, privateKey); - try { - return evidenceServiceEngine.addSignature(sigData, privateKey, evidenceAddress); - } catch (Exception e) { - logger.error("create evidence failed due to system error. ", e); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } + return hashToNewEvidence(hashResp.getResult(), weIdPrivateKey.getPrivateKey(), extraValue); } /* (non-Javadoc) @@ -331,41 +188,23 @@ private ResponseData getHashValue(Hashable object) { * * @param hashValue the hash value to be uploaded * @param privateKey the private key to reload contract and sign txn - * @param signers the uploading signers - only used in create case + * @param extra the extra value (compact json formatted blob) */ private ResponseData hashToNewEvidence(String hashValue, String privateKey, - List signers) { + String extra) { try { - String credentialHashOnChain = hashValue - .replaceAll(WeIdConstant.HEX_PREFIX, StringUtils.EMPTY); - List hashAttributes = new ArrayList<>(); - Sign.SignatureData sigData; - if (!StringUtils.isEmpty(credentialHashOnChain)) { - hashAttributes.add( - credentialHashOnChain.substring(0, WeIdConstant.BYTES32_FIXED_LENGTH)); - hashAttributes.add( - credentialHashOnChain.substring( - WeIdConstant.BYTES32_FIXED_LENGTH, - WeIdConstant.BYTES32_FIXED_LENGTH * 2 - )); - sigData = - DataToolUtils.signMessage(hashValue, privateKey); - } else { - hashAttributes.add(StringUtils.EMPTY); - hashAttributes.add(StringUtils.EMPTY); - byte v = (byte) 0; - byte[] r = new byte[32]; - byte[] s = new byte[32]; - sigData = new SignatureData(v, r, s); - } - List extraValueList = new ArrayList<>(); - extraValueList.add(StringUtils.EMPTY); + Sign.SignatureData sigData = + DataToolUtils.signMessage(hashValue, privateKey); + String signature = new String( + DataToolUtils.base64Encode(DataToolUtils.simpleSignatureSerialization(sigData)), + StandardCharsets.UTF_8); + Long timestamp = DateUtils.getNoMillisecondTimeStamp(); return evidenceServiceEngine.createEvidence( - sigData, - hashAttributes, - extraValueList, - privateKey, - signers + hashValue, + signature, + extra, + timestamp, + privateKey ); } catch (Exception e) { logger.error("create evidence failed due to system error. ", e); @@ -376,127 +215,23 @@ private ResponseData hashToNewEvidence(String hashValue, String privateK /** * Get the evidence from blockchain. * - * @param evidenceAddress the evidence address on chain + * @param evidenceKey the evidence hash on chain * @return The EvidenceInfo */ @Override - public ResponseData getEvidence(String evidenceAddress) { - if (StringUtils.isEmpty(evidenceAddress) || !WeIdUtils.isValidAddress(evidenceAddress)) { - logger.error("Evidence argument illegal input: address. "); + public ResponseData getEvidence(String evidenceKey) { + if (!DataToolUtils.isValidHash(evidenceKey)) { + logger.error("Evidence argument illegal input: evidence hash. "); return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT); } try { - ResponseData resp = evidenceServiceEngine.getInfo(evidenceAddress); - if (resp.getResult().getCredentialHash().equalsIgnoreCase(WeIdConstant.HEX_PREFIX)) { - resp.getResult().setCredentialHash(StringUtils.EMPTY); - } - return resp; + return evidenceServiceEngine.getInfo(evidenceKey); } catch (Exception e) { logger.error("get evidence failed.", e); return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); } } - private ResponseData verify(String hashValue, String evidenceAddress) { - if (!verifyHashValueFormat(hashValue)) { - return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); - } - // Step 1: Get EvidenceInfo from chain - ResponseData evidenceInfoResponseData = verifyAndGetEvidenceFromChain( - evidenceAddress); - if (evidenceInfoResponseData.getResult() == null) { - return new ResponseData<>(false, evidenceInfoResponseData.getErrorCode(), - evidenceInfoResponseData.getErrorMessage()); - } - EvidenceInfo evidenceInfo = evidenceInfoResponseData.getResult(); - - // Step 2: Verify each signature value in EvidenceInfo wrt the signer based on their their - // publickeys from WeIDContract. Here each signature/signer pair must pass the verification. - return verifyHashToEvidenceSignature(hashValue, evidenceInfo); - } - - /** - * Verify a Credential based on the provided Evidence info. - * - * @param object the given Java object - * @param evidenceAddress the evidence address - * @return true if succeeds, false otherwise - */ - @Override - public ResponseData verify(Hashable object, String evidenceAddress) { - ResponseData hashResp = getHashValue(object); - if (StringUtils.isEmpty(hashResp.getResult())) { - return new ResponseData<>(false, hashResp.getErrorCode(), - hashResp.getErrorMessage()); - } - return verify(hashResp.getResult(), evidenceAddress); - } - - private ResponseData verifyAndGetEvidenceFromChain(String evidenceAddress) { - if (!WeIdUtils.isValidAddress(evidenceAddress)) { - logger.error("Verify EvidenceInfo input illegal: evidenceInfo address"); - return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT); - } - ResponseData innerEvidenceResponseData = getEvidence(evidenceAddress); - if (innerEvidenceResponseData.getResult() == null) { - return new ResponseData<>( - null, - ErrorCode.getTypeByErrorCode(innerEvidenceResponseData.getErrorCode()) - ); - } - return new ResponseData<>(innerEvidenceResponseData.getResult(), ErrorCode.SUCCESS); - } - - private ResponseData verifyHashToEvidenceSignature(String hashOffChain, - EvidenceInfo evidenceInfo) { - if (!StringUtils.equalsIgnoreCase(hashOffChain, evidenceInfo.getCredentialHash())) { - logger.error( - "credential hash mismatches. Off-chain: {}, on-chain: {}", hashOffChain, - evidenceInfo.getCredentialHash()); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_HASH_MISMATCH); - } - try { - for (int i = 0; i < evidenceInfo.getSignatures().size(); i++) { - String signature = evidenceInfo.getSignatures().get(i); - // iterate through each signer - boolean foundMatchedSigner = false; - for (int j = 0; j < evidenceInfo.getSigners().size(); j++) { - String signerWeId = evidenceInfo.getSigners().get(j); - if (WeIdUtils - .isEmptyAddress(new Address(WeIdUtils.convertWeIdToAddress(signerWeId)))) { - break; - } - SignatureData signatureData = - DataToolUtils.simpleSignatureDeserialization( - DataToolUtils.base64Decode(signature.getBytes(StandardCharsets.UTF_8)) - ); - ResponseData innerResponseData = verifySignatureToSigner( - hashOffChain, - WeIdUtils.convertAddressToWeId(signerWeId), - signatureData - ); - if (innerResponseData.getResult()) { - foundMatchedSigner = true; - break; - } - } - if (!foundMatchedSigner) { - logger.error("Signature: " + signature + ", signer mismatch."); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_ISSUER_MISMATCH); - } - } - } catch (WeIdBaseException e) { - logger.error( - "Generic error occurred during verify evidenceInfo: ", e); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_SIGNATURE_BROKEN); - } catch (Exception e) { - logger.error( - "Generic error occurred during verify evidenceInfo: ", e); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } - return new ResponseData<>(true, ErrorCode.SUCCESS); - } - private ResponseData verifySignatureToSigner( String rawData, String signerWeId, @@ -524,8 +259,72 @@ private ResponseData verifySignatureToSigner( } } - private boolean verifyHashValueFormat(String hashValue) { - return !StringUtils.isEmpty(hashValue) - && Pattern.compile(WeIdConstant.HASH_VALUE_PATTERN).matcher(hashValue).matches(); + /** + * Validate whether an evidence is signed by this WeID. + * + * @param evidenceInfo the evidence info fetched from chain + * @param weId the WeID + * @return true if yes, false otherwise + */ + @Override + public ResponseData verifySigner(EvidenceInfo evidenceInfo, String weId) { + return verifySigner(evidenceInfo, weId, null); + } + + + /** + * Validate whether an evidence is signed by this WeID with passed-in public key. + * + * @param evidenceInfo the evidence info fetched from chain + * @param weId the WeID + * @param publicKey the public key + * @return true if yes, false otherwise + */ + @Override + public ResponseData verifySigner( + EvidenceInfo evidenceInfo, + String weId, + String publicKey) { + if (evidenceInfo == null || evidenceInfo.getSigners().isEmpty()) { + return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); + } + if (!WeIdUtils.isWeIdValid(weId)) { + return new ResponseData<>(false, ErrorCode.WEID_INVALID); + } + if (!evidenceInfo.getSigners().contains(weId)) { + logger.error("This Evidence does not contain the provided WeID: {}", weId); + return new ResponseData<>(false, ErrorCode.WEID_DOES_NOT_EXIST); + } + EvidenceSignInfo signInfo = evidenceInfo.getSignInfo().get(weId); + String signature = signInfo.getSignature(); + if (!DataToolUtils.isValidBase64String(signature)) { + return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_SIGNATURE_BROKEN); + } + SignatureData signatureData = + DataToolUtils.simpleSignatureDeserialization( + DataToolUtils.base64Decode(signature.getBytes(StandardCharsets.UTF_8)) + ); + if (StringUtils.isEmpty(publicKey)) { + return verifySignatureToSigner( + evidenceInfo.getCredentialHash(), + WeIdUtils.convertAddressToWeId(weId), + signatureData + ); + } else { + try { + boolean result = DataToolUtils + .verifySignature(evidenceInfo.getCredentialHash(), signatureData, + new BigInteger(publicKey)); + if (!result) { + logger.error("Public key does not match signature."); + return new ResponseData<>(false, ErrorCode.CREDENTIAL_SIGNATURE_BROKEN); + } + return new ResponseData<>(true, ErrorCode.SUCCESS); + } catch (Exception e) { + logger.error("Passed-in signature illegal"); + return new ResponseData<>(false, ErrorCode.WEID_PUBLICKEY_INVALID); + } + } } + } diff --git a/src/main/java/com/webank/weid/service/impl/engine/EvidenceServiceEngine.java b/src/main/java/com/webank/weid/service/impl/engine/EvidenceServiceEngine.java index 206cef612..4a4cc2558 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/EvidenceServiceEngine.java +++ b/src/main/java/com/webank/weid/service/impl/engine/EvidenceServiceEngine.java @@ -19,10 +19,6 @@ package com.webank.weid.service.impl.engine; -import java.util.List; - -import org.bcos.web3j.crypto.Sign; - import com.webank.weid.constant.ErrorCode; import com.webank.weid.protocol.base.EvidenceInfo; import com.webank.weid.protocol.response.ResponseData; @@ -30,19 +26,13 @@ public interface EvidenceServiceEngine { ResponseData createEvidence( - Sign.SignatureData sigData, - List hashAttributes, - List extraValueList, - String privateKey, - List signerWeIdList + String hashValue, + String signature, + String extra, + Long timestamp, + String privateKey ); - ResponseData addSignature(Sign.SignatureData sigData, String privateKey, - String eviAddress); - - ResponseData setHashValue(List hashAttributes, String privateKey, - String eviAddress); - ResponseData getInfo(String evidenceAddress); /** diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/CptServiceEngineV1.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/CptServiceEngineV1.java index f73bb77b4..7011ddb0e 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/CptServiceEngineV1.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/CptServiceEngineV1.java @@ -98,7 +98,7 @@ public class CptServiceEngineV1 extends BaseEngine implements CptServiceEngine { private static String CREDENTIALTEMPLATETOPIC; - private static Persistence dataDriver = new MysqlDriver(); + private static Persistence dataDriver; static { Event event = new Event( @@ -224,6 +224,13 @@ public static ResponseData getResultByResolveEvent( return new ResponseData<>(result, ErrorCode.SUCCESS, info); } + private Persistence getDataDriver() { + if (dataDriver == null) { + dataDriver = new MysqlDriver(); + } + return dataDriver; + } + /* (non-Javadoc) * @see com.webank.weid.service.impl.engine.CptEngineController * #updateCpt(int, java.lang.String, java.lang.String, @@ -371,7 +378,7 @@ public ResponseData registerCpt(String address, String cptJsonSchem private ErrorCode processTemplate(Integer cptId, String cptJsonSchemaNew) { - if (!CredentialPojoUtils.isZkpCpt(cptId)) { + if (!CredentialPojoUtils.isZkpCpt(cptJsonSchemaNew)) { return ErrorCode.SUCCESS; } List attributeList; @@ -382,7 +389,7 @@ private ErrorCode processTemplate(Integer cptId, String cptJsonSchemaNew) { CredentialTemplateEntity template = issuerResult.credentialTemplateEntity; String templateSecretKey = issuerResult.templateSecretKey; ResponseData resp = - dataDriver.saveOrUpdate( + this.getDataDriver().saveOrUpdate( DataDriverConstant.DOMAIN_ISSUER_TEMPLATE_SECRET, String.valueOf(cptId), templateSecretKey); diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/EvidenceServiceEngineV1.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/EvidenceServiceEngineV1.java index 3aff5f084..28329cb96 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/EvidenceServiceEngineV1.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/EvidenceServiceEngineV1.java @@ -19,37 +19,38 @@ package com.webank.weid.service.impl.engine.fiscov1; +import java.io.IOException; import java.math.BigInteger; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; +import java.util.Map; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.bcos.web3j.abi.datatypes.Address; -import org.bcos.web3j.abi.datatypes.DynamicArray; -import org.bcos.web3j.abi.datatypes.Type; -import org.bcos.web3j.abi.datatypes.generated.Bytes32; -import org.bcos.web3j.abi.datatypes.generated.Uint8; -import org.bcos.web3j.crypto.ECKeyPair; -import org.bcos.web3j.crypto.Keys; -import org.bcos.web3j.crypto.Sign; -import org.bcos.web3j.crypto.Sign.SignatureData; +import org.bcos.web3j.abi.datatypes.Utf8String; +import org.bcos.web3j.abi.datatypes.generated.Uint256; +import org.bcos.web3j.protocol.Web3j; +import org.bcos.web3j.protocol.core.DefaultBlockParameterNumber; +import org.bcos.web3j.protocol.core.methods.response.EthBlock; +import org.bcos.web3j.protocol.core.methods.response.EthGetTransactionReceipt; +import org.bcos.web3j.protocol.core.methods.response.Log; +import org.bcos.web3j.protocol.core.methods.response.Transaction; import org.bcos.web3j.protocol.core.methods.response.TransactionReceipt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webank.weid.constant.ErrorCode; +import com.webank.weid.constant.ResolveEventLogStatus; import com.webank.weid.constant.WeIdConstant; -import com.webank.weid.contract.v1.Evidence; -import com.webank.weid.contract.v1.Evidence.AddHashLogEventResponse; -import com.webank.weid.contract.v1.Evidence.AddSignatureLogEventResponse; -import com.webank.weid.contract.v1.EvidenceFactory; -import com.webank.weid.contract.v1.EvidenceFactory.CreateEvidenceLogEventResponse; +import com.webank.weid.contract.v1.EvidenceContract; +import com.webank.weid.contract.v1.EvidenceContract.EvidenceAttributeChangedEventResponse; import com.webank.weid.protocol.base.EvidenceInfo; +import com.webank.weid.protocol.base.EvidenceSignInfo; +import com.webank.weid.protocol.response.ResolveEventLogResult; import com.webank.weid.protocol.response.ResponseData; import com.webank.weid.protocol.response.TransactionInfo; import com.webank.weid.service.impl.engine.BaseEngine; @@ -66,265 +67,234 @@ public class EvidenceServiceEngineV1 extends BaseEngine implements EvidenceServi private static final Logger logger = LoggerFactory.getLogger(EvidenceServiceEngineV1.class); - /** - * Create evidence in 1.x FISCO-BCOS. - * - * @param sigData signature Data - * @param hashAttributes hash value - * @param extraValueList extra value - * @param privateKey private key - * @param signerList declared signers - * @return evidence address - */ + private static EvidenceContract evidenceContract = getContractService( + fiscoConfig.getEvidenceAddress(), + EvidenceContract.class); + @Override public ResponseData createEvidence( - Sign.SignatureData sigData, - List hashAttributes, - List extraValueList, - String privateKey, - List signerList + String hashValue, + String signature, + String extra, + Long timestamp, + String privateKey ) { - try { - Bytes32 r = DataToolUtils.bytesArrayToBytes32(sigData.getR()); - Bytes32 s = DataToolUtils.bytesArrayToBytes32(sigData.getS()); - Uint8 v = DataToolUtils.intToUnt8(Integer.valueOf(sigData.getV())); - List
signer = new ArrayList<>(); - if (signerList == null || signerList.size() == 0) { - // Evidence has only one signer - default to be the WeID behind the private key - ECKeyPair keyPair = ECKeyPair.create(new BigInteger(privateKey)); - signer.add(new Address(Keys.getAddress(keyPair))); - } else { - // Evidence has a pre-defined signer list - for (String signerWeId : signerList) { - signer.add(new Address(WeIdUtils.convertWeIdToAddress(signerWeId))); - } - } - EvidenceFactory evidenceFactory = + EvidenceContract evidenceContractWriter = reloadContract( fiscoConfig.getEvidenceAddress(), privateKey, - EvidenceFactory.class + EvidenceContract.class ); - Future future = evidenceFactory.createEvidence( - new DynamicArray(generateBytes32List(hashAttributes)), - new DynamicArray
(signer), - r, - s, - v, - new DynamicArray(generateBytes32List(extraValueList)) - ); + TransactionReceipt receipt = + evidenceContractWriter.createEvidence( + new Utf8String(hashValue), + new Utf8String(signature), + new Utf8String(extra), + new Uint256(new BigInteger(String.valueOf(timestamp), 10)) + ).get(WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, TimeUnit.SECONDS); - TransactionReceipt receipt = future.get( - WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, - TimeUnit.SECONDS); TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = - EvidenceFactory.getCreateEvidenceLogEvents(receipt); - CreateEvidenceLogEventResponse event = eventResponseList.get(0); - - if (event != null) { - ErrorCode innerResponse = - verifyCreateEvidenceEvent( - event.retCode.getValue().intValue(), - event.addr.toString() - ); - if (ErrorCode.SUCCESS.getCode() != innerResponse.getCode()) { - return new ResponseData<>(StringUtils.EMPTY, innerResponse, info); - } - return new ResponseData<>(event.addr.toString(), ErrorCode.SUCCESS, info); - } else { - logger.error( - "create evidence failed due to transcation event decoding failure." - ); + List eventList = + EvidenceContract.getEvidenceAttributeChangedEvents(receipt); + if (eventList == null || eventList.isEmpty()) { return new ResponseData<>(StringUtils.EMPTY, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + } else { + String address = WeIdUtils + .convertWeIdToAddress(DataToolUtils.convertPrivateKeyToDefaultWeId(privateKey)); + for (EvidenceAttributeChangedEventResponse event : eventList) { + if (isSignEvent(event) && event.value.getValue().equalsIgnoreCase(signature) + && event.signer.toString().equalsIgnoreCase(address)) { + return new ResponseData<>(hashValue, ErrorCode.SUCCESS, info); + } + } } - } catch (TimeoutException e) { - logger.error("create evidence failed due to system timeout. ", e); - return new ResponseData<>(StringUtils.EMPTY, ErrorCode.TRANSACTION_TIMEOUT); - } catch (InterruptedException | ExecutionException e) { - logger.error("create evidence failed due to transaction error. ", e); - return new ResponseData<>(StringUtils.EMPTY, ErrorCode.TRANSACTION_EXECUTE_ERROR); + return new ResponseData<>(StringUtils.EMPTY, + ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT); + } catch (Exception e) { + logger.error("create evidence failed due to system error. ", e); + return new ResponseData<>(StringUtils.EMPTY, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); } } + private static boolean isSignEvent(EvidenceAttributeChangedEventResponse event) { + return event.key.getValue().equalsIgnoreCase("info"); + } + + private static boolean isExtraEvent(EvidenceAttributeChangedEventResponse event) { + return event.key.getValue().equalsIgnoreCase("extra"); + } + /** - * Add signature to an evidence. + * Get an evidence full info. * - * @param sigData signature data - * @param privateKey private key - * @return true if succeeded, false otherwise + * @param hash evidence hash + * @return evidence info */ @Override - public ResponseData addSignature(Sign.SignatureData sigData, String privateKey, - String evidenceAddress) { - Evidence evidence = - reloadContract( - evidenceAddress, - privateKey, - Evidence.class - ); - Bytes32 r = DataToolUtils.bytesArrayToBytes32(sigData.getR()); - Bytes32 s = DataToolUtils.bytesArrayToBytes32(sigData.getS()); - Uint8 v = DataToolUtils.intToUnt8(Integer.valueOf(sigData.getV())); - Future future = evidence.addSignature(r, s, v); + public ResponseData getInfo(String hash) { + EvidenceInfo evidenceInfo = new EvidenceInfo(); + evidenceInfo.setCredentialHash(hash); + int latestBlockNumber = 0; try { - TransactionReceipt receipt = future.get( - WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, - TimeUnit.SECONDS); - TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = - Evidence.getAddSignatureLogEvents(receipt); - AddSignatureLogEventResponse event = eventResponseList.get(0); - if (event != null) { - if (event.retCode.getValue().intValue() - == ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT.getCode()) { - return new ResponseData<>(false, - ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT, info); - } - return new ResponseData<>(true, ErrorCode.SUCCESS, info); - } else { - logger.error( - "add signature failed due to transcation event decoding failure." - ); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + latestBlockNumber = DataToolUtils + .uint256ToInt(evidenceContract.getLatestRelatedBlock(new Utf8String(hash)) + .get(WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, TimeUnit.SECONDS)); + if (latestBlockNumber == 0) { + return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_NOT_EXIST); } - } catch (TimeoutException e) { - logger.error("add signature failed due to system timeout. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_TIMEOUT); - } catch (InterruptedException | ExecutionException e) { - logger.error("add signature failed due to transaction error. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_EXECUTE_ERROR); + resolveTransaction(hash, latestBlockNumber, evidenceInfo); + return new ResponseData<>(evidenceInfo, ErrorCode.SUCCESS); + } catch (Exception e) { + logger.error("get evidence failed.", e); + return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); } } - /** - * Set hash value an evidence. - * - * @param hashAttributes hash value - * @param privateKey private key - * @param evidenceAddress evidence address - * @return true if succeeded, false otherwise - */ - @Override - public ResponseData setHashValue(List hashAttributes, String privateKey, - String evidenceAddress) { - Evidence evidence = - reloadContract( - evidenceAddress, - privateKey, - Evidence.class - ); - Future future = evidence - .setHash(new DynamicArray(generateBytes32List(hashAttributes))); - try { - TransactionReceipt receipt = future.get( - WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, - TimeUnit.SECONDS); - TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = Evidence.getAddHashLogEvents(receipt); - AddHashLogEventResponse event = eventResponseList.get(0); - if (event != null) { - if (event.retCode.getValue().intValue() - == ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT.getCode()) { - return new ResponseData<>(false, - ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT, info); - } - return new ResponseData<>(true, ErrorCode.SUCCESS, info); - } else { + private static void resolveTransaction( + String hash, + int startBlockNumber, + EvidenceInfo evidenceInfo) { + + int previousBlock = startBlockNumber; + while (previousBlock != 0) { + int currentBlockNumber = previousBlock; + EthBlock latestBlock = null; + try { + latestBlock = ((Web3j) getWeb3j()).ethGetBlockByNumber( + new DefaultBlockParameterNumber(currentBlockNumber), true).send(); + } catch (IOException e) { logger.error( - "set hash value failed due to transaction event decoding failure." - ); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + "Get block by number:{} failed. Exception message:{}", currentBlockNumber, e); + } + if (latestBlock == null) { + logger.info("Get block by number:{}. latestBlock is null", currentBlockNumber); + return; + } + List transList = latestBlock + .getBlock() + .getTransactions() + .stream() + .map(transactionResult -> (Transaction) transactionResult.get()) + .collect(Collectors.toList()); + previousBlock = 0; + try { + for (Transaction transaction : transList) { + String transHash = transaction.getHash(); + + EthGetTransactionReceipt rec1 = ((Web3j) getWeb3j()) + .ethGetTransactionReceipt(transHash) + .send(); + TransactionReceipt receipt = rec1.getTransactionReceipt().get(); + List logs = rec1.getResult().getLogs(); + for (Log log : logs) { + ResolveEventLogResult returnValue = + resolveEventLog(hash, log, receipt, evidenceInfo); + if (returnValue.getResultStatus().equals( + ResolveEventLogStatus.STATUS_SUCCESS)) { + if (returnValue.getPreviousBlock() == currentBlockNumber) { + continue; + } + previousBlock = returnValue.getPreviousBlock(); + } + } + } + } catch (Exception e) { + logger.error("Get TransactionReceipt by key :{} failed.", hash, e); } - } catch (TimeoutException e) { - logger.error("add signature failed due to system timeout. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_TIMEOUT); - } catch (InterruptedException | ExecutionException e) { - logger.error("add signature failed due to transaction error. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_EXECUTE_ERROR); } } - private List generateBytes32List(List bytes32List) { - int desiredLength = bytes32List.size(); - List finalList = new ArrayList<>(); - for (int i = 0; i < desiredLength; i++) { - finalList.add(DataToolUtils.stringToBytes32(bytes32List.get(i))); + private static ResolveEventLogResult resolveEventLog( + String hash, + Log log, + TransactionReceipt receipt, + EvidenceInfo evidenceInfo) { + String topic = log.getTopics().get(0); + if (!StringUtils.isBlank(topic)) { + return resolveAttributeEvent(hash, receipt, evidenceInfo); } - return finalList; + ResolveEventLogResult response = new ResolveEventLogResult(); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_EVENT_NULL); + return response; } - /** - * Get an evidence info. - * - * @param evidenceAddress evidence addr - * @return evidence info - */ - @Override - public ResponseData getInfo(String evidenceAddress) { - try { - Evidence evidence = (Evidence) getContractService(evidenceAddress, Evidence.class); - List rawResult = - evidence.getInfo() - .get(WeIdConstant.TRANSACTION_RECEIPT_TIMEOUT, TimeUnit.SECONDS); + private static ResolveEventLogResult resolveAttributeEvent( + String hash, + TransactionReceipt receipt, + EvidenceInfo evidenceInfo) { + List eventList = + EvidenceContract.getEvidenceAttributeChangedEvents(receipt); + ResolveEventLogResult response = new ResolveEventLogResult(); - if (rawResult == null) { - return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } - List credentialHashList = ((DynamicArray) rawResult.get(0)) - .getValue(); - List
issuerList = ((DynamicArray
) rawResult.get(1)).getValue(); + if (CollectionUtils.isEmpty(eventList)) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_EVENTLOG_NULL); + return response; + } - EvidenceInfo evidenceInfoData = new EvidenceInfo(); - if (credentialHashList.size() < 1) { - evidenceInfoData.setCredentialHash(WeIdConstant.HEX_PREFIX); - } else { - evidenceInfoData.setCredentialHash( - WeIdConstant.HEX_PREFIX + DataToolUtils - .bytes32ToString(credentialHashList.get(0)) - + DataToolUtils.bytes32ToString(credentialHashList.get(1))); + int previousBlock = 0; + // Actual construction code + for (EvidenceAttributeChangedEventResponse event : eventList) { + if (event.signer == null || event.key == null || event.previousBlock == null) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_RES_NULL); + return response; } - List signerStringList = new ArrayList<>(); - for (Address addr : issuerList) { - signerStringList.add(WeIdUtils.convertAddressToWeId(addr.toString())); + if (!hash.equalsIgnoreCase(event.hash.getValue())) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); + return response; } - evidenceInfoData.setSigners(signerStringList); - - List signaturesList = new ArrayList<>(); - List rlist = ((DynamicArray) rawResult.get(2)).getValue(); - List slist = ((DynamicArray) rawResult.get(3)).getValue(); - List vlist = ((DynamicArray) rawResult.get(4)).getValue(); - byte v; - byte[] r; - byte[] s; - for (int index = 0; index < rlist.size(); index++) { - v = (byte) (vlist.get(index).getValue().intValue()); - r = rlist.get(index).getValue(); - s = slist.get(index).getValue(); - if ((int) v == 0) { - // skip empty signatures - continue; + String signerWeId = WeIdUtils.convertAddressToWeId(event.signer.toString()); + if (isSignEvent(event)) { + // higher block sig will be overwritten anyway - any new one will be accepted + EvidenceSignInfo signInfo = new EvidenceSignInfo(); + signInfo.setSignature(event.value.getValue()); + signInfo.setTimestamp(String.valueOf(DataToolUtils.uint256ToInt(event.updated))); + if (evidenceInfo.getSignInfo().containsKey(signerWeId)) { + signInfo.setExtraValue( + evidenceInfo.getSignInfo().get(signerWeId).getExtraValue()); } - SignatureData sigData = new SignatureData(v, r, s); - signaturesList.add( - new String( - DataToolUtils.base64Encode( - DataToolUtils.simpleSignatureSerialization(sigData) - ), - StandardCharsets.UTF_8 - ) - ); + evidenceInfo.getSignInfo().put(signerWeId, signInfo); + } + if (isExtraEvent(event)) { + // higher block blob will overwrite existing one - any new one will be abandoned + EvidenceSignInfo signInfo = new EvidenceSignInfo(); + if (evidenceInfo.getSignInfo().containsKey(signerWeId)) { + signInfo.setSignature( + evidenceInfo.getSignInfo().get(signerWeId).getSignature()); + signInfo.setTimestamp( + evidenceInfo.getSignInfo().get(signerWeId).getTimestamp()); + } else { + signInfo.setSignature(StringUtils.EMPTY); + signInfo.setTimestamp(StringUtils.EMPTY); + } + Map newBlob; + try { + newBlob = DataToolUtils.deserialize(URLDecoder.decode(event.value.getValue(), + StandardCharsets.UTF_8.name()), HashMap.class); + } catch (Exception e) { + logger.error("Failed to decode and deserialize extra value: {}", event.value); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); + return response; + } + Map oldBlob = evidenceInfo.getSignInfo().get(signerWeId) + .getExtraValue(); + if (oldBlob == null || oldBlob.isEmpty()) { + oldBlob = new HashMap<>(); + } + // Iterate each key in the new blob. If it is already in the old one, abandon. + for (Map.Entry entry : newBlob.entrySet()) { + if (!oldBlob.containsKey(entry.getKey())) { + oldBlob.put(entry.getKey(), entry.getValue()); + } + } + signInfo.setExtraValue(oldBlob); + evidenceInfo.getSignInfo().put(signerWeId, signInfo); } - evidenceInfoData.setSignatures(signaturesList); - return new ResponseData<>(evidenceInfoData, ErrorCode.SUCCESS); - } catch (TimeoutException e) { - logger.error("create evidence failed due to system timeout. ", e); - return new ResponseData<>(null, ErrorCode.TRANSACTION_TIMEOUT); - } catch (InterruptedException | ExecutionException e) { - logger.error("create evidence failed due to transaction error. ", e); - return new ResponseData<>(null, ErrorCode.TRANSACTION_EXECUTE_ERROR); + previousBlock = DataToolUtils.uint256ToInt(event.previousBlock); } + response.setPreviousBlock(previousBlock); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_SUCCESS); + return response; } } diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/WeIdServiceEngineV1.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/WeIdServiceEngineV1.java index d8a74577e..0cb736b9d 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov1/WeIdServiceEngineV1.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov1/WeIdServiceEngineV1.java @@ -152,7 +152,7 @@ private static ResolveEventLogResult resolveAttributeEvent( } String weAddress = WeIdUtils.convertWeIdToAddress(weId); if (!StringUtils.equals(weAddress, identity)) { - response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_WEID_NOT_MATCH); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); return response; } diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/CptServiceEngineV2.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/CptServiceEngineV2.java index 165a5bb54..296574be6 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/CptServiceEngineV2.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/CptServiceEngineV2.java @@ -84,7 +84,7 @@ public class CptServiceEngineV2 extends BaseEngine implements CptServiceEngine { private static final String CREDENTIAL_TEMPLATE_EVENT = EventEncoder .encode(CptController.CREDENTIALTEMPLATE_EVENT); private static CptController cptController; - private static Persistence dataDriver = new MysqlDriver(); + private static Persistence dataDriver; static { @@ -93,6 +93,13 @@ public class CptServiceEngineV2 extends BaseEngine implements CptServiceEngine { } } + private static Persistence getDataDriver() { + if (dataDriver == null) { + dataDriver = new MysqlDriver(); + } + return dataDriver; + } + /* (non-Javadoc) * @see com.webank.weid.service.impl.engine.CptEngineController * #updateCpt(int, java.lang.String, java.lang.String, @@ -252,7 +259,7 @@ public ResponseData registerCpt( private ErrorCode processTemplate(Integer cptId, String cptJsonSchemaNew) { //if the cpt is not zkp type, no need to make template. - if (!CredentialPojoUtils.isZkpCpt(cptId)) { + if (!CredentialPojoUtils.isZkpCpt(cptJsonSchemaNew)) { return ErrorCode.SUCCESS; } List attributeList; @@ -262,7 +269,7 @@ private ErrorCode processTemplate(Integer cptId, String cptJsonSchemaNew) { CredentialTemplateEntity template = issuerResult.credentialTemplateEntity; String templateSecretKey = issuerResult.templateSecretKey; ResponseData resp = - dataDriver.saveOrUpdate( + getDataDriver().saveOrUpdate( DataDriverConstant.DOMAIN_ISSUER_TEMPLATE_SECRET, String.valueOf(cptId), templateSecretKey); diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/EvidenceServiceEngineV2.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/EvidenceServiceEngineV2.java index ac48ad995..c51a402c7 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/EvidenceServiceEngineV2.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/EvidenceServiceEngineV2.java @@ -19,29 +19,34 @@ package com.webank.weid.service.impl.engine.fiscov2; +import java.io.IOException; import java.math.BigInteger; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; -import org.bcos.web3j.crypto.ECKeyPair; -import org.bcos.web3j.crypto.Keys; -import org.bcos.web3j.crypto.Sign; -import org.bcos.web3j.crypto.Sign.SignatureData; +import org.fisco.bcos.web3j.protocol.Web3j; +import org.fisco.bcos.web3j.protocol.core.DefaultBlockParameterNumber; +import org.fisco.bcos.web3j.protocol.core.methods.response.BcosBlock; +import org.fisco.bcos.web3j.protocol.core.methods.response.BcosTransactionReceipt; +import org.fisco.bcos.web3j.protocol.core.methods.response.Log; +import org.fisco.bcos.web3j.protocol.core.methods.response.Transaction; import org.fisco.bcos.web3j.protocol.core.methods.response.TransactionReceipt; -import org.fisco.bcos.web3j.tuples.generated.Tuple6; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webank.weid.constant.ErrorCode; -import com.webank.weid.constant.WeIdConstant; -import com.webank.weid.contract.v2.Evidence; -import com.webank.weid.contract.v2.Evidence.AddHashLogEventResponse; -import com.webank.weid.contract.v2.Evidence.AddSignatureLogEventResponse; -import com.webank.weid.contract.v2.EvidenceFactory; -import com.webank.weid.contract.v2.EvidenceFactory.CreateEvidenceLogEventResponse; +import com.webank.weid.constant.ResolveEventLogStatus; +import com.webank.weid.contract.v2.EvidenceContract; +import com.webank.weid.contract.v2.EvidenceContract.EvidenceAttributeChangedEventResponse; import com.webank.weid.protocol.base.EvidenceInfo; +import com.webank.weid.protocol.base.EvidenceSignInfo; +import com.webank.weid.protocol.response.ResolveEventLogResult; import com.webank.weid.protocol.response.ResponseData; import com.webank.weid.protocol.response.TransactionInfo; import com.webank.weid.service.impl.engine.BaseEngine; @@ -58,245 +63,232 @@ public class EvidenceServiceEngineV2 extends BaseEngine implements EvidenceServi private static final Logger logger = LoggerFactory.getLogger(EvidenceServiceEngineV2.class); - /** - * Create Evidence on a FISCO-BCOS 2.x blockchain. - * - * @param sigData signature data - * @param hashAttributes hash value - * @param extraValueList extra value - * @param privateKey private key - * @param signerList declared signers - * @return evidence address - */ + private static EvidenceContract evidenceContract = getContractService( + fiscoConfig.getEvidenceAddress(), + EvidenceContract.class); + @Override public ResponseData createEvidence( - Sign.SignatureData sigData, - List hashAttributes, - List extraValueList, - String privateKey, - List signerList + String hashValue, + String signature, + String extra, + Long timestamp, + String privateKey ) { try { - List hashAttributesByte = new ArrayList<>(); - for (String hashValue : hashAttributes) { - hashAttributesByte.add(DataToolUtils.stringToByte32Array(hashValue)); - } - List extraValueListByte = new ArrayList<>(); - for (String extraValue : extraValueList) { - extraValueListByte.add(DataToolUtils.stringToByte32Array(extraValue)); - } - List signer = new ArrayList<>(); - if (signerList == null || signerList.size() == 0) { - // Evidence has only one signer - default to be the WeID behind the private key - ECKeyPair keyPair = ECKeyPair.create(new BigInteger(privateKey)); - signer.add(Keys.getAddress(keyPair)); - } else { - // Evidence has a pre-defined signer list - for (String signerWeId : signerList) { - signer.add(WeIdUtils.convertWeIdToAddress(signerWeId)); - } - } - - EvidenceFactory evidenceFactory = + EvidenceContract evidenceContractWriter = reloadContract( fiscoConfig.getEvidenceAddress(), privateKey, - EvidenceFactory.class + EvidenceContract.class ); TransactionReceipt receipt = - evidenceFactory.createEvidence( - hashAttributesByte, - signer, - sigData.getR(), - sigData.getS(), - BigInteger.valueOf(sigData.getV()), - extraValueListByte + evidenceContractWriter.createEvidence( + hashValue, + signature, + extra, + new BigInteger(String.valueOf(timestamp), 10) ).send(); TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = - evidenceFactory.getCreateEvidenceLogEvents(receipt); - CreateEvidenceLogEventResponse event = eventResponseList.get(0); - - if (event != null) { - ErrorCode innerResponse = verifyCreateEvidenceEvent(event.retCode.intValue(), - event.addr); - if (ErrorCode.SUCCESS.getCode() != innerResponse.getCode()) { - return new ResponseData<>(StringUtils.EMPTY, innerResponse, info); - } - return new ResponseData<>(event.addr.toString(), ErrorCode.SUCCESS, info); - } else { - logger.error( - "create evidence failed due to transcation event decoding failure." - ); + List eventList = + evidenceContractWriter.getEvidenceAttributeChangedEvents(receipt); + if (eventList == null || eventList.isEmpty()) { return new ResponseData<>(StringUtils.EMPTY, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + } else { + String address = WeIdUtils + .convertWeIdToAddress(DataToolUtils.convertPrivateKeyToDefaultWeId(privateKey)); + for (EvidenceAttributeChangedEventResponse event : eventList) { + if (isSignEvent(event) && event.value.equalsIgnoreCase(signature) + && event.signer.equalsIgnoreCase(address)) { + return new ResponseData<>(hashValue, ErrorCode.SUCCESS, info); + } + } } + return new ResponseData<>(StringUtils.EMPTY, + ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT); } catch (Exception e) { logger.error("create evidence failed due to system error. ", e); return new ResponseData<>(StringUtils.EMPTY, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); } } + private static boolean isSignEvent(EvidenceAttributeChangedEventResponse event) { + return event.key.equalsIgnoreCase("info"); + } + + private static boolean isExtraEvent(EvidenceAttributeChangedEventResponse event) { + return event.key.equalsIgnoreCase("extra"); + } /** - * Add signature to an evidence. + * Get an evidence full info. * - * @param sigData signature data - * @param privateKey private key - * @return true if succeeded, false otherwise + * @param hash evidence hash + * @return evidence info */ @Override - public ResponseData addSignature(Sign.SignatureData sigData, String privateKey, - String evidenceAddress) { - Evidence evidence = - reloadContract( - evidenceAddress, - privateKey, - Evidence.class - ); + public ResponseData getInfo(String hash) { + EvidenceInfo evidenceInfo = new EvidenceInfo(); + evidenceInfo.setCredentialHash(hash); + int latestBlockNumber = 0; try { - TransactionReceipt receipt = evidence - .addSignature(sigData.getR(), sigData.getS(), BigInteger.valueOf(sigData.getV())) - .send(); - TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = - evidence.getAddSignatureLogEvents(receipt); - AddSignatureLogEventResponse event = eventResponseList.get(0); - if (event != null) { - if (event.retCode.intValue() - == ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT.getCode()) { - return new ResponseData<>(false, - ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT, info); - } - return new ResponseData<>(true, ErrorCode.SUCCESS, info); - } else { - logger.error( - "add signature failed due to transcation event decoding failure." - ); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + latestBlockNumber = evidenceContract.getLatestRelatedBlock(hash).send().intValue(); + if (latestBlockNumber == 0) { + return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_NOT_EXIST); } + resolveTransaction(hash, latestBlockNumber, evidenceInfo); + return new ResponseData<>(evidenceInfo, ErrorCode.SUCCESS); } catch (Exception e) { - logger.error("add signature failed due to transaction error. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_EXECUTE_ERROR); + logger.error("get evidence failed.", e); + return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); } } - /** - * Set hash value an evidence. - * - * @param hashAttributes hash value - * @param privateKey private key - * @param evidenceAddress evidence address - * @return true if succeeded, false otherwise - */ - @Override - public ResponseData setHashValue(List hashAttributes, String privateKey, - String evidenceAddress) { - Evidence evidence = - reloadContract( - evidenceAddress, - privateKey, - Evidence.class - ); - try { - List hashAttributesByte = new ArrayList<>(); - for (String hashValue : hashAttributes) { - hashAttributesByte.add(DataToolUtils.stringToByte32Array(hashValue)); + private static void resolveTransaction( + String hash, + int startBlockNumber, + EvidenceInfo evidenceInfo) { + + int previousBlock = startBlockNumber; + while (previousBlock != 0) { + int currentBlockNumber = previousBlock; + BcosBlock latestBlock = null; + try { + latestBlock = ((Web3j) getWeb3j()).getBlockByNumber( + new DefaultBlockParameterNumber(currentBlockNumber), true).send(); + } catch (IOException e) { + logger.error( + "Get block by number:{} failed. Exception message:{}", currentBlockNumber, e); } - TransactionReceipt receipt = evidence.setHash(hashAttributesByte).send(); - TransactionInfo info = new TransactionInfo(receipt); - List eventResponseList = evidence.getAddHashLogEvents(receipt); - AddHashLogEventResponse event = eventResponseList.get(0); - if (event != null) { - if (event.retCode.intValue() - == ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT.getCode()) { - return new ResponseData<>(false, - ErrorCode.CREDENTIAL_EVIDENCE_CONTRACT_FAILURE_ILLEAGAL_INPUT, info); + if (latestBlock == null) { + logger.info("Get block by number:{}. latestBlock is null", currentBlockNumber); + return; + } + List transList = latestBlock + .getBlock() + .getTransactions() + .stream() + .map(transactionResult -> (Transaction) transactionResult.get()) + .collect(Collectors.toList()); + previousBlock = 0; + try { + for (Transaction transaction : transList) { + String transHash = transaction.getHash(); + + BcosTransactionReceipt rec1 = ((Web3j) getWeb3j()) + .getTransactionReceipt(transHash) + .send(); + TransactionReceipt receipt = rec1.getTransactionReceipt().get(); + List logs = rec1.getResult().getLogs(); + for (Log log : logs) { + ResolveEventLogResult returnValue = + resolveEventLog(hash, log, receipt, evidenceInfo); + if (returnValue.getResultStatus().equals( + ResolveEventLogStatus.STATUS_SUCCESS)) { + if (returnValue.getPreviousBlock() == currentBlockNumber) { + continue; + } + previousBlock = returnValue.getPreviousBlock(); + } + } } - return new ResponseData<>(true, ErrorCode.SUCCESS, info); - } else { - logger.error( - "set hash value failed due to transcation event decoding failure." - ); - return new ResponseData<>(false, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR, info); + } catch (Exception e) { + logger.error("Get TransactionReceipt by key :{} failed.", hash, e); } - } catch (Exception e) { - logger.error("add signature failed due to transaction error. ", e); - return new ResponseData<>(false, ErrorCode.TRANSACTION_EXECUTE_ERROR); } } - /** - * Get an evidence full info. - * - * @param evidenceAddress evidence addr - * @return evidence info - */ - @Override - public ResponseData getInfo(String evidenceAddress) { - try { - Evidence evidence = (Evidence) getContractService(evidenceAddress, Evidence.class); - Tuple6< - List, - List, - List, - List, - List, - List - > rawResult = evidence.getInfo().send(); - if (rawResult == null) { - return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); - } + private static ResolveEventLogResult resolveEventLog( + String hash, + Log log, + TransactionReceipt receipt, + EvidenceInfo evidenceInfo) { + String topic = log.getTopics().get(0); + if (!StringUtils.isBlank(topic)) { + return resolveAttributeEvent(hash, receipt, evidenceInfo); + } + ResolveEventLogResult response = new ResolveEventLogResult(); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_EVENT_NULL); + return response; + } - List credentialHashList = rawResult.getValue1(); - List issuerList = rawResult.getValue2(); + private static ResolveEventLogResult resolveAttributeEvent( + String hash, + TransactionReceipt receipt, + EvidenceInfo evidenceInfo) { + List eventList = + evidenceContract.getEvidenceAttributeChangedEvents(receipt); + ResolveEventLogResult response = new ResolveEventLogResult(); - EvidenceInfo evidenceInfoData = new EvidenceInfo(); - if (credentialHashList.size() < 1) { - evidenceInfoData.setCredentialHash(WeIdConstant.HEX_PREFIX); - } else { - evidenceInfoData.setCredentialHash( - WeIdConstant.HEX_PREFIX + new String(credentialHashList.get(0)).trim() - + new String(credentialHashList.get(1)).trim()); - } + if (CollectionUtils.isEmpty(eventList)) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_EVENTLOG_NULL); + return response; + } - List signerStringList = new ArrayList<>(); - for (String addr : issuerList) { - signerStringList.add(WeIdUtils.convertAddressToWeId(addr)); + int previousBlock = 0; + // Actual construction code + for (EvidenceAttributeChangedEventResponse event : eventList) { + if (event.signer == null || event.key == null || event.previousBlock == null) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_RES_NULL); + return response; } - evidenceInfoData.setSigners(signerStringList); - - List signaturesList = new ArrayList<>(); - List rlist = rawResult.getValue3(); - List slist = rawResult.getValue4(); - List vlist = rawResult.getValue5(); - byte v; - byte[] r; - byte[] s; - for (int index = 0; index < rlist.size(); index++) { - v = (byte) (vlist.get(index).intValue()); - r = rlist.get(index); - s = slist.get(index); - if ((int) v == 0) { - // skip empty signatures - continue; + if (!hash.equalsIgnoreCase(event.hash)) { + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); + return response; + } + String signerWeId = WeIdUtils.convertAddressToWeId(event.signer); + if (isSignEvent(event)) { + // higher block sig will be overwritten anyway - any new one will be accepted + EvidenceSignInfo signInfo = new EvidenceSignInfo(); + signInfo.setSignature(event.value); + signInfo.setTimestamp(String.valueOf(event.updated.longValue())); + if (evidenceInfo.getSignInfo().containsKey(signerWeId)) { + signInfo.setExtraValue( + evidenceInfo.getSignInfo().get(signerWeId).getExtraValue()); } - SignatureData sigData = new SignatureData(v, r, s); - signaturesList.add( - new String( - DataToolUtils.base64Encode( - DataToolUtils.simpleSignatureSerialization(sigData) - ), - StandardCharsets.UTF_8 - ) - ); + evidenceInfo.getSignInfo().put(signerWeId, signInfo); } - evidenceInfoData.setSignatures(signaturesList); - return new ResponseData<>(evidenceInfoData, ErrorCode.SUCCESS); - } catch (Exception e) { - logger.error("get evidence failed.", e); - return new ResponseData<>(null, ErrorCode.CREDENTIAL_EVIDENCE_BASE_ERROR); + if (isExtraEvent(event)) { + // higher block blob will overwrite existing one - any new one will be abandoned + EvidenceSignInfo signInfo = new EvidenceSignInfo(); + if (evidenceInfo.getSignInfo().containsKey(signerWeId)) { + signInfo.setSignature( + evidenceInfo.getSignInfo().get(signerWeId).getSignature()); + signInfo.setTimestamp( + evidenceInfo.getSignInfo().get(signerWeId).getTimestamp()); + } else { + signInfo.setSignature(StringUtils.EMPTY); + signInfo.setTimestamp(StringUtils.EMPTY); + } + Map newBlob; + try { + newBlob = DataToolUtils.deserialize(URLDecoder.decode(event.value, + StandardCharsets.UTF_8.name()), HashMap.class); + } catch (Exception e) { + logger.error("Failed to decode and deserialize extra value: {}", event.value); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); + return response; + } + Map oldBlob = evidenceInfo.getSignInfo().get(signerWeId) + .getExtraValue(); + if (oldBlob == null || oldBlob.isEmpty()) { + oldBlob = new HashMap<>(); + } + // Iterate each key in the new blob. If it is already in the old one, abandon. + for (Map.Entry entry : newBlob.entrySet()) { + if (!oldBlob.containsKey(entry.getKey())) { + oldBlob.put(entry.getKey(), entry.getValue()); + } + } + signInfo.setExtraValue(oldBlob); + evidenceInfo.getSignInfo().put(signerWeId, signInfo); + } + previousBlock = event.previousBlock.intValue(); } + response.setPreviousBlock(previousBlock); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_SUCCESS); + return response; } } diff --git a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/WeIdServiceEngineV2.java b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/WeIdServiceEngineV2.java index 9d4a403dd..ceb6208a5 100644 --- a/src/main/java/com/webank/weid/service/impl/engine/fiscov2/WeIdServiceEngineV2.java +++ b/src/main/java/com/webank/weid/service/impl/engine/fiscov2/WeIdServiceEngineV2.java @@ -126,7 +126,7 @@ private static ResolveEventLogResult resolveAttributeEvent( } String weAddress = WeIdUtils.convertWeIdToAddress(weId); if (!StringUtils.equals(weAddress, identity)) { - response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_WEID_NOT_MATCH); + response.setResolveEventLogStatus(ResolveEventLogStatus.STATUS_KEY_NOT_MATCH); return response; } diff --git a/src/main/java/com/webank/weid/suite/api/transportation/inf/PdfTransportation.java b/src/main/java/com/webank/weid/suite/api/transportation/inf/PdfTransportation.java index 3013e8ec6..5ee0fbcee 100644 --- a/src/main/java/com/webank/weid/suite/api/transportation/inf/PdfTransportation.java +++ b/src/main/java/com/webank/weid/suite/api/transportation/inf/PdfTransportation.java @@ -19,13 +19,13 @@ package com.webank.weid.suite.api.transportation.inf; -import java.io.OutputStream; import java.util.List; import com.webank.weid.protocol.base.WeIdAuthentication; import com.webank.weid.protocol.inf.JsonSerializer; import com.webank.weid.protocol.response.ResponseData; import com.webank.weid.suite.api.transportation.params.ProtocolProperty; +import com.webank.weid.suite.transportation.pdf.protocol.PdfAttributeInfo; /** * PDF序列化工具,支持明文和加密两种方式. @@ -49,13 +49,11 @@ public interface PdfTransportation { * @param object 协议存储的实体数据对象 * @param the type of the element * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 * @return 序列化以后生成PDF文件的byte[] */ ResponseData serialize( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication + T object, + ProtocolProperty property ); /** @@ -64,19 +62,16 @@ ResponseData serialize( * * @param object 协议存储的实体数据对象 * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 * @param outputPdfFilePath 输出PDF文件的路径 * @param the type of the element * @return 序列化结果 */ ResponseData serialize( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String outputPdfFilePath + T object, + ProtocolProperty property, + String outputPdfFilePath ); - /** * 协议传输序列化接口. 此方法会将presentation按PDF模板的样式数据序列化为PDF文件,PDF文件的内容为claim表单, * presentation和协议头会放到自定义属性里。 @@ -84,15 +79,13 @@ ResponseData serialize( * @param object 协议存储的实体数据对象 * @param the type of the element * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 * @param inputPdfTemplatePath presentation的PDF模板 * @return byte[] 序列化以后生成PDF文件的byte[] */ ResponseData serializeWithTemplate( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String inputPdfTemplatePath + T object, + ProtocolProperty property, + String inputPdfTemplatePath ); /** @@ -101,18 +94,16 @@ ResponseData serializeWithTemplate( * * @param object 协议存储的实体数据对象 * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 * @param inputPdfTemplatePath presentation的PDF模板 * @param outputPdfFilePath 输出PDF文件的路径 * @param the type of the element * @return 序列化结果 */ ResponseData serializeWithTemplate( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String inputPdfTemplatePath, - String outputPdfFilePath + T object, + ProtocolProperty property, + String inputPdfTemplatePath, + String outputPdfFilePath ); /** @@ -126,8 +117,33 @@ ResponseData serializeWithTemplate( * @return 返回PresentationE对象数据 */ ResponseData deserialize( - byte[] pdfTransportation, - Class clazz, - WeIdAuthentication weIdAuthentication + byte[] pdfTransportation, + Class clazz, + WeIdAuthentication weIdAuthentication + ); + + /** + * 验证两个pdf的信息是否一致. + * + * @param object presentation + * @param pdfTemplatePath pdf模板路径 + * @param pdfAttributeInfo pdf基本信息 + * @param serializePdf 序列化生成包含pdf信息的byte数组 + * @param JsonSerializer + * @return 返回两个结果是否一致 + */ + Boolean verifyPdf( + T object, + String pdfTemplatePath, + PdfAttributeInfo pdfAttributeInfo, + byte[] serializePdf ); + + /** + * 通过pdf的byte数组获取PdfBaseData. + * + * @param pdfTransportation 包含pdf信息的byte数组 + * @return pdf基本信息 + */ + PdfAttributeInfo getBaseData(byte[] pdfTransportation); } diff --git a/src/main/java/com/webank/weid/suite/transportation/pdf/impl/PdfTransportationImpl.java b/src/main/java/com/webank/weid/suite/transportation/pdf/impl/PdfTransportationImpl.java index 90949a2d9..8018314f5 100644 --- a/src/main/java/com/webank/weid/suite/transportation/pdf/impl/PdfTransportationImpl.java +++ b/src/main/java/com/webank/weid/suite/transportation/pdf/impl/PdfTransportationImpl.java @@ -27,6 +27,7 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.LinkedHashMap; @@ -50,20 +51,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.webank.weid.constant.CredentialConstant; import com.webank.weid.constant.ErrorCode; import com.webank.weid.exception.WeIdBaseException; import com.webank.weid.protocol.base.Cpt; import com.webank.weid.protocol.base.CredentialPojo; import com.webank.weid.protocol.base.CredentialPojoList; -import com.webank.weid.protocol.base.HashString; import com.webank.weid.protocol.base.PresentationE; import com.webank.weid.protocol.base.WeIdAuthentication; import com.webank.weid.protocol.inf.JsonSerializer; import com.webank.weid.protocol.response.ResponseData; import com.webank.weid.rpc.CptService; -import com.webank.weid.rpc.EvidenceService; import com.webank.weid.service.impl.CptServiceImpl; -import com.webank.weid.service.impl.EvidenceServiceImpl; import com.webank.weid.suite.api.transportation.inf.PdfTransportation; import com.webank.weid.suite.api.transportation.params.EncodeType; import com.webank.weid.suite.api.transportation.params.ProtocolProperty; @@ -71,16 +70,15 @@ import com.webank.weid.suite.entity.EncodeData; import com.webank.weid.suite.entity.PdfVersion; import com.webank.weid.suite.transportation.AbstractPdfTransportation; -import com.webank.weid.suite.transportation.pdf.protocol.PdfBaseData; +import com.webank.weid.suite.transportation.pdf.protocol.PdfAttributeInfo; import com.webank.weid.util.DataToolUtils; public class PdfTransportationImpl - extends AbstractPdfTransportation - implements PdfTransportation { + extends AbstractPdfTransportation + implements PdfTransportation { - private static final Logger logger = - LoggerFactory.getLogger(PdfTransportationImpl.class); + private static final Logger logger = LoggerFactory.getLogger(PdfTransportationImpl.class); private static final PdfVersion version = PdfVersion.V1; @@ -106,10 +104,14 @@ public class PdfTransportationImpl private static final String FILE_SEPARATOR = "."; - private static CptService cptService = new CptServiceImpl(); - - private static EvidenceService evidenceService = new EvidenceServiceImpl(); + private static final String PDF_ATTRIBUTE_ID = "id"; + private static final String PDF_ATTRIBUTE_ORG_ID = "orgId"; + private static final String PDF_ATTRIBUTE_DATA = "data"; + private static final String PDF_ATTRIBUTE_ENCODE_TYPE = "encodeType"; + private static final String PDF_ATTRIBUTE_VERSION = "version"; + private static final String PDF_ATTRIBUTE_TEMPLATE_ID = "pdfTemplateId"; + private static CptService cptService = new CptServiceImpl(); /** * 根据Claim和Salt把需要显示的数据写入到disclosureInfo中. @@ -122,12 +124,12 @@ public class PdfTransportationImpl * @param isSpecTpl 是否是指定pdf模板情况 */ private void buildDisclosureInfo( - LinkedHashMap disclosureInfo, - Map salt, - Map claim, - StringBuilder prefix, - Map propMap, - Boolean isSpecTpl) throws WeIdBaseException { + LinkedHashMap disclosureInfo, + Map salt, + Map claim, + StringBuilder prefix, + Map propMap, + Boolean isSpecTpl) throws WeIdBaseException { if (salt == null) { logger.error("buildDisclosureInfo due to salt illegal error."); @@ -163,14 +165,16 @@ private void buildDisclosureInfo( if (saltV instanceof Map) { //判断name是否存在 if (propMapV != null) { - if (isSpecTpl || !propMapV.containsKey("name") - || String.valueOf(propMapV.get("name")).equals("")) { + if (isSpecTpl + || !propMapV.containsKey("name") + || String.valueOf(propMapV.get("name")).equals("")) { prefix.append(entry.getKey()); } else { prefix.append(propMapV.get("name")); } } else { - logger.error("buildDisclosureInfo duo to " + logger.error( + "buildDisclosureInfo duo to " + "map type cpt missing properties, propMapV is null error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } @@ -187,12 +191,13 @@ private void buildDisclosureInfo( //递归处理多层Map buildDisclosureInfo( - disclosureInfo, - (HashMap) saltV, - (HashMap) claimV, - prefix, - certProp, - isSpecTpl); + disclosureInfo, + (HashMap) saltV, + (HashMap) claimV, + prefix, + certProp, + isSpecTpl + ); stringTools(prefix); //2. 如果claim为List则根据List内部结构来处理 @@ -210,8 +215,8 @@ private void buildDisclosureInfo( int i = 0; //判断name是否存在 if (isSpecTpl - || !propMapV.containsKey("name") - || String.valueOf(propMapV.get("name")).equals("")) { + || !propMapV.containsKey("name") + || String.valueOf(propMapV.get("name")).equals("")) { prefix.insert(0, entry.getKey()); } else { prefix.insert(0, propMapV.get("name")); @@ -220,12 +225,12 @@ private void buildDisclosureInfo( //处理List结构的claim buildDisclosureInfoByList( - disclosureInfo, - (ArrayList) saltV, - (ArrayList) claimV, - prefix, - itemsProp, - isSpecTpl + disclosureInfo, + (ArrayList) saltV, + (ArrayList) claimV, + prefix, + itemsProp, + isSpecTpl ); //3. 如果claim为单层Map则直接处理 @@ -238,13 +243,13 @@ private void buildDisclosureInfo( //判断name是否存在 try { if (isSpecTpl - || !propMapV.containsKey("name") - || String.valueOf(propMapV.get("name")).equals("")) { + || !propMapV.containsKey("name") + || String.valueOf(propMapV.get("name")).equals("")) { disclosureInfo.put(prefix + entry.getKey(), String.valueOf(claimV)); } else { disclosureInfo.put( - prefix + String.valueOf(propMapV.get("name")), - String.valueOf(claimV)); + prefix + String.valueOf(propMapV.get("name")), + String.valueOf(claimV)); } } catch (WeIdBaseException e) { logger.error("buildDisclosureInfo due to get name error.", e); @@ -289,12 +294,12 @@ private void stringTools(StringBuilder prefix) { * @param items CPT中List类型获取Properties */ private void buildDisclosureInfoByList( - LinkedHashMap disclosureInfo, - List salt, - List claim, - StringBuilder prefix, - Map items, - Boolean isSpecTpl) throws WeIdBaseException { + LinkedHashMap disclosureInfo, + List salt, + List claim, + StringBuilder prefix, + Map items, + Boolean isSpecTpl) throws WeIdBaseException { try { //传入的salt就是List,需要遍历每一个salt[i] @@ -305,21 +310,21 @@ private void buildDisclosureInfoByList( if (saltObj instanceof Map) { //List里面是Map buildDisclosureInfo( - disclosureInfo, - (HashMap) saltObj, - (HashMap) claimObj, - prefix, - items, - isSpecTpl); + disclosureInfo, + (HashMap) saltObj, + (HashMap) claimObj, + prefix, + items, + isSpecTpl); } else if (saltObj instanceof List) { //List里面是List,就一直递归直到是Map buildDisclosureInfoByList( - disclosureInfo, - (ArrayList) saltObj, - (ArrayList) claimObj, - prefix, - items, - isSpecTpl); + disclosureInfo, + (ArrayList) saltObj, + (ArrayList) claimObj, + prefix, + items, + isSpecTpl); } prefix.replace(0, prefix.length(), prefix.substring(0, prefix.length() - 3)); prefix.append(i + 1).append("]").append("-"); @@ -359,9 +364,10 @@ private float calcStrLength(String str, int fontSize, PDFont font) throws WeIdBa * @param lines 处理后存储结果的ArrayList */ private void buildLines( - String output, int fontSize, - PDFont font, - ArrayList lines) throws WeIdBaseException { + String output, + int fontSize, + PDFont font, + ArrayList lines) throws WeIdBaseException { try { String str; @@ -392,12 +398,12 @@ private void buildLines( * @param lines 存有多行字符串的ArrayList */ private void addMultiLine2Pdf( - int lineSize, - PDPageContentStream contents, - int fontSize, - PDFont font, - float pos, - ArrayList lines) { + int lineSize, + PDPageContentStream contents, + int fontSize, + PDFont font, + float pos, + ArrayList lines) { String text; for (int j = 0; j < lineSize; j++) { @@ -408,12 +414,12 @@ private void addMultiLine2Pdf( } private void addContent( - PDPageContentStream contents, - String text, - float posX, - float posY, - PDFont font, - int fontSize) { + PDPageContentStream contents, + String text, + float posX, + float posY, + PDFont font, + int fontSize) { try { contents.beginText(); @@ -430,33 +436,38 @@ private void addContent( /** * 为PDF添加属性信息. * @param document 当前PDF - * @param pdfBaseData PDF协议数据 + * @param pdfAttributeInfo PDF协议数据 */ - private void addAttributeInfo(PDDocument document, PdfBaseData pdfBaseData) { + private void addAttributeInfo(PDDocument document, PdfAttributeInfo pdfAttributeInfo) { PDDocumentInformation pdd = document.getDocumentInformation(); - pdd.setCustomMetadataValue("id", pdfBaseData.getId()); - pdd.setCustomMetadataValue("orgId", pdfBaseData.getOrgId()); - pdd.setCustomMetadataValue("data", String.valueOf(pdfBaseData.getData())); - pdd.setCustomMetadataValue("encodeType", String.valueOf(pdfBaseData.getEncodeType())); - pdd.setCustomMetadataValue("version", String.valueOf(pdfBaseData.getVersion())); - pdd.setCustomMetadataValue("address", String.valueOf(pdfBaseData.getAddress())); + pdd.setCustomMetadataValue(PDF_ATTRIBUTE_ID, pdfAttributeInfo.getId()); + pdd.setCustomMetadataValue(PDF_ATTRIBUTE_ORG_ID, pdfAttributeInfo.getOrgId()); + pdd.setCustomMetadataValue(PDF_ATTRIBUTE_DATA, String.valueOf(pdfAttributeInfo.getData())); + pdd.setCustomMetadataValue( + PDF_ATTRIBUTE_ENCODE_TYPE, String.valueOf(pdfAttributeInfo.getEncodeType())); + pdd.setCustomMetadataValue( + PDF_ATTRIBUTE_VERSION, String.valueOf(pdfAttributeInfo.getVersion())); + pdd.setCustomMetadataValue( + PDF_ATTRIBUTE_TEMPLATE_ID, String.valueOf(pdfAttributeInfo.getTemplateId())); } /** * 将PDF中的属性信息解析到PdfBaseData数据结构中. * * @param pdd PDF属性信息 - * @param pdfBaseData PDF协议数据 + * @param pdfAttributeInfo PDF协议数据 */ - private void buildPdfDataFromPdf(PDDocumentInformation pdd, PdfBaseData pdfBaseData) { - - pdfBaseData.setId(pdd.getCustomMetadataValue("id")); - pdfBaseData.setOrgId(pdd.getCustomMetadataValue("orgId")); - pdfBaseData.setData(pdd.getCustomMetadataValue("data")); - pdfBaseData.setEncodeType(Integer.parseInt(pdd.getCustomMetadataValue("encodeType"))); - pdfBaseData.setVersion(Integer.parseInt(pdd.getCustomMetadataValue("version"))); - pdfBaseData.setAddress(pdd.getCustomMetadataValue("address")); + private void buildPdfDataFromPdf(PDDocumentInformation pdd, PdfAttributeInfo pdfAttributeInfo) { + + pdfAttributeInfo.setId(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_ID)); + pdfAttributeInfo.setOrgId(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_ORG_ID)); + pdfAttributeInfo.setData(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_DATA)); + pdfAttributeInfo.setEncodeType( + Integer.parseInt(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_ENCODE_TYPE))); + pdfAttributeInfo.setVersion( + Integer.parseInt(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_VERSION))); + pdfAttributeInfo.setTemplateId(pdd.getCustomMetadataValue(PDF_ATTRIBUTE_TEMPLATE_ID)); } /** @@ -464,13 +475,13 @@ private void buildPdfDataFromPdf(PDDocumentInformation pdd, PdfBaseData pdfBaseD * * @param JsonSerializer * @param object serialize函数输入的object - * @param pdfBaseData PDF协议数据 + * @param pdfAttributeInfo PDF协议数据 * @return PDF流数据 * @throws WeIdBaseException exception */ private byte[] buildPdf4DefaultTpl( - T object, - PdfBaseData pdfBaseData) throws WeIdBaseException { + T object, + PdfAttributeInfo pdfAttributeInfo) throws WeIdBaseException { try { PresentationE presentation; @@ -485,7 +496,7 @@ private byte[] buildPdf4DefaultTpl( //处理credentialList不存在的情况 if (presentation.getVerifiableCredential().size() == 0) { logger.error( - "buildPdf4SpecTpl due to credentialList size equal to zero error."); + "buildPdf4SpecTpl due to credentialList size equal to zero error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } @@ -495,8 +506,9 @@ private byte[] buildPdf4DefaultTpl( credentialPojo = (CredentialPojo) object; //多签情况递归获取最内层credentialList,否则直接获取credentialList - if (credentialPojo.getClaim().containsKey("credentialList") - && credentialPojo.getClaim().size() == 1) { + if ( + credentialPojo.getClaim().containsKey("credentialList") + && credentialPojo.getClaim().size() == 1) { getMultiSignClaim(credentialPojo, creList); credentialPojoList = creList; } else { @@ -506,14 +518,14 @@ private byte[] buildPdf4DefaultTpl( credentialPojoList = (CredentialPojoList) object; } else { logger.error( - "buildPdf4DefaultTpl due to object illegal error."); + "buildPdf4DefaultTpl due to object illegal error."); throw new WeIdBaseException(ErrorCode.DATA_TYPE_CASE_ERROR); } int creListSize = credentialPojoList.size(); if (creListSize == 0) { logger.error( - "buildPdf4DefaultTpl due to credentialList size equal to zero error."); + "buildPdf4DefaultTpl due to credentialList size equal to zero error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } @@ -527,7 +539,7 @@ private byte[] buildPdf4DefaultTpl( addClaim2Pdf(credentialPojoList, document); //设置输出pdf文件的属性信息 - addAttributeInfo(document, pdfBaseData); + addAttributeInfo(document, pdfAttributeInfo); //定义OutputStream ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -548,15 +560,15 @@ private byte[] buildPdf4DefaultTpl( * * @param object serialize函数输入的object * @param document 指定PDF模板的PDDocument - * @param pdfBaseData PDF协议数据 + * @param pdfAttributeInfo PDF协议数据 * @param JsonSerializer * @return PDF流数据 * @throws WeIdBaseException exception */ private byte[] buildPdf4SpecTpl( - T object, - PDDocument document, - PdfBaseData pdfBaseData) throws WeIdBaseException { + T object, + PDDocument document, + PdfAttributeInfo pdfAttributeInfo) throws WeIdBaseException { try { PresentationE presentation = new PresentationE(); @@ -572,7 +584,7 @@ private byte[] buildPdf4SpecTpl( //处理credentialList不存在的情况 if (presentation.getVerifiableCredential().size() == 0) { logger.error( - "buildPdf4SpecTpl due to credentialList size equal to zero error."); + "buildPdf4SpecTpl due to credentialList size equal to zero error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } @@ -583,7 +595,7 @@ private byte[] buildPdf4SpecTpl( //多签情况递归获取最内层credentialList,否则直接获取credentialList if (credentialPojo.getClaim().containsKey("credentialList") - && credentialPojo.getClaim().size() == 1) { + && credentialPojo.getClaim().size() == 1) { getMultiSignClaim(credentialPojo, creList); credentialPojoList = creList; } else { @@ -593,7 +605,7 @@ private byte[] buildPdf4SpecTpl( credentialPojoList = (CredentialPojoList) object; } else { logger.error( - "buildPdf4SpecTpl due to object illegal error."); + "buildPdf4SpecTpl due to object illegal error."); throw new WeIdBaseException(ErrorCode.DATA_TYPE_CASE_ERROR); } @@ -622,7 +634,6 @@ private byte[] buildPdf4SpecTpl( } } - //从presentation获取salt和claim salt[i] = credentialPojoList.get(i).getSalt(); claim[i] = credentialPojoList.get(i).getClaim(); @@ -637,13 +648,13 @@ private byte[] buildPdf4SpecTpl( } InputStream is = this - .getClass() - .getClassLoader() - .getResourceAsStream("NotoSansCJKtc-Regular.ttf"); + .getClass() + .getClassLoader() + .getResourceAsStream("NotoSansCJKtc-Regular.ttf"); TTFParser parser = new TTFParser(); if (is == null) { logger.error( - "buildPdf4SpecTpl due to font stream is null error."); + "buildPdf4SpecTpl due to font stream is null error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } TrueTypeFont font = parser.parse(is); @@ -654,7 +665,7 @@ private byte[] buildPdf4SpecTpl( if (acroForm == null) { logger.error( - "buildPdf4SpecTpl due to pdf template acroForm is null error."); + "buildPdf4SpecTpl due to pdf template acroForm is null error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR); } @@ -682,13 +693,13 @@ private byte[] buildPdf4SpecTpl( field.setValue(text); } else { logger.error( - "buildPdf4SpecTpl due to pdf template doesn't match with claim error."); + "buildPdf4SpecTpl due to pdf template doesn't match with claim error."); throw new WeIdBaseException(ErrorCode.TRANSPORTATION_BASE_ERROR); } } //设置输出pdf文件的属性信息(PdfBaseData中每个字段),并关闭PDDocument - addAttributeInfo(document, pdfBaseData); + addAttributeInfo(document, pdfAttributeInfo); //定义OutputStream ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -712,12 +723,12 @@ private byte[] buildPdf4SpecTpl( * 把PDF流数据读出为PDDcoument数据,来获取PDF的属性信息并生成文件来验证存证. * * @param pdfTransportation PDF流数据 - * @param pdfBaseData 存PDF属性信息的PdfBaseData + * @param pdfAttributeInfo 存PDF属性信息的PdfBaseData * @throws WeIdBaseException exception */ private void resolvePdfStream( - byte[] pdfTransportation, - PdfBaseData pdfBaseData) throws WeIdBaseException { + byte[] pdfTransportation, + PdfAttributeInfo pdfAttributeInfo) throws WeIdBaseException { try { //加载文件流为PDDocument @@ -732,7 +743,7 @@ private void resolvePdfStream( //将PDF中属性信息解析到PdfBaseData数据结构中 PDDocumentInformation pdd = document.getDocumentInformation(); - buildPdfDataFromPdf(pdd, pdfBaseData); + buildPdfDataFromPdf(pdd, pdfAttributeInfo); document.close(); } catch (Exception e) { @@ -741,51 +752,25 @@ private void resolvePdfStream( } } - /** - * 通过默认PDF模板序列化. - * - * @param object 协议存储的实体数据对象 - * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 - * @return 返回PDF流数据 - */ @Override public ResponseData serialize( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication) { + T object, + ProtocolProperty property) { logger.info( - "begin to execute PdfTransportationImpl serialization, property:{}.", - property - ); + "begin to execute PdfTransportationImpl serialization, property:{}.", property); - ResponseData errorCode1 = checkPara(object, property, weIdAuthentication); + ResponseData errorCode1 = checkPara(object, property); if (errorCode1 != null) { return errorCode1; } try { - //建立用于存证的address - ResponseData evidenceAddress = evidenceService - .createEvidence(null, weIdAuthentication.getWeIdPrivateKey()); - - if (evidenceAddress.getResult().isEmpty()) { - logger.error("[serialize] PdfTransportation serialization " - + "due to build evidenceAddress error."); - return new ResponseData<>( - null, - ErrorCode.getTypeByErrorCode(evidenceAddress.getErrorCode())); - } - //构建PDF协议数据 - PdfBaseData pdfBaseData = setPdfBaseData(object, property, evidenceAddress); + PdfAttributeInfo pdfAttributeInfo = setPdfBaseData(object, property); //处理PDF显示信息和属性信息 - byte[] pdfFileByte = buildPdf4DefaultTpl(object, pdfBaseData); - - //对byte数组的Keccak-256哈希值进行存证 - setEvidence(evidenceAddress, weIdAuthentication, pdfFileByte); + byte[] pdfFileByte = buildPdf4DefaultTpl(object, pdfAttributeInfo); logger.info("PdfTransportationImpl serialization finished."); return new ResponseData<>(pdfFileByte, ErrorCode.SUCCESS); @@ -798,38 +783,26 @@ public ResponseData serialize( } } - /** - * 通过默认模板生成PDF文件. - * - * @param object 协议存储的实体数据对象 - * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 - * @param outputPdfFilePath 输出PDF文件的路径 - * @param the type of the element - * @return 序列化生成文件结果 - */ + @Override public ResponseData serialize( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String outputPdfFilePath) { + T object, + ProtocolProperty property, + String outputPdfFilePath) { try { if (outputPdfFilePath == null || outputPdfFilePath.length() == 0) { logger.error( - "[serialize] PdfTransportation " - + "serialization due to File Path illegal error."); + "[serialize] PdfTransportation serialization due to File Path illegal error."); return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); } File file = createFileByPath(outputPdfFilePath); - ResponseData res = serialize(object, property, weIdAuthentication); + ResponseData res = serialize(object, property); if (res.getResult() == null) { logger.error("[serialize] PdfTransportation serialization due to serialize error."); return new ResponseData<>( - false, - ErrorCode.getTypeByErrorCode(res.getErrorCode())); + false, ErrorCode.getTypeByErrorCode(res.getErrorCode())); } else { //生成文件 FileOutputStream outputStream = new FileOutputStream(file); @@ -846,28 +819,16 @@ public ResponseData serialize( } } - /** - * 通过指定PDF模板序列化. - * - * @param object 协议存储的实体数据对象 - * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 - * @param inputPdfTemplatePath 指定的PDF模板位置 - * @return 返回PDF的byte数组数据. - */ @Override public ResponseData serializeWithTemplate( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String inputPdfTemplatePath) { + T object, + ProtocolProperty property, + String inputPdfTemplatePath) { logger.info( - "begin to execute PdfTransportationImpl serialization, property:{}.", - property - ); + "begin to execute PdfTransportationImpl serialization, property:{}.", property); - ResponseData errorCode1 = checkPara(object, property, weIdAuthentication); + ResponseData errorCode1 = checkPara(object, property); if (errorCode1 != null) { return errorCode1; } @@ -888,26 +849,20 @@ public ResponseData serializeWithTemplate( return new ResponseData<>(null, ErrorCode.ILLEGAL_INPUT); } - //build 存证address - ResponseData evidenceAddress = evidenceService - .createEvidence(null, weIdAuthentication.getWeIdPrivateKey()); - - if (evidenceAddress.getResult().isEmpty()) { - logger.error("[serializeWithTemplate] PdfTransportation serialization " - + "due to build evidenceAddress error."); - return new ResponseData<>( - null, - ErrorCode.getTypeByErrorCode(evidenceAddress.getErrorCode())); - } + //输出PDF模板的bytes[],并计算keccak哈希值 + ByteArrayOutputStream tmpStream = new ByteArrayOutputStream(); + document.save(tmpStream); + byte[] retBytes = tmpStream.toByteArray(); + String templateHash = getChecksum(retBytes); //构建PDF协议数据 - PdfBaseData pdfBaseData = setPdfBaseData(object, property, evidenceAddress); + PdfAttributeInfo pdfAttributeInfo = setPdfBaseData(object, property); - //处理PDF显示信息和属性信息 - byte[] pdfFileByte = buildPdf4SpecTpl(object, document, pdfBaseData); + //设置PDF模板的id + pdfAttributeInfo.setTemplateId(templateHash); - //对byte数组的Keccak-256哈希值进行存证 - setEvidence(evidenceAddress, weIdAuthentication, pdfFileByte); + //处理PDF显示信息和属性信息 + byte[] pdfFileByte = buildPdf4SpecTpl(object, document, pdfAttributeInfo); logger.info("PdfTransportationImpl serialization finished."); return new ResponseData<>(pdfFileByte, ErrorCode.SUCCESS); @@ -920,47 +875,32 @@ public ResponseData serializeWithTemplate( } } - /** - * 通过指定模板生成PDF文件. - * - * @param object 协议存储的实体数据对象 - * @param property 协议类型,支持加密和非加密两种 - * @param weIdAuthentication WeID公私钥信息 - * @param inputPdfTemplatePath presentation的PDF模板 - * @param outputPdfFilePath 输出PDF文件位置 - * @param the type of the element - * @return 生成文件结果 - */ @Override public ResponseData serializeWithTemplate( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication, - String inputPdfTemplatePath, - String outputPdfFilePath) { + T object, + ProtocolProperty property, + String inputPdfTemplatePath, + String outputPdfFilePath) { try { if (outputPdfFilePath == null || outputPdfFilePath.length() == 0) { logger.error( - "[serialize] PdfTransportation " - + "serialization due to File Path illegal error."); + "[serialize] PdfTransportation serialization due to File Path illegal error."); return new ResponseData<>(false, ErrorCode.ILLEGAL_INPUT); } File file = createFileByPath(outputPdfFilePath); ResponseData res = serializeWithTemplate( - object, - property, - weIdAuthentication, - inputPdfTemplatePath); + object, + property, + inputPdfTemplatePath); if (res.getResult() == null) { logger.error( - "[serialize] PdfTransportation " - + "serialization due to serializeWithTemplate error."); + "[serialize] PdfTransportation serialization " + + "due to serializeWithTemplate error."); return new ResponseData<>( - false, - ErrorCode.getTypeByErrorCode(res.getErrorCode())); + false, ErrorCode.getTypeByErrorCode(res.getErrorCode())); } else { FileOutputStream outputStream = new FileOutputStream(file); outputStream.write(res.getResult()); @@ -969,31 +909,21 @@ public ResponseData serializeWithTemplate( return new ResponseData<>(true, ErrorCode.SUCCESS); } catch (WeIdBaseException e) { logger.error( - "[serializeWithTemplate] PdfTransportation " - + "serialization due to base error.", e); + "[serializeWithTemplate] PdfTransportation serialization due to base error.", e); return new ResponseData<>(false, e.getErrorCode()); } catch (Exception e) { logger.error( - "[serializeWithTemplate] PdfTransportation " - + "serialization due to unknown error.", e); + "[serializeWithTemplate] PdfTransportation serialization " + + "due to unknown error.", e); return new ResponseData<>(false, ErrorCode.TRANSPORTATION_BASE_ERROR); } } - /** - * pdf transportation 反序列化. - * - * @param pdfTransportation 指定反序列化的PDF文档路径 - * @param clazz 如果是presentation,这里就是PresentationE.class - * @param weIdAuthentication WeID公私钥信息 - * @param the type of the element - * @return 反序列化得到的presentation - */ @Override public ResponseData deserialize( - byte[] pdfTransportation, - Class clazz, - WeIdAuthentication weIdAuthentication) { + byte[] pdfTransportation, + Class clazz, + WeIdAuthentication weIdAuthentication) { //检查WeIdAuthentication合法性 ErrorCode errorCode = checkWeIdAuthentication(weIdAuthentication); @@ -1006,32 +936,20 @@ public ResponseData deserialize( //开始反序列化 logger.info("begin to execute PdfTransportationImpl deserialization from InputStream."); try { - PdfBaseData pdfBaseData = new PdfBaseData(); - resolvePdfStream(pdfTransportation, pdfBaseData); - - //验证存证逻辑 - HashString checkSum = new HashString(getChecksum(pdfTransportation)); - String address = pdfBaseData.getAddress(); - ResponseData resVerify = evidenceService - .verify(checkSum, address); - if (resVerify.getResult() == null || !resVerify.getResult()) { - logger.info("Evidence verify fail."); - return new ResponseData<>( - null, - ErrorCode.getTypeByErrorCode(resVerify.getErrorCode())); - } + PdfAttributeInfo pdfAttributeInfo = new PdfAttributeInfo(); + resolvePdfStream(pdfTransportation, pdfAttributeInfo); //创建编解码实体对象并对pdfBaseData中的数据进行解码 EncodeData encodeData = new EncodeData( - pdfBaseData.getId(), - pdfBaseData.getOrgId(), - String.valueOf(pdfBaseData.getData()), - super.getWeIdAuthentication() + pdfAttributeInfo.getId(), + pdfAttributeInfo.getOrgId(), + String.valueOf(pdfAttributeInfo.getData()), + super.getWeIdAuthentication() ); //根据编解码类型获取编解码枚举对象 - EncodeType encodeType = - EncodeType.getObject(String.valueOf(pdfBaseData.getEncodeType())); + EncodeType encodeType = EncodeType.getObject( + String.valueOf(pdfAttributeInfo.getEncodeType())); if (encodeType == null) { return new ResponseData<>(null, ErrorCode.TRANSPORTATION_PROTOCOL_ENCODE_ERROR); @@ -1039,10 +957,8 @@ public ResponseData deserialize( logger.info("decode by {}.", encodeType.name()); //解码 - String presentationEStr = - EncodeProcessorFactory - .getEncodeProcessor(encodeType) - .decode(encodeData); + String presentationEStr = EncodeProcessorFactory.getEncodeProcessor( + encodeType).decode(encodeData); String presentationEJson = DataToolUtils.convertUtcToTimestamp(presentationEStr); String presentationEJsonNew = presentationEJson; @@ -1058,8 +974,20 @@ public ResponseData deserialize( object = (T) method.invoke(null, presentationEJsonNew); } - logger.info("PdfTransportationImpl deserialization finished."); - return new ResponseData<>(object, ErrorCode.SUCCESS); + //有模板的情况设置presentation的type属性 + if (!pdfAttributeInfo.getTemplateId().equals("null") + && object instanceof PresentationE) { + PresentationE presentationE = new PresentationE(); + presentationE = (PresentationE) object; + List typeList = presentationE.getType(); + typeList.add(CredentialConstant.PRESENTATION_PDF); + presentationE.setType(typeList); + logger.info("PdfTransportationImpl deserialization finished."); + return new ResponseData<>((T)presentationE, ErrorCode.SUCCESS); + } else { + logger.info("PdfTransportationImpl deserialization finished."); + return new ResponseData<>(object, ErrorCode.SUCCESS); + } } catch (WeIdBaseException e) { logger.error("[deserialize] PdfTransportation deserialize due to base error.", e); return new ResponseData<>(null, e.getErrorCode()); @@ -1069,22 +997,135 @@ public ResponseData deserialize( } } + @Override + public Boolean verifyPdf( + T object, + String pdfTemplatePath, + PdfAttributeInfo pdfAttributeInfo, + byte[] serializePdf) { + + byte[] assemblePdf = assemblePdf(object, pdfTemplatePath, pdfAttributeInfo); + logger.info("[verifyPdf] verify pdf finished."); + return comparePdf(assemblePdf, serializePdf); + } + + @Override + public PdfAttributeInfo getBaseData(byte[] pdfTransportation) { + + if (pdfTransportation == null || pdfTransportation.length == 0) { + logger.error( + "[getBaseData] get PdfBaseData from byte[] " + + "due to output file path is illegal error."); + return null; + } + + PdfAttributeInfo pdfAttributeInfo = new PdfAttributeInfo(); + resolvePdfStream(pdfTransportation, pdfAttributeInfo); + return pdfAttributeInfo; + } + + /** + * 通过presentation和pdf模板组转pdf. + * + * @param object presentation + * @param pdfTemplatePath pdf模板位置 + * @param pdfAttributeInfo pdf基本信息 + * @param JsonSerializer + * @return 组装pdf信息的byte数组 + */ + private byte[] assemblePdf( + T object, + String pdfTemplatePath, + PdfAttributeInfo pdfAttributeInfo) { + + try { + //检查presentation完整性 + ErrorCode errorCode = checkProtocolData(object); + if (errorCode != ErrorCode.SUCCESS) { + logger.error("[assemblePdf] checkProtocolData fail, errorCode:{}.", errorCode); + return null; + } + + //检查Pdf模板路径合法性 + if (pdfTemplatePath == null || pdfTemplatePath.length() == 0) { + logger.error( + "[assemblePdf] assemble pdf due to pdf template path is illegal error."); + return null; + } + + //读取PDF模板 + PDDocument document; + File file = new File(pdfTemplatePath); + if (file.exists() && !file.isDirectory()) { + try { + document = PDDocument.load(file); + } catch (IOException e) { + logger.error("[assemblePdf] pdf template load error:{}.", ErrorCode.BASE_ERROR); + return null; + } + } else { + logger.error( + "[assemblePdf] pdf template directory illegal:{}.", ErrorCode.ILLEGAL_INPUT); + return null; + } + + //处理PDF显示信息和属性信息 + byte[] pdfFileByte = buildPdf4SpecTpl(object, document, pdfAttributeInfo); + + logger.info("PdfTransportationImpl assemble finished."); + return pdfFileByte; + } catch (WeIdBaseException e) { + logger.error("[assemblePdf] PdfTransportation serialization due to base error.", e); + return null; + } catch (Exception e) { + logger.error("[assemblePdf] PdfTransportation serialization due to unknown error.", e); + return null; + } + } + + /** + * 比较两个pdf的byte是否一致. + * + * @param assemblePdf 组装的pdf + * @param serializePdf 序列化生成的pdf + * @return 两者一致返回true + */ + private Boolean comparePdf( + byte[] assemblePdf, + byte[] serializePdf) { + + if (assemblePdf == null + || assemblePdf.length == 0 + || serializePdf == null + || serializePdf.length == 0) { + + logger.error( + "[comparePdfHash] compare pdf hash by byte[] " + + "due to input parameter is illegal error."); + return Boolean.FALSE; + } + + if (Arrays.equals(assemblePdf, serializePdf)) { + return Boolean.TRUE; + } else { + return Boolean.FALSE; + } + } + /** * 构建协议实体数据. * * @param property 协议配置对象 - * @param address 用于存证的合约地址 * @return 返回协议实体对象 */ - private PdfBaseData buildPdfData(ProtocolProperty property, String address) { - - PdfBaseData pdfBaseData = new PdfBaseData(); - pdfBaseData.setVersion(version.getCode()); - pdfBaseData.setEncodeType(property.getEncodeType().getCode()); - pdfBaseData.setId(DataToolUtils.getUuId32()); - pdfBaseData.setOrgId(fiscoConfig.getCurrentOrgId()); - pdfBaseData.setAddress(address); - return pdfBaseData; + private PdfAttributeInfo buildPdfData(ProtocolProperty property) { + + PdfAttributeInfo pdfAttributeInfo = new PdfAttributeInfo(); + pdfAttributeInfo.setVersion(version.getCode()); + pdfAttributeInfo.setEncodeType(property.getEncodeType().getCode()); + pdfAttributeInfo.setId(DataToolUtils.getUuId32()); + pdfAttributeInfo.setOrgId(fiscoConfig.getCurrentOrgId()); + return pdfAttributeInfo; } /** @@ -1101,7 +1142,6 @@ private void addPdfPage(int creListSize, PDDocument document) { } } - /** * 把Claim数据写入到PDF文档中. * @@ -1109,8 +1149,8 @@ private void addPdfPage(int creListSize, PDDocument document) { * @param document PDF文档 */ private void addClaim2Pdf( - List credentialPojoList, - PDDocument document) throws WeIdBaseException { + List credentialPojoList, + PDDocument document) throws WeIdBaseException { int pageAddNum = 0; int creListSize = credentialPojoList.size(); @@ -1157,30 +1197,29 @@ private void addClaim2Pdf( /** * 把disclosureInfo中的数据写入PDF. * - * @param i 当前写入page的索引 + * @param pageNum 当前写入page的索引 * @param document 待写入的PDF * @param disclosureInfo credentialList包含元素个数 * @param cptJson 用于获取当前CLaim的title * @return 增对单条disclosureInfo信息跨行,以及Claim跨页情况,返回本函数新增的page数量 */ private int drawPdf( - int i, - PDDocument document, - LinkedHashMap disclosureInfo, - Map cptJson) throws WeIdBaseException { + int pageNum, + PDDocument document, + LinkedHashMap disclosureInfo, + Map cptJson) throws WeIdBaseException { try { int pageAddNum = 0; //获取需要写入PDF的索引 PDPageContentStream contents; - contents = new PDPageContentStream(document, document.getPage(i)); + contents = new PDPageContentStream(document, document.getPage(pageNum)); //设置pdf中文字体 - InputStream is = this - .getClass() - .getClassLoader() - .getResourceAsStream("NotoSansCJKtc-Regular.ttf"); + InputStream is = this.getClass() + .getClassLoader() + .getResourceAsStream("NotoSansCJKtc-Regular.ttf"); logger.error("InputStream:" + is.available()); PDType0Font fontChinese = PDType0Font.load(document, is); @@ -1208,21 +1247,21 @@ private int drawPdf( //输出当前行的lines addMultiLine2Pdf( - lineSize, - contents, - FONT_SIZE_CONTENT, - fontChinese, - pos, - lines); + lineSize, + contents, + FONT_SIZE_CONTENT, + fontChinese, + pos, + lines); pos = pos - 15 * (lineSize - 1); pos = pos - 30; } else { addContent( - contents, - output, - POS_CONTENT_X, - pos, fontChinese, - FONT_SIZE_CONTENT); + contents, + output, + POS_CONTENT_X, + pos, fontChinese, + FONT_SIZE_CONTENT); pos = pos - 30; } @@ -1233,7 +1272,7 @@ private int drawPdf( PDPage page = new PDPage(); document.addPage(page); //用pageAddNum告诉外层已经新增了一页 - contents = new PDPageContentStream(document, document.getPage(i + 1)); + contents = new PDPageContentStream(document, document.getPage(pageNum + 1)); pageAddNum++; //设置新页面的位置 @@ -1259,7 +1298,6 @@ private ByteArrayInputStream parse(byte[] out) { return new ByteArrayInputStream(out); } - /** * 计算指定路径文件的哈希值. * @@ -1279,14 +1317,12 @@ private String getChecksum(byte[] pdfFileByte) { * * @param object 协议存储的实体数据对象 * @param property 加密属性信息 - * @param weIdAuthentication WeID公私钥信息 * @param JsonSerializer * @return 如果出错返回错误码,否则返回空 */ private ResponseData checkPara( - T object, - ProtocolProperty property, - WeIdAuthentication weIdAuthentication) { + T object, + ProtocolProperty property) { //检查协议配置完整性 ErrorCode errorCode = checkEncodeProperty(property); @@ -1301,14 +1337,6 @@ private ResponseData checkPara( logger.error("checkProtocolData fail, errorCode:{}.", errorCode); return new ResponseData<>(null, errorCode); } - - //检查WeIdAuthentication合法性 - errorCode = checkWeIdAuthentication(weIdAuthentication); - if (errorCode != ErrorCode.SUCCESS) { - logger.error("[deserialize] checkWeIdAuthentication fail, errorCode:{}.", errorCode); - return new ResponseData<>(null, errorCode); - } - super.setWeIdAuthentication(weIdAuthentication); return null; } @@ -1317,41 +1345,38 @@ private ResponseData checkPara( * * @param object 协议存储的实体数据对象 * @param property 加密属性信息 - * @param evidenceAddress 建立用于存证address的返回值 * @param JsonSerializer * @return 返回PDF协议数据实体对象 */ - private PdfBaseData setPdfBaseData( - T object, - ProtocolProperty property, - ResponseData evidenceAddress) { + private PdfAttributeInfo setPdfBaseData( + T object, + ProtocolProperty property) { //构建PDF协议数据 - PdfBaseData pdfBaseData = buildPdfData(property, evidenceAddress.getResult()); + PdfAttributeInfo pdfAttributeInfo = buildPdfData(property); logger.info("encode by {}.", property.getEncodeType().name()); //非加密情况直接设置PDF协议中data数据 if (property.getEncodeType() != EncodeType.CIPHER) { - pdfBaseData.setData(object.toJson()); + pdfAttributeInfo.setData(object.toJson()); } else { //加密情况,构建编解码数据,加密数据,设置data属性 - EncodeData encodeData = - new EncodeData( - pdfBaseData.getId(), - pdfBaseData.getOrgId(), - object.toJson(), - super.getVerifiers() + EncodeData encodeData = new EncodeData( + pdfAttributeInfo.getId(), + pdfAttributeInfo.getOrgId(), + object.toJson(), + super.getVerifiers() ); - String data = EncodeProcessorFactory - .getEncodeProcessor(property.getEncodeType()) - .encode(encodeData); - pdfBaseData.setData(data); + String data = EncodeProcessorFactory.getEncodeProcessor( + property.getEncodeType()).encode(encodeData); + pdfAttributeInfo.setData(data); } - return pdfBaseData; + return pdfAttributeInfo; } /** * 处理多签情况,获取最内层的credentialList. + * * @param credentialPojo 多签的credentialPojo * @param creList 用于返回的最内层credentialList * @return 最内层的credentialList @@ -1377,14 +1402,15 @@ private List getMultiSignClaim( for (Object innerCredentialObject : objList) { Map map = (Map) innerCredentialObject; try { - CredentialPojo innerCredentialPojo = DataToolUtils - .mapToObj(map, CredentialPojo.class); + CredentialPojo innerCredentialPojo = DataToolUtils.mapToObj( + map, + CredentialPojo.class); //处理objList内无多签credential情况 credentialPojos.add(innerCredentialPojo); if (innerCredentialPojo.getClaim().containsKey("credentialList") - && innerCredentialPojo.getClaim().size() == 1) { + && innerCredentialPojo.getClaim().size() == 1) { cp = innerCredentialPojo; break; } @@ -1405,33 +1431,15 @@ private List getMultiSignClaim( return creList; } - private void setEvidence( - ResponseData evidenceAddress, - WeIdAuthentication weIdAuthentication, - byte[] pdfFileByte) throws Exception { - - ResponseData setEvidenceRes = evidenceService - .setHashValue( - getChecksum(pdfFileByte), - evidenceAddress.getResult(), - weIdAuthentication.getWeIdPrivateKey()); - if (setEvidenceRes.getResult() == null || !setEvidenceRes.getResult()) { - logger.error("SetHashValue error."); - throw new WeIdBaseException( - ErrorCode.getTypeByErrorCode(setEvidenceRes.getErrorCode())); - } - } - private File createFileByPath(String outputPdfFilePath) { try { - String fileName = null; + String fileName; File file = new File(outputPdfFilePath); //outputPdfFilePath是文件还是路径 - if (outputPdfFilePath.contains(FILE_SEPARATOR) - && outputPdfFilePath.substring( - outputPdfFilePath.lastIndexOf(FILE_SEPARATOR)).equals(PDF_SUFFIX)) { + if (outputPdfFilePath.contains(FILE_SEPARATOR) && outputPdfFilePath.substring( + outputPdfFilePath.lastIndexOf(FILE_SEPARATOR)).equals(PDF_SUFFIX)) { file = new File(outputPdfFilePath); //如果文件所属目录不存在就创建目录 @@ -1455,14 +1463,12 @@ private File createFileByPath(String outputPdfFilePath) { throw new WeIdBaseException(ErrorCode.BASE_ERROR); } fileName = outputPdfFilePath - + PATH_LINKER - + calendar.getTimeInMillis() + PDF_SUFFIX; + + PATH_LINKER + calendar.getTimeInMillis() + PDF_SUFFIX; file = new File(fileName); //文件路径不存在,则新建目录,并使用默认文件名新建文件 } else { fileName = outputPdfFilePath - + PATH_LINKER - + calendar.getTimeInMillis() + PDF_SUFFIX; + + PATH_LINKER + calendar.getTimeInMillis() + PDF_SUFFIX; file = new File(fileName); } } diff --git a/src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfBaseData.java b/src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfAttributeInfo.java similarity index 90% rename from src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfBaseData.java rename to src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfAttributeInfo.java index e53512652..1919441d6 100644 --- a/src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfBaseData.java +++ b/src/main/java/com/webank/weid/suite/transportation/pdf/protocol/PdfAttributeInfo.java @@ -27,10 +27,12 @@ @Getter @Setter -public class PdfBaseData extends JsonBaseData { +public class PdfAttributeInfo extends JsonBaseData { /** - * 存证地址. + * PDF模板id. */ - private String address; + private String templateId; + + } diff --git a/src/main/java/com/webank/weid/util/CredentialPojoUtils.java b/src/main/java/com/webank/weid/util/CredentialPojoUtils.java index 294c215fd..7a579dfe6 100644 --- a/src/main/java/com/webank/weid/util/CredentialPojoUtils.java +++ b/src/main/java/com/webank/weid/util/CredentialPojoUtils.java @@ -33,6 +33,7 @@ import static com.webank.weid.service.impl.CredentialPojoServiceImpl.generateSalt; +import com.webank.weid.constant.CptType; import com.webank.weid.constant.CredentialConstant; import com.webank.weid.constant.CredentialConstant.CredentialProofType; import com.webank.weid.constant.CredentialFieldDisclosureValue; @@ -961,17 +962,19 @@ private static boolean isCredentialProofTypeValid(String type) { /** * check if the cpt can be used for zkp or not. * - * @param cptId the id of the CPT + * @param cptJson the json schema of the CPT * @return true if can be used for zkp, otherwise fales */ - public static boolean isZkpCpt(Integer cptId) { + public static boolean isZkpCpt(String cptJson) { - //currently, the system cpt 107, 110 and 111 can not be used for zkp - if (cptId == CredentialConstant.CREDENTIALPOJO_EMBEDDED_SIGNATURE_CPT - || cptId == CredentialConstant.METADATA_CPT - || cptId == CredentialConstant.ZKP_USER_NONCE_CPT) { - return false; + Map jsonSchemaMap = DataToolUtils + .deserialize(cptJson.trim(), HashMap.class); + if (jsonSchemaMap.containsKey(CredentialConstant.CPT_TYPE_KEY)) { + String cptType = String.valueOf(jsonSchemaMap.get(CredentialConstant.CPT_TYPE_KEY)); + if (StringUtils.equals(cptType, CptType.ZKP.getName().toString())) { + return true; + } } - return true; + return false; } } diff --git a/src/main/java/com/webank/weid/util/DataToolUtils.java b/src/main/java/com/webank/weid/util/DataToolUtils.java index 35c2975e9..b90ced0f8 100644 --- a/src/main/java/com/webank/weid/util/DataToolUtils.java +++ b/src/main/java/com/webank/weid/util/DataToolUtils.java @@ -52,6 +52,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -251,6 +252,30 @@ public static String serialize(T object) { return write.toString(); } + /** + * Convert a private key to its default WeID. + * + * @param privateKey the pass-in privatekey + * @return true if yes, false otherwise + */ + public static String convertPrivateKeyToDefaultWeId(String privateKey) { + org.fisco.bcos.web3j.crypto.ECKeyPair keyPair = org.fisco.bcos.web3j.crypto.ECKeyPair + .create(new BigInteger(privateKey)); + return WeIdUtils + .convertAddressToWeId(new org.fisco.bcos.web3j.abi.datatypes.Address( + org.fisco.bcos.web3j.crypto.Keys.getAddress(keyPair)).toString()); + } + + /** + * Check whether the String is a valid hash. + * @param hashValue hash in String + * @return true if yes, false otherwise + */ + public static boolean isValidHash(String hashValue) { + return !StringUtils.isEmpty(hashValue) + && Pattern.compile(WeIdConstant.HASH_VALUE_PATTERN).matcher(hashValue).matches(); + } + /** * deserialize a JSON String to an class instance. * @@ -335,6 +360,18 @@ public static String mapToCompactJson(Map map) throws Exception return OBJECT_MAPPER.readTree(serialize(map)).toString(); } + /** + * Convert a Map to compact Json output, with keys ordered. Use Jackson JsonNode toString() to + * ensure key order and compact output. + * + * @param map input map + * @return JsonString + * @throws Exception IOException + */ + public static String stringMapToCompactJson(Map map) throws Exception { + return OBJECT_MAPPER.readTree(serialize(map)).toString(); + } + /** * Convert a POJO to Map. * diff --git a/src/test/java/com/webank/weid/full/credentialpojo/TestVerifyCredentialWithPresentation.java b/src/test/java/com/webank/weid/full/credentialpojo/TestVerifyCredentialWithPresentation.java index b05630c65..db3882a76 100644 --- a/src/test/java/com/webank/weid/full/credentialpojo/TestVerifyCredentialWithPresentation.java +++ b/src/test/java/com/webank/weid/full/credentialpojo/TestVerifyCredentialWithPresentation.java @@ -5,22 +5,27 @@ import java.util.Map; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webank.weid.common.LogUtil; import com.webank.weid.constant.ErrorCode; -import com.webank.weid.full.TestBaseServcie; import com.webank.weid.full.TestBaseUtil; +import com.webank.weid.full.transportation.TestBaseTransportation; import com.webank.weid.protocol.base.Challenge; import com.webank.weid.protocol.base.ClaimPolicy; import com.webank.weid.protocol.base.CredentialPojo; import com.webank.weid.protocol.base.PresentationE; import com.webank.weid.protocol.base.PresentationPolicyE; import com.webank.weid.protocol.response.ResponseData; +import com.webank.weid.suite.api.transportation.TransportationFactory; +import com.webank.weid.suite.api.transportation.params.EncodeType; +import com.webank.weid.suite.api.transportation.params.ProtocolProperty; +import com.webank.weid.suite.transportation.pdf.impl.PdfTransportationImpl; -public class TestVerifyCredentialWithPresentation extends TestBaseServcie { +public class TestVerifyCredentialWithPresentation extends TestBaseTransportation { private static final Logger logger = LoggerFactory.getLogger(TestCreatePresentation.class); @@ -36,8 +41,21 @@ public class TestVerifyCredentialWithPresentation extends TestBaseServcie { private static PresentationE presentationE = null; + //test for pdf presentation verify + private static CredentialPojo credentialPojoNew1 = null; + + private static List credentialList1 = new ArrayList<>(); + + private static PresentationPolicyE presentationPolicyE1 + = PresentationPolicyE.create("test-spectpl-policy.json"); + + private static Challenge challenge1 = null; + + private static PresentationE presentationE1 = null; + @Override public synchronized void testInit() { + super.testInit(); if (credentialPojoNew == null) { @@ -72,12 +90,47 @@ public synchronized void testInit() { presentationE = response.getResult(); } + //init for pdf presentation verify + super.testInitSpecTplCpt(); + + if (credentialPojoNew1 == null) { + credentialPojoNew1 = super.createCredentialPojo(createCredentialPojoArgs4); + } + if (presentationPolicyE1 != null) { + presentationPolicyE1 = PresentationPolicyE.create("test-spectpl-policy.json"); + presentationPolicyE1.setPolicyPublisherWeId(createWeIdResultWithSetAttr.getWeId()); + Map policyMap1 = presentationPolicyE1.getPolicy(); + ClaimPolicy cliamPolicy1 = policyMap1.get(1005); + policyMap1.remove(1005); + policyMap1.put(createCredentialPojoArgs4.getCptId(), cliamPolicy1); + } + if (challenge1 == null) { + challenge1 = Challenge.create( + createWeIdResultWithSetAttr.getWeId(), + String.valueOf(System.currentTimeMillis())); + } + + if (credentialList1 == null || credentialList1.size() == 0) { + credentialList1.add(credentialPojoNew1); + } + if (presentationE1 == null) { + ResponseData response1 = credentialPojoService.createPresentation( + credentialList1, + presentationPolicyE1, + challenge1, + TestBaseUtil.buildWeIdAuthentication(createWeIdResultWithSetAttr) + ); + + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response1.getErrorCode().intValue()); + presentationE1 = response1.getResult(); + } + + } /** * verify credential pojo with presention successs. */ - @Test public void testVerfiyCredential_suceess() { @@ -90,5 +143,69 @@ public void testVerfiyCredential_suceess() { Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); } + /** + * verify presentation from pdf transportation. + */ + @Test + @Ignore + public void testVerifyPdfPresentation_fail() { + + //序列化PDF,生成包含PDF信息的byte[] + ResponseData retSerialize = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentationE1, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template.pdf"); + LogUtil.info(logger, "serialize", retSerialize); + + //反序列化PDF数组为PresentationE + ResponseData retDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(retSerialize.getResult(), PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", retDeserialize); + ResponseData response = credentialPojoService.verify( + credentialPojoNew1.getIssuer(), + presentationPolicyE1, + challenge1, + retDeserialize.getResult()); + LogUtil.info(logger, "testVerfiyCredentialWithPresention", response); + Assert.assertEquals( + ErrorCode.CREDENTIAL_USE_VERIFY_FUNCTION_ERROR.getCode(), + response.getErrorCode().intValue()); + } + + /** + * verify presentation from pdf transportation. + */ + @Test + @Ignore + public void testVerifyPdfPresentation_success() { + PdfTransportationImpl pdfTransportation = new PdfTransportationImpl(); + + //序列化PDF,生成包含PDF信息的byte[] + ResponseData retSerialize = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentationE1, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template.pdf"); + LogUtil.info(logger, "serialize", retSerialize); + + //反序列化PDF数组为PresentationE + ResponseData retDeserialize = TransportationFactory.newPdfTransportation() + .deserialize( + retSerialize.getResult(), + PresentationE.class, + weIdAuthentication); + LogUtil.info(logger, "deserialize", retDeserialize); + + ResponseData response = credentialPojoService.verifyPresentationFromPdf( + "src/test/resources/test-template.pdf", + retSerialize.getResult(), + credentialPojoNew1.getIssuer(), + presentationPolicyE1, + challenge1, + retDeserialize.getResult()); + LogUtil.info(logger, "testVerfiyCredentialWithPresention", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + } } diff --git a/src/test/java/com/webank/weid/full/evidence/TestCreateEvidence.java b/src/test/java/com/webank/weid/full/evidence/TestCreateEvidence.java index 640fd54c4..ac263efe8 100644 --- a/src/test/java/com/webank/weid/full/evidence/TestCreateEvidence.java +++ b/src/test/java/com/webank/weid/full/evidence/TestCreateEvidence.java @@ -20,9 +20,7 @@ package com.webank.weid.full.evidence; import java.io.File; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -43,7 +41,6 @@ import com.webank.weid.protocol.base.CredentialPojo; import com.webank.weid.protocol.base.CredentialWrapper; import com.webank.weid.protocol.base.EvidenceInfo; -import com.webank.weid.protocol.base.HashString; import com.webank.weid.protocol.base.WeIdPrivateKey; import com.webank.weid.protocol.response.CreateWeIdDataResult; import com.webank.weid.protocol.response.ResponseData; @@ -75,12 +72,93 @@ public synchronized void testInit() { public void testCreateEvidence_success() { CreateWeIdDataResult tempCreateWeIdResultWithSetAttr = super.copyCreateWeId(createWeIdResultWithSetAttr); - ResponseData response = evidenceService - .createEvidence(credential, tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey()); - LogUtil.info(logger, "createEvidence", response); + String hash = evidenceService.generateHash(credential).getResult().getHash(); + System.out.println(hash); + Map extraMap = new HashMap<>(); + extraMap.put("credentialId", "1144225"); + ResponseData response = evidenceService.createEvidence(credential, + tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey(), extraMap); + String signerWeId = tempCreateWeIdResultWithSetAttr.getWeId(); Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); Assert.assertTrue(!response.getResult().isEmpty()); + ResponseData eviInfo = evidenceService.getEvidence(hash); + EvidenceInfo evidenceInfo = eviInfo.getResult(); + Assert.assertTrue(evidenceInfo.getCredentialHash().equalsIgnoreCase(hash)); + Assert.assertTrue(evidenceInfo.getSigners().contains(signerWeId)); + Assert.assertFalse(evidenceInfo.getSignInfo().get(signerWeId).getExtraValue().isEmpty()); + ResponseData resp = evidenceService.verifySigner(evidenceInfo, signerWeId); + Assert.assertTrue(resp.getResult()); + } + + @Test + public void testCreateEvidence_MultipleSigners() { + CreateWeIdDataResult tempCreateWeIdResultWithSetAttr = + super.copyCreateWeId(createWeIdResultWithSetAttr); + Map extraMap = new HashMap<>(); + extraMap.put("credentialId", "1144225"); + ResponseData response = evidenceService + .createEvidence(credential, tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey(), + extraMap); + CreateWeIdDataResult tempCreateWeIdResultWithSetAttr2 = createWeIdWithSetAttr(); + extraMap.put("temprecord", "abcabc"); + ResponseData response2 = evidenceService.createEvidence(credential, + tempCreateWeIdResultWithSetAttr2.getUserWeIdPrivateKey(), extraMap); + Assert.assertTrue(response.getResult().equalsIgnoreCase(response2.getResult())); + String hash = evidenceService.generateHash(credential).getResult().getHash(); + Assert.assertTrue(response.getResult().equalsIgnoreCase(hash)); + Assert.assertTrue(response.getErrorCode().equals(ErrorCode.SUCCESS.getCode()) + && response2.getErrorCode().equals(ErrorCode.SUCCESS.getCode())); + ResponseData eviInfo = evidenceService.getEvidence(hash); + EvidenceInfo evidenceInfo = eviInfo.getResult(); + Assert.assertTrue( + evidenceInfo.getSigners().contains(tempCreateWeIdResultWithSetAttr.getWeId()) + && evidenceInfo.getSigners().contains(tempCreateWeIdResultWithSetAttr2.getWeId())); + Assert.assertEquals(evidenceInfo.getSignInfo() + .get(tempCreateWeIdResultWithSetAttr.getWeId()).getExtraValue().size(), 1); + Assert.assertEquals(evidenceInfo.getSignInfo() + .get(tempCreateWeIdResultWithSetAttr2.getWeId()).getExtraValue().size(), 2); + Assert.assertTrue(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr.getWeId()).getResult()); + Assert.assertTrue(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr2.getWeId()).getResult()); + Assert.assertTrue(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr.getWeId(), + tempCreateWeIdResultWithSetAttr.getUserWeIdPublicKey().getPublicKey()).getResult()); + Assert.assertFalse(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr.getWeId(), + tempCreateWeIdResultWithSetAttr2.getUserWeIdPublicKey().getPublicKey()).getResult()); + Assert.assertFalse(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr.getWeId(), "abcde").getResult()); + } + + @Test + public void testCreateEvidence_SignMultipleTimesWithMultipleMapValues() { + CreateWeIdDataResult tempCreateWeIdResultWithSetAttr = createWeIdWithSetAttr(); + Map extraMap = new HashMap<>(); + extraMap.put("credentialId", "aab-ccd"); + ResponseData response = evidenceService.createEvidence(credential, + tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey(), extraMap); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + extraMap.put("credentialId", "11223344"); + extraMap.put("my name is", "dummy dull"); + ResponseData response2 = evidenceService.createEvidence(credential, + tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey(), extraMap); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response2.getErrorCode().intValue()); + extraMap = new HashMap<>(); + extraMap.put("slashId", "A0519872"); + evidenceService.createEvidence(credential, + tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey(), extraMap); + String hash = evidenceService.generateHash(credential).getResult().getHash(); + ResponseData eviInfo = evidenceService.getEvidence(hash); + EvidenceInfo evidenceInfo = eviInfo.getResult(); + String signerWeId = tempCreateWeIdResultWithSetAttr.getWeId(); + Assert.assertEquals(evidenceInfo.getSignInfo() + .get(signerWeId).getExtraValue().size(), 3); + Assert.assertTrue(evidenceInfo.getSignInfo().get(signerWeId).getExtraValue() + .get("credentialId").equalsIgnoreCase("11223344")); + Assert.assertTrue(evidenceService.verifySigner(evidenceInfo, + tempCreateWeIdResultWithSetAttr.getWeId()).getResult()); } /** @@ -152,30 +230,6 @@ public void testCreateEvidence_priKeyBlank() { Assert.assertFalse(!response.getResult().isEmpty()); } - /** - * case8: createEvidence immutability - multiple invocations lead to different addresses. - */ - @Test - public void testCreateEvidence_theSameRequestHasDifferentAddress() { - CreateWeIdDataResult tempCreateWeIdResultWithSetAttr = super.copyCreateWeId(createWeIdNew); - ResponseData response = evidenceService - .createEvidence(credential, tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey()); - LogUtil.info(logger, "createEvidence", response); - - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertTrue(!response.getResult().isEmpty()); - - ResponseData response1 = evidenceService - .createEvidence(credential, tempCreateWeIdResultWithSetAttr.getUserWeIdPrivateKey()); - LogUtil.info(logger, "createEvidence", response); - - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertFalse(response.getResult().equalsIgnoreCase(response1.getResult())); - } /** * case9: privateKey is not exist. @@ -544,8 +598,6 @@ public void testEvidenceFull_SelectivelyDisclosurePojo() { EvidenceInfo sdEvi = evidenceService.getEvidence(sdAddr).getResult(); Assert.assertTrue( originalEvi.getCredentialHash().equalsIgnoreCase(sdEvi.getCredentialHash())); - Assert.assertTrue(evidenceService.verify(originalCredential, originalAddr).getResult()); - Assert.assertTrue(evidenceService.verify(sdCredential, sdAddr).getResult()); } @@ -574,82 +626,6 @@ public void testEvidenceFull_SelectivelyDisclosure() { EvidenceInfo sdEvi = evidenceService.getEvidence(sdAddr).getResult(); Assert.assertTrue( originalEvi.getCredentialHash().equalsIgnoreCase(sdEvi.getCredentialHash())); - Assert.assertTrue(evidenceService.verify(tempCredential, originalAddr).getResult()); - Assert.assertTrue(evidenceService.verify(credentialWrapper, sdAddr).getResult()); - } - - /** - * Case: multiple signers happy path. - */ - @Test - public void testEvidenceMultipleSignersAll() { - List signersList = new ArrayList<>(); - signersList.add(createWeIdNew.getWeId()); - CreateWeIdDataResult weId2Result = createWeId(); - signersList.add(weId2Result.getWeId()); - CreateWeIdDataResult weId3Result = createWeId(); - signersList.add(weId3Result.getWeId()); - CreateWeIdDataResult weId4Result = createWeId(); - ResponseData resp = evidenceService - .createEvidence(credential, signersList, weId4Result.getUserWeIdPrivateKey()); - Assert.assertTrue(StringUtils.isEmpty(resp.getResult())); - Assert.assertEquals(resp.getErrorCode().intValue(), - ErrorCode.CREDENTIAL_PRIVATE_KEY_NOT_EXISTS.getCode()); - String eviAddr = evidenceService - .createEvidence(credential, signersList, createWeIdNew.getUserWeIdPrivateKey()) - .getResult(); - Assert.assertFalse(StringUtils.isEmpty(eviAddr)); - EvidenceInfo eviInfo = evidenceService.getEvidence(eviAddr).getResult(); - Assert.assertNotNull(eviInfo); - Assert.assertEquals(eviInfo.getSignatures().size(), 1); - Assert.assertEquals(eviInfo.getSigners().size(), 3); - List signersAddrList = new ArrayList<>(); - for (String weId : signersList) { - signersAddrList.add(weId); - } - List onChainSigners = eviInfo.getSigners(); - for (String weId : signersAddrList) { - Assert.assertTrue(onChainSigners.contains(weId)); - } - for (String weId : onChainSigners) { - Assert.assertTrue(signersAddrList.contains(weId)); - } - Assert.assertTrue(evidenceService.verify(credential, eviAddr).getResult()); - Assert.assertFalse( - evidenceService.addSignature(credential, eviAddr, weId4Result.getUserWeIdPrivateKey()) - .getResult()); - Assert.assertTrue( - evidenceService.addSignature(credential, eviAddr, weId2Result.getUserWeIdPrivateKey()) - .getResult()); - Assert.assertFalse( - evidenceService - .addSignature(credentialPojo, eviAddr, weId3Result.getUserWeIdPrivateKey()) - .getResult()); - eviInfo = evidenceService.getEvidence(eviAddr).getResult(); - Assert.assertEquals(eviInfo.getSignatures().size(), 2); - Assert.assertTrue(evidenceService.verify(credential, eviAddr).getResult()); - } - - /** - * Case: empty evidence. - */ - @Test - public void testEmptyEvidenceAll() { - WeIdPrivateKey privKey = createWeIdNew.getUserWeIdPrivateKey(); - String eviAddr = evidenceService.createEvidence(null, privKey).getResult(); - Assert.assertFalse(StringUtils.isEmpty(eviAddr)); - EvidenceInfo evidenceInfo = evidenceService.getEvidence(eviAddr).getResult(); - Assert.assertTrue(StringUtils.isEmpty(evidenceInfo.getCredentialHash())); - for (String sig : evidenceInfo.getSignatures()) { - Assert.assertTrue(StringUtils.isEmpty(sig)); - } - String hashValue = credential.getHash(); - ResponseData resp = evidenceService.setHashValue(hashValue, eviAddr, privKey); - Assert.assertTrue(resp.getResult()); - Assert.assertTrue(evidenceService.verify(credential, eviAddr).getResult()); - Assert.assertTrue(evidenceService.verify(new HashString(hashValue), eviAddr).getResult()); - // Any second attempt will fail - Assert.assertFalse(evidenceService.setHashValue(hashValue, eviAddr, privKey).getResult()); } /** diff --git a/src/test/java/com/webank/weid/full/evidence/TestGetEvidence.java b/src/test/java/com/webank/weid/full/evidence/TestGetEvidence.java index a5aab87ae..60a481c3f 100644 --- a/src/test/java/com/webank/weid/full/evidence/TestGetEvidence.java +++ b/src/test/java/com/webank/weid/full/evidence/TestGetEvidence.java @@ -75,7 +75,7 @@ public void testGetEvidence_success() { * case2: address is null. */ @Test - public void testGetEvidence_addressNull() { + public void testGetEvidence_HashNull() { ResponseData responseData = evidenceService.getEvidence(null); logger.info("testGetEvidenceCase2 result :" + responseData); @@ -89,21 +89,8 @@ public void testGetEvidence_addressNull() { * case3: address is "". */ @Test - public void testGetEvidence_addressBlank() { - String evidenceAddress = ""; - ResponseData responseData = evidenceService.getEvidence(evidenceAddress); - logger.info("testGetEvidenceCase3 result :" + responseData); - Assert.assertEquals(ErrorCode.ILLEGAL_INPUT.getCode(), - responseData.getErrorCode().intValue()); - Assert.assertNull(responseData.getResult()); - } - - /** - * case3: address Contain SpecialChar. - */ - @Test - public void testGetEvidence_addressContainSpecialChar() { - String evidenceAddress = ""; + public void testGetEvidence_HashIllegal() { + String evidenceAddress = "sdasfdcscwwewecas"; ResponseData responseData = evidenceService.getEvidence(evidenceAddress); logger.info("testGetEvidenceCase3 result :" + responseData); Assert.assertEquals(ErrorCode.ILLEGAL_INPUT.getCode(), diff --git a/src/test/java/com/webank/weid/full/evidence/TestVerifyEvidence.java b/src/test/java/com/webank/weid/full/evidence/TestVerifyEvidence.java deleted file mode 100644 index 364840fba..000000000 --- a/src/test/java/com/webank/weid/full/evidence/TestVerifyEvidence.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright© (2018-2019) WeBank Co., Ltd. - * - * This file is part of weid-java-sdk. - * - * weid-java-sdk is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * weid-java-sdk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with weid-java-sdk. If not, see . - */ - -package com.webank.weid.full.evidence; - -import java.util.Map; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static com.webank.weid.util.CredentialUtils.copyCredential; - -import com.webank.weid.constant.ErrorCode; -import com.webank.weid.constant.ParamKeyConstant; -import com.webank.weid.full.TestBaseServcie; -import com.webank.weid.protocol.base.Credential; -import com.webank.weid.protocol.response.CreateWeIdDataResult; -import com.webank.weid.protocol.response.ResponseData; -import com.webank.weid.util.DateUtils; - -/** - * TestVerifyEvidence v_wbpenghu. - */ -public class TestVerifyEvidence extends TestBaseServcie { - - private static final Logger logger = LoggerFactory.getLogger(TestVerifyEvidence.class); - private static Credential evidenceCredential = null; - private static String evidenceAddress; - - @Override - public synchronized void testInit() { - if (!isInitIssuer) { - super.testInit(); - } - if (evidenceCredential == null) { - evidenceCredential = super.createCredential(createCredentialArgs).getCredential(); - ResponseData evidence = evidenceService.createEvidence(evidenceCredential, - createWeIdResultWithSetAttr.getUserWeIdPrivateKey()); - Assert.assertTrue(!evidence.getResult().isEmpty()); - evidenceAddress = evidence.getResult(); - } - } - - /** - * case1: succeed. - */ - @Test - public void testVerifyEvidenceCase1() { - ResponseData responseData = evidenceService - .verify(evidenceCredential, evidenceAddress); - logger.info("testVerifyEvidenceCase1 result :" + responseData); - Assert.assertTrue(responseData.getResult()); - Assert.assertEquals(responseData.getErrorCode().intValue(), ErrorCode.SUCCESS.getCode()); - } - - /** - * case2: id is "". - */ - @Test - public void testVerifyEvidenceCase2() { - Credential credential = copyCredential(evidenceCredential); - credential.setId(""); - ResponseData innerResp = credentialService.getCredentialHash(credential); - Assert.assertEquals( - ErrorCode.CREDENTIAL_ID_NOT_EXISTS.getCode(), - innerResp.getErrorCode().intValue()); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase2 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - } - - /** - * case3: id is null. - */ - @Test - public void testVerifyEvidenceCase3() { - Credential credential = copyCredential(evidenceCredential); - credential.setId(null); - ResponseData innerResp = credentialService.getCredentialHash(credential); - Assert.assertEquals( - ErrorCode.CREDENTIAL_ID_NOT_EXISTS.getCode(), - innerResp.getErrorCode().intValue()); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase3 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - } - - - /** - * case5: Issuer is "". - */ - @Test - public void testVerifyEvidenceCase5() { - Credential credential = copyCredential(evidenceCredential); - credential.setId(credential.getId()); - credential.setIssuer(""); - ResponseData innerResp = credentialService.getCredentialHash(credential); - Assert.assertEquals( - ErrorCode.CREDENTIAL_ISSUER_INVALID.getCode(), - innerResp.getErrorCode().intValue()); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase5 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - } - - /** - * case6: cptId is not exit. - */ - @Test - public void testVerifyEvidenceCase6() { - Credential credential = copyCredential(evidenceCredential); - credential.setId(credential.getId()); - credential.setCptId(-1); - ResponseData innerResp = credentialService.getCredentialHash(credential); - Assert.assertEquals( - ErrorCode.CPT_ID_ILLEGAL.getCode(), - innerResp.getErrorCode().intValue()); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase6 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - } - - /** - * case7: ExpirationDate is not match. - */ - @Test - public void testVerifyEvidenceCase7() { - Credential credential = copyCredential(evidenceCredential); - credential.setExpirationDate(System.currentTimeMillis() - 5000); - ResponseData innerResp = credentialService.getCredentialHash(credential); - Assert.assertTrue(innerResp.getErrorCode() == ErrorCode.CREDENTIAL_EXPIRED.getCode() - || innerResp.getErrorCode() == ErrorCode.CREDENTIAL_EVIDENCE_HASH_MISMATCH.getCode()); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase7 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - - } - - /** - * case8: IssuranceDate is not match. - */ - @Test - public void testVerifyEvidenceCase8() { - Credential credential = copyCredential(evidenceCredential); - credential.setIssuanceDate(DateUtils.getNoMillisecondTimeStamp() + 10); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase8 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - Assert.assertEquals(responseData.getErrorCode().intValue(), - ErrorCode.CREDENTIAL_EVIDENCE_HASH_MISMATCH.getCode()); - } - - /** - * case10: args is null. - */ - @Test - public void testVerifyEvidenceCase10() { - ResponseData responseData = evidenceService - .verify(evidenceCredential, null); - logger.info("testVerifyEvidenceCase12 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - Assert.assertEquals(responseData.getErrorCode().intValue(), - ErrorCode.ILLEGAL_INPUT.getCode()); - } - - /** - * case11: Signature is not match. - */ - @Test - public void testVerifyEvidenceCase11() { - Credential credential = copyCredential(evidenceCredential); - Map proof = credential.getProof(); - String sigValue = proof.get(ParamKeyConstant.CREDENTIAL_SIGNATURE); - proof.put(ParamKeyConstant.CREDENTIAL_SIGNATURE, sigValue + "x"); - credential.setProof(proof); - ResponseData responseData = evidenceService - .verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase11 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - Assert.assertEquals(responseData.getErrorCode().intValue(), - ErrorCode.CREDENTIAL_EVIDENCE_HASH_MISMATCH.getCode()); - } - - /** - * case12: args is null. - */ - @Test - public void testVerifyEvidenceCase12() { - Credential credential = null; - ResponseData responseData = evidenceService.verify(credential, evidenceAddress); - logger.info("testVerifyEvidenceCase12 result :" + responseData); - Assert.assertFalse(responseData.getResult()); - Assert.assertEquals(responseData.getErrorCode().intValue(), - ErrorCode.ILLEGAL_INPUT.getCode()); - } - - /** - * case13: privateKey is not match. - */ - @Test - public void testVerifyEvidenceCase13() { - CreateWeIdDataResult weIdWithSetAttr = super.copyCreateWeId(createWeIdResultWithSetAttr); - weIdWithSetAttr.getUserWeIdPrivateKey().setPrivateKey("11111111"); - ResponseData responseData = evidenceService - .createEvidence(evidenceCredential, weIdWithSetAttr.getUserWeIdPrivateKey()); - Assert.assertTrue(!responseData.getResult().isEmpty()); - Assert.assertEquals(responseData.getErrorCode().intValue(), ErrorCode.SUCCESS.getCode()); - ResponseData responseData1 = evidenceService - .verify(evidenceCredential, responseData.getResult()); - logger.info("testVerifyEvidenceCase13 result :" + responseData1); - Assert.assertEquals(responseData1.getErrorCode().intValue(), - ErrorCode.CREDENTIAL_ISSUER_MISMATCH.getCode()); - Assert.assertFalse(responseData1.getResult()); - } - - /** - * case15: privateKey is correct , private is on chain(weid exist) ,but this weid not set - * Permission. - */ - @Test - public void testVerifyEvidenceCase15() { - CreateWeIdDataResult weIdWithSetAttr = weIdService.createWeId().getResult(); - ResponseData responseData1 = evidenceService - .createEvidence(evidenceCredential, weIdWithSetAttr.getUserWeIdPrivateKey()); - logger.info("testVerifyEvidenceCase15 result :" + responseData1); - Assert.assertEquals(responseData1.getErrorCode().intValue(), ErrorCode.SUCCESS.getCode()); - ResponseData responseData2 = evidenceService - .verify(evidenceCredential, responseData1.getResult()); - Assert.assertEquals(responseData2.getErrorCode().intValue(), - ErrorCode.SUCCESS.getCode()); - Assert.assertTrue(responseData2.getResult()); - } -} diff --git a/src/test/java/com/webank/weid/full/transportation/TestPdfDeserialize.java b/src/test/java/com/webank/weid/full/transportation/TestPdfDeserialize.java deleted file mode 100644 index c2a03d1cf..000000000 --- a/src/test/java/com/webank/weid/full/transportation/TestPdfDeserialize.java +++ /dev/null @@ -1,332 +0,0 @@ -package com.webank.weid.full.transportation; - -import java.io.File; -import java.io.FileInputStream; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.webank.weid.common.LogUtil; -import com.webank.weid.constant.ErrorCode; -import com.webank.weid.protocol.base.CredentialPojo; -import com.webank.weid.protocol.base.CredentialPojoList; -import com.webank.weid.protocol.base.PresentationE; -import com.webank.weid.protocol.response.ResponseData; -import com.webank.weid.suite.api.transportation.TransportationFactory; -import com.webank.weid.suite.api.transportation.params.EncodeType; -import com.webank.weid.suite.api.transportation.params.ProtocolProperty; - -/** - * test base class. - */ -public class TestPdfDeserialize extends TestBaseTransportation { - - private static final Logger logger = LoggerFactory.getLogger(TestPdfDeserialize.class); - - private static PresentationE presentation; - private static PresentationE presentation4MlCpt; - private static PresentationE presentation4MultiCpt; - private static PresentationE presentation4SpecTpl; - - @Override - public synchronized void testInit() { - if (presentation == null) { - super.testInit(); - super.testInit4MlCpt(); - super.testInit4MultiCpt(); - super.testInitSpecTplCpt(); - presentation = this.getPresentationE(); - presentation4MlCpt = getPresentationE4MlCpt(); - presentation4MultiCpt = getPresentationE4MultiCpt(); - presentation4SpecTpl = getPresentationE4SpecTplCpt(); - } - } - - /** - * 使用原文方式构建协议数据并解析. - */ - @Test - public void testDeserializeCase1() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation, - new ProtocolProperty((EncodeType.ORIGINAL)), - weIdAuthentication); - - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - response.getResult(), - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(presentation.toJson(), resDeserialize.getResult().toJson()); - } - - /** - * 使用密文方式构建协议数据并解析. - */ - @Test - public void testDeserializeCase2() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .specify(verifier) - .serialize( - presentation4MlCpt, - new ProtocolProperty((EncodeType.CIPHER)), - weIdAuthentication); - - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .specify(verifier) - .deserialize( - response.getResult(), - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(presentation4MlCpt.toJson(), resDeserialize.getResult().toJson()); - } - - /** - * 未设置verifier导致的无权限获取密钥数据. - */ - @Test - public void testDeserializeCase3() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation4MlCpt, - new ProtocolProperty((EncodeType.CIPHER)), - weIdAuthentication); - - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - response.getResult(), - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.ENCRYPT_KEY_NO_PERMISSION.getCode(), - resDeserialize.getErrorCode().intValue()); - } - - /** - * 对指定PDF模板序列化并解析. - */ - @Test - public void testDeserializeCase4() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty((EncodeType.ORIGINAL)), - weIdAuthentication, - "src/test/resources/test-template.pdf"); - - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - response.getResult(), - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(presentation4SpecTpl.toJson(), resDeserialize.getResult().toJson()); - } - - - /** - * 输入流数据为空. - */ - @Test - public void testDeserializeCase5() { - byte[] out = null; - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize(out, PresentationE.class, weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), - resDeserialize.getErrorCode().intValue()); - Assert.assertNull(resDeserialize.getResult()); - } - - /** - * 输入流数据非法. - */ - @Test - public void testDeserializeCase6() { - byte[] out = new byte[0]; - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize(out, PresentationE.class, weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), - resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(null, resDeserialize.getResult()); - } - - - /** - * credentialPojo测试. - */ - @Test - public void testDeserializeCase7() { - List credentialPojoList = presentation.getVerifiableCredential(); - CredentialPojo credentialPojo = new CredentialPojo(); - if (credentialPojoList.size() > 0) { - credentialPojo = credentialPojoList.get(0); - } - - ResponseData response = - TransportationFactory.newPdfTransportation().serialize( - credentialPojo, - new ProtocolProperty(EncodeType.CIPHER), - weIdAuthentication - ); - ResponseData resDeserialize = TransportationFactory.newPdfTransportation() - .deserialize( - response.getResult(), - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.ENCRYPT_KEY_NO_PERMISSION.getCode(), - resDeserialize.getErrorCode().intValue()); - } - - /** - * 读入默认模板PDF文件反序列化. - */ - public void testDeserializeCase8() { - - //1. 序列化presentation4MultiCpt为pdf文件 - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./out.pdf"); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - - byte[] bytesArray = getFileByte("./out.pdf"); - - //3. 对读取到byte[]做反序列化 - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - bytesArray, - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(presentation4MultiCpt.toJson(), resDeserialize.getResult().toJson()); - } - - private byte[] getFileByte(String filePath) { - //2. 从pdf文件读取到byte[] - File file = new File(filePath); - byte[] bytesArray = new byte[(int) file.length()]; - try { - - FileInputStream fis = new FileInputStream(file); - fis.read(bytesArray); //read file into bytes[] - fis.close(); - } catch (Exception e) { - e.printStackTrace(); - } - return bytesArray; - } - - /** - * 读入指定模板PDF文件反序列化. - */ - public void testDeserializeCase9() { - - //1. 序列化presentation4MultiCpt为pdf文件 - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test-template-complex-out.pdf"); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - - //2. 从pdf文件读取到byte[] - byte[] bytesArray = getFileByte("./test-template-complex-out.pdf"); - - //3. 对读取到byte[]做反序列化 - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - bytesArray, - PresentationE.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(presentation4MultiCpt.toJson(), resDeserialize.getResult().toJson()); - } - - /** - * 使用原文方式构建协议数据并解析.(无模板) - */ - @Test - public void testDeserialize_credentialList() { - CredentialPojoList credentialPojoList = getCredentialPojoList(presentation4MultiCpt); - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - credentialPojoList, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication); - - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - response.getResult(), - CredentialPojoList.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(credentialPojoList.toJson(), resDeserialize.getResult().toJson()); - } - - /** - * 使用原文方式构建协议数据并解析.(有模板) - */ - @Test - public void testDeserializeWithTemplet_credentialList() { - CredentialPojoList credentialPojoList = getCredentialPojoList(presentation4MultiCpt); - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - credentialPojoList, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template-complex.pdf", - "./out1.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - - byte[] bytesArray = getFileByte("./out1.pdf"); - ResponseData resDeserialize = TransportationFactory - .newPdfTransportation() - .deserialize( - bytesArray, - CredentialPojoList.class, - weIdAuthentication); - LogUtil.info(logger, "deserialize", resDeserialize); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); - Assert.assertEquals(credentialPojoList.toJson(), resDeserialize.getResult().toJson()); - } -} diff --git a/src/test/java/com/webank/weid/full/transportation/TestPdfSerialize.java b/src/test/java/com/webank/weid/full/transportation/TestPdfSerialize.java deleted file mode 100644 index fa8a78cf8..000000000 --- a/src/test/java/com/webank/weid/full/transportation/TestPdfSerialize.java +++ /dev/null @@ -1,525 +0,0 @@ -package com.webank.weid.full.transportation; - -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.webank.weid.common.LogUtil; -import com.webank.weid.constant.ErrorCode; -import com.webank.weid.protocol.base.PresentationE; -import com.webank.weid.protocol.response.ResponseData; -import com.webank.weid.suite.api.transportation.TransportationFactory; -import com.webank.weid.suite.api.transportation.params.EncodeType; -import com.webank.weid.suite.api.transportation.params.ProtocolProperty; - -/** - * test serialize class. - */ -public class TestPdfSerialize extends TestBaseTransportation { - - private static final Logger logger = LoggerFactory.getLogger(TestPdfSerialize.class); - private static PresentationE presentation; - private static PresentationE presentation4MlCpt; - private static PresentationE presentation4MultiCpt; - private static PresentationE presentation4SpecTpl; - - @Override - public synchronized void testInit() { - super.testInit(); - super.testInit4MlCpt(); - super.testInit4MultiCpt(); - super.testInitSpecTplCpt(); - - presentation = getPresentationE(); - presentation4MlCpt = getPresentationE4MlCpt(); - presentation4MultiCpt = getPresentationE4MultiCpt(); - presentation4SpecTpl = getPresentationE4SpecTplCpt(); - } - - - /** - * 单级CPT测试. - */ - @Test - public void testSerializeCase1() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - - /** - * 多级CPT测试. - */ - @Test - public void testSerializeCase2() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation4MlCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - - /** - * 多CPT测试. - */ - @Test - public void testSerializeCase3() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - /** - * 多CPT,指定已存在目录,不指定文件名,生成文件测试. - */ - public void testSerializeCase31() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - - /** - * 多CPT,指定已存在目录,指定文件名,生成文件测试. - */ - public void testSerializeCase32() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./out.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定不存在目录,不指定文件名,生成文件测试. - */ - public void testSerializeCase33() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./out" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT,指定已存在多层目录,不指定文件名,生成文件测试. - */ - public void testSerializeCase34() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定已存在多层目录,指定文件名,生成文件测试. - */ - public void testSerializeCase35() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test/out.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定不存在多层目录,不指定文件名,生成文件测试. - */ - public void testSerializeCase36() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test/test/test/test/out" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定已存在包含多个"."的路径,生成文件测试. - */ - public void testSerializeCase37() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test/test.test.test" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定已存在包含多个"."的路径和文件名,生成文件测试. - */ - public void testSerializeCase38() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test/te.te.te/a.b.c.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定不存在包含多个"."的路径和文件名,生成文件测试. - */ - public void testSerializeCase39() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "./test/test.test.test/a.b.c.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 多CPT测试,指定输出目录为空. - */ - public void testSerializeCase310() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.ILLEGAL_INPUT.getCode(), response.getErrorCode().intValue()); - Assert.assertTrue(!response.getResult()); - } - - - /** - * 使用密文方式构建协议数据. - */ - @Test - public void testSerializeCase4() { - ResponseData response = TransportationFactory - .newPdfTransportation().specify(verifier) - .serialize( - presentation, - new ProtocolProperty(EncodeType.CIPHER), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - /** - * 传入协议配置编解码方式为null. - */ - @Test - public void testSerializeCase5() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize(presentation, - new ProtocolProperty(null), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.TRANSPORTATION_PROTOCOL_ENCODE_ERROR.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - - /** - * 传入的协议配置为null. - */ - @Test - public void testSerializeCase6() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation, - null, - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.TRANSPORTATION_PROTOCOL_PROPERTY_ERROR.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - * 传入presentation为null. - */ - @Test - public void testSerializeCase7() { - PresentationE presentation = null; - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.TRANSPORTATION_PROTOCOL_DATA_INVALID.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - * 传入weIdAuthentication为null. - */ - @Test - public void testSerializeCase8() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - presentation, - new ProtocolProperty(EncodeType.ORIGINAL), - null - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.WEID_AUTHORITY_INVALID.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - * 指定PDF模板测试. - */ - @Test - public void testSerializeCase9() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - /** - * 指定PDF模板测试. - */ - public void testSerializeCase91() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template.pdf", - "./" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - * 指定复杂PDF模板测试. - */ - @Test - public void testSerializeCase10() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template-complex.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - /** - * 指定复杂PDF模板测试. - */ - public void testSerializeCase101() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4MultiCpt, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template-complex.pdf", - "./test-template-complex-out.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } - - /** - * 传入指定模板目录为空字符串. - */ - @Test - public void testSerializeCase11() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.ILLEGAL_INPUT.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - * 传入指定模板目录为非法字符串. - */ - @Test - public void testSerializeCase12() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "illegal" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.ILLEGAL_INPUT.getCode(), response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - * 传入模板与披露信息不匹配. - */ - @Test - public void testSerializeCase13() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - presentation4SpecTpl, - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template-complex.pdf" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), - response.getErrorCode().intValue()); - Assert.assertNull(response.getResult()); - } - - /** - *将credentialList序列化成pdf(指定模板). - */ - @Test - public void testSerializeWithTemplate_credentialList() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serializeWithTemplate( - getCredentialPojoList(presentation4MultiCpt), - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication, - "src/test/resources/test-template-complex.pdf", - "./" - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals( - ErrorCode.SUCCESS.getCode(), - response.getErrorCode().intValue()); - Assert.assertTrue(response.getResult()); - } - - /** - *将credentialList序列化成pdf(不指定模板). - */ - @Test - public void testSerialize_credentialList() { - ResponseData response = TransportationFactory - .newPdfTransportation() - .serialize( - getCredentialPojoList(presentation4MultiCpt), - new ProtocolProperty(EncodeType.ORIGINAL), - weIdAuthentication - ); - LogUtil.info(logger, "serialize", response); - Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); - Assert.assertNotNull(response.getResult()); - } -} diff --git a/src/test/java/com/webank/weid/full/transportation/TestPdfTransportation.java b/src/test/java/com/webank/weid/full/transportation/TestPdfTransportation.java new file mode 100644 index 000000000..1c7ade989 --- /dev/null +++ b/src/test/java/com/webank/weid/full/transportation/TestPdfTransportation.java @@ -0,0 +1,680 @@ +package com.webank.weid.full.transportation; + +import java.io.File; +import java.io.FileInputStream; +import java.util.List; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.webank.weid.common.LogUtil; +import com.webank.weid.constant.ErrorCode; +import com.webank.weid.protocol.base.CredentialPojo; +import com.webank.weid.protocol.base.CredentialPojoList; +import com.webank.weid.protocol.base.PresentationE; +import com.webank.weid.protocol.response.ResponseData; +import com.webank.weid.suite.api.transportation.TransportationFactory; +import com.webank.weid.suite.api.transportation.params.EncodeType; +import com.webank.weid.suite.api.transportation.params.ProtocolProperty; + +/** + * test serialize class. + */ +public class TestPdfTransportation extends TestBaseTransportation { + + private static final String PRESENTATION_PDF = "presentationFromPDF"; + private static final Logger logger = LoggerFactory.getLogger(TestPdfTransportation.class); + private static PresentationE presentation; + private static PresentationE presentation4MlCpt; + private static PresentationE presentation4MultiCpt; + private static PresentationE presentation4SpecTpl; + + @Override + public synchronized void testInit() { + super.testInit(); + super.testInit4MlCpt(); + super.testInit4MultiCpt(); + super.testInitSpecTplCpt(); + + presentation = getPresentationE(); + presentation4MlCpt = getPresentationE4MlCpt(); + presentation4MultiCpt = getPresentationE4MultiCpt(); + presentation4SpecTpl = getPresentationE4SpecTplCpt(); + } + + + /** + * 单级CPT测试. + */ + @Test + public void testSerializeCase1() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize( + presentation, + new ProtocolProperty(EncodeType.ORIGINAL) + ); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + + /** + * 多级CPT测试. + */ + @Test + public void testSerializeCase2() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MlCpt, new ProtocolProperty(EncodeType.ORIGINAL)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + + /** + * 多CPT测试. + */ + @Test + public void testSerializeCase3() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, new ProtocolProperty(EncodeType.ORIGINAL)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + /** + * 多CPT,指定已存在目录,不指定文件名,生成文件测试. + */ + public void testSerializeCase31() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, new ProtocolProperty(EncodeType.ORIGINAL), "./"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + + /** + * 多CPT,指定已存在目录,指定文件名,生成文件测试. + */ + public void testSerializeCase32() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize( + presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./out.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定不存在目录,不指定文件名,生成文件测试. + */ + public void testSerializeCase33() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./out"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT,指定已存在多层目录,不指定文件名,生成文件测试. + */ + public void testSerializeCase34() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定已存在多层目录,指定文件名,生成文件测试. + */ + public void testSerializeCase35() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test/out.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定不存在多层目录,不指定文件名,生成文件测试. + */ + public void testSerializeCase36() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test/test/test/test/out"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定已存在包含多个"."的路径,生成文件测试. + */ + public void testSerializeCase37() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test/test.test.test"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定已存在包含多个"."的路径和文件名,生成文件测试. + */ + public void testSerializeCase38() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test/te.te.te/a.b.c.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定不存在包含多个"."的路径和文件名,生成文件测试. + */ + public void testSerializeCase39() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test/test.test.test/a.b.c.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 多CPT测试,指定输出目录为空. + */ + public void testSerializeCase310() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + ""); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.ILLEGAL_INPUT.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(!response.getResult()); + } + + + /** + * 使用密文方式构建协议数据. + */ + @Test + public void testSerializeCase4() { + ResponseData response = TransportationFactory.newPdfTransportation() + .specify(verifier) + .serialize( + presentation, + new ProtocolProperty(EncodeType.CIPHER)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + /** + * 传入协议配置编解码方式为null. + */ + @Test + public void testSerializeCase5() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation, + new ProtocolProperty(null)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PROTOCOL_ENCODE_ERROR.getCode(), + response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + + /** + * 传入的协议配置为null. + */ + @Test + public void testSerializeCase6() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation, null); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PROTOCOL_PROPERTY_ERROR.getCode(), + response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + /** + * 传入presentation为null. + */ + @Test + public void testSerializeCase7() { + PresentationE presentation = null; + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation, new ProtocolProperty(EncodeType.ORIGINAL)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PROTOCOL_DATA_INVALID.getCode(), + response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + /** + * 指定PDF模板测试. + */ + @Test + public void testSerializeCase9() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.SUCCESS.getCode(), + response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + /** + * 指定PDF模板测试. + */ + public void testSerializeCase91() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template.pdf", + "./"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.SUCCESS.getCode(), + response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + * 指定复杂PDF模板测试. + */ + @Test + public void testSerializeCase10() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template-complex.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.SUCCESS.getCode(), + response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + /** + * 指定复杂PDF模板测试. + */ + public void testSerializeCase101() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template-complex.pdf", + "./test-template-complex-out.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.SUCCESS.getCode(), + response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + /** + * 传入指定模板目录为空字符串. + */ + @Test + public void testSerializeCase11() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty(EncodeType.ORIGINAL), + ""); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.ILLEGAL_INPUT.getCode(), + response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + /** + * 传入指定模板目录为非法字符串. + */ + @Test + public void testSerializeCase12() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty(EncodeType.ORIGINAL), + "illegal"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.ILLEGAL_INPUT.getCode(), response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + /** + * 传入模板与披露信息不匹配. + */ + @Test + public void testSerializeCase13() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template-complex.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), + response.getErrorCode().intValue()); + Assert.assertNull(response.getResult()); + } + + /** + *将credentialList序列化成pdf(指定模板). + */ + @Test + @Ignore + public void testSerializeWithTemplate_credentialList() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + getCredentialPojoList(presentation4MultiCpt), + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template-complex.pdf", + "./"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals( + ErrorCode.SUCCESS.getCode(), + response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + } + + /** + *将credentialList序列化成pdf(不指定模板). + */ + @Test + public void testSerialize_credentialList() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize( + getCredentialPojoList(presentation4MultiCpt), + new ProtocolProperty(EncodeType.ORIGINAL)); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertNotNull(response.getResult()); + } + + //deserialize测试用例 + + /** + * 使用原文方式构建协议数据并解析. + */ + @Test + public void testDeserializeCase1() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation, new ProtocolProperty((EncodeType.ORIGINAL))); + + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize( + response.getResult(), + PresentationE.class, + weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(presentation.toJson(), resDeserialize.getResult().toJson()); + } + + /** + * 使用密文方式构建协议数据并解析. + */ + @Test + public void testDeserializeCase2() { + ResponseData response = TransportationFactory.newPdfTransportation() + .specify(verifier) + .serialize(presentation4MlCpt, new ProtocolProperty((EncodeType.CIPHER))); + + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .specify(verifier) + .deserialize(response.getResult(), PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(presentation4MlCpt.toJson(), resDeserialize.getResult().toJson()); + } + + /** + * 未设置verifier导致的无权限获取密钥数据. + */ + @Test + public void testDeserializeCase3() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MlCpt, new ProtocolProperty((EncodeType.CIPHER))); + + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(response.getResult(), PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals( + ErrorCode.ENCRYPT_KEY_NO_PERMISSION.getCode(), + resDeserialize.getErrorCode().intValue()); + } + + /** + * 对指定PDF模板序列化并解析. + */ + @Test + public void testDeserializeCase4() { + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + presentation4SpecTpl, + new ProtocolProperty((EncodeType.ORIGINAL)), + "src/test/resources/test-template.pdf"); + + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(response.getResult(), PresentationE.class, weIdAuthentication); + + PresentationE presentationE = new PresentationE(); + + if (resDeserialize.getErrorCode() == ErrorCode.SUCCESS.getCode()) { + presentationE = resDeserialize.getResult(); + } + if (presentationE.getType().contains(PRESENTATION_PDF)) { + List typeList = presentationE.getType(); + typeList.remove(PRESENTATION_PDF); + presentationE.setType(typeList); + } + + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(presentation4SpecTpl.toJson(), presentationE.toJson()); + } + + + /** + * 输入流数据为空. + */ + @Test + public void testDeserializeCase5() { + byte[] out = null; + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(out, PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), + resDeserialize.getErrorCode().intValue()); + Assert.assertNull(resDeserialize.getResult()); + } + + /** + * 输入流数据非法. + */ + @Test + public void testDeserializeCase6() { + byte[] out = new byte[0]; + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(out, PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals( + ErrorCode.TRANSPORTATION_PDF_TRANSFER_ERROR.getCode(), + resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(null, resDeserialize.getResult()); + } + + + /** + * credentialPojo测试. + */ + @Test + public void testDeserializeCase7() { + List credentialPojoList = presentation.getVerifiableCredential(); + CredentialPojo credentialPojo = new CredentialPojo(); + if (credentialPojoList.size() > 0) { + credentialPojo = credentialPojoList.get(0); + } + + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(credentialPojo, new ProtocolProperty(EncodeType.CIPHER)); + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize( + response.getResult(), + PresentationE.class, + weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals( + ErrorCode.ENCRYPT_KEY_NO_PERMISSION.getCode(), + resDeserialize.getErrorCode().intValue()); + } + + /** + * 读入默认模板PDF文件反序列化. + */ + public void testDeserializeCase8() { + + //1. 序列化presentation4MultiCpt为pdf文件 + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize( + presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./out.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + + byte[] bytesArray = getFileByte("./out.pdf"); + + //3. 对读取到byte[]做反序列化 + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(bytesArray, PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(presentation4MultiCpt.toJson(), resDeserialize.getResult().toJson()); + } + + private byte[] getFileByte(String filePath) { + //2. 从pdf文件读取到byte[] + File file = new File(filePath); + byte[] bytesArray = new byte[(int) file.length()]; + try { + + FileInputStream fis = new FileInputStream(file); + fis.read(bytesArray); //read file into bytes[] + fis.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return bytesArray; + } + + /** + * 读入指定模板PDF文件反序列化. + */ + public void testDeserializeCase9() { + + //1. 序列化presentation4MultiCpt为pdf文件 + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(presentation4MultiCpt, + new ProtocolProperty(EncodeType.ORIGINAL), + "./test-template-complex-out.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + + //2. 从pdf文件读取到byte[] + byte[] bytesArray = getFileByte("./test-template-complex-out.pdf"); + + //3. 对读取到byte[]做反序列化 + ResponseData resDeserialize = TransportationFactory.newPdfTransportation() + .deserialize(bytesArray, PresentationE.class, weIdAuthentication); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(presentation4MultiCpt.toJson(), resDeserialize.getResult().toJson()); + } + + /** + * 使用原文方式构建协议数据并解析.(无模板) + */ + @Test + public void testDeserialize_credentialList() { + CredentialPojoList credentialPojoList = getCredentialPojoList(presentation4MultiCpt); + ResponseData response = TransportationFactory.newPdfTransportation() + .serialize(credentialPojoList, new ProtocolProperty(EncodeType.ORIGINAL)); + + ResponseData resDeserialize = TransportationFactory + .newPdfTransportation() + .deserialize(response.getResult(), CredentialPojoList.class, weIdAuthentication); + System.out.println(resDeserialize.getResult().toJson()); + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(credentialPojoList.toJson(), resDeserialize.getResult().toJson()); + } + + /** + * 使用原文方式构建协议数据并解析.(有模板) + */ + @Test + public void testDeserializeWithTemplet_credentialList() { + CredentialPojoList credentialPojoList = getCredentialPojoList(presentation4MultiCpt); + ResponseData response = TransportationFactory.newPdfTransportation() + .serializeWithTemplate( + credentialPojoList, + new ProtocolProperty(EncodeType.ORIGINAL), + "src/test/resources/test-template-complex.pdf", + "./out1.pdf"); + LogUtil.info(logger, "serialize", response); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), response.getErrorCode().intValue()); + Assert.assertTrue(response.getResult()); + + byte[] bytesArray = getFileByte("./out1.pdf"); + ResponseData resDeserialize = TransportationFactory + .newPdfTransportation() + .deserialize(bytesArray, CredentialPojoList.class, weIdAuthentication); + + LogUtil.info(logger, "deserialize", resDeserialize); + Assert.assertEquals(ErrorCode.SUCCESS.getCode(), resDeserialize.getErrorCode().intValue()); + Assert.assertEquals(credentialPojoList.toJson(), resDeserialize.getResult().toJson()); + } + +}