Skip to content

Commit

Permalink
Merge pull request #177 from yg3630536/feature/verify-offline
Browse files Browse the repository at this point in the history
* add code for verify credential offline
  • Loading branch information
chaoxinhu committed Apr 24, 2020
2 parents 041fe0f + cd03719 commit 076cbc9
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 16 deletions.
9 changes: 9 additions & 0 deletions src/main/java/com/webank/weid/rpc/CredentialPojoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ ResponseData<Boolean> verify(
PresentationE presentationE
);

/**
* Verify the validity of a credential. Public key must be provided. This is offline interface.
*
* @param issuerPublicKey the specified public key which used to verify credential signature
* @param credential the credential
* @return the verification result. True if yes, false otherwise with exact verify error codes
*/
ResponseData<Boolean> verifyOffline(WeIdPublicKey issuerPublicKey, CredentialPojo credential);

/**
* verify the presentation and pdf information.
* @param pdfTemplatePath path of pdf template
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,14 @@ private static void addSaltForList(
}
}

private static ErrorCode verifyContent(CredentialPojo credential, String publicKey) {
private static ErrorCode verifyContent(
CredentialPojo credential,
String publicKey,
boolean offLine
) {
ErrorCode errorCode;
try {
errorCode = verifyContentInner(credential, publicKey);
errorCode = verifyContentInner(credential, publicKey, offLine);
} catch (WeIdBaseException ex) {
logger.error("[verifyContent] verify credential has exception.", ex);
return ex.getErrorCode();
Expand Down Expand Up @@ -529,7 +533,11 @@ private static ErrorCode verifyTimestampClaim(CredentialPojo credential) {
return ErrorCode.SUCCESS;
}

private static ErrorCode verifyContentInner(CredentialPojo credential, String publicKey) {
private static ErrorCode verifyContentInner(
CredentialPojo credential,
String publicKey,
boolean offline
) {
ErrorCode checkResp = CredentialPojoUtils.isCredentialPojoValid(credential);
if (ErrorCode.SUCCESS.getCode() != checkResp.getCode()) {
return checkResp;
Expand All @@ -543,7 +551,7 @@ private static ErrorCode verifyContentInner(CredentialPojo credential, String pu
.intValue() || credential.getCptId() == CredentialConstant.EMBEDDED_TIMESTAMP_CPT
.intValue()) {
// This is a multi-signed Credential. We firstly verify itself (i.e. external check)
ErrorCode errorCode = verifySingleSignedCredential(credential, publicKey);
ErrorCode errorCode = verifySingleSignedCredential(credential, publicKey, offline);
if (errorCode != ErrorCode.SUCCESS) {
return errorCode;
}
Expand Down Expand Up @@ -571,7 +579,7 @@ private static ErrorCode verifyContentInner(CredentialPojo credential, String pu
} else {
innerCredential = (CredentialPojo) innerCredentialObject;
}
errorCode = verifyContentInner(innerCredential, null);
errorCode = verifyContentInner(innerCredential, null, offline);
if (errorCode != ErrorCode.SUCCESS) {
return errorCode;
}
Expand All @@ -582,17 +590,19 @@ private static ErrorCode verifyContentInner(CredentialPojo credential, String pu
}
return ErrorCode.SUCCESS;
}
return verifySingleSignedCredential(credential, publicKey);
return verifySingleSignedCredential(credential, publicKey, offline);
}

private static ErrorCode verifySingleSignedCredential(
CredentialPojo credential,
String publicKey
String publicKey,
boolean offline
) {
ErrorCode errorCode = verifyCptFormat(
credential.getCptId(),
credential.getClaim(),
CredentialPojoUtils.isSelectivelyDisclosed(credential.getSalt())
CredentialPojoUtils.isSelectivelyDisclosed(credential.getSalt()),
offline
);
if (ErrorCode.SUCCESS.getCode() != errorCode.getCode()) {
return errorCode;
Expand Down Expand Up @@ -656,8 +666,11 @@ private static ErrorCode verifySingleSignedCredential(
}


private static ErrorCode verifyCptFormat(Integer cptId, Map<String, Object> claim,
boolean isSelectivelyDisclosed) {
private static ErrorCode verifyCptFormat(
Integer cptId, Map<String, Object> claim,
boolean isSelectivelyDisclosed,
boolean offline
) {
if (cptId == CredentialConstant.CREDENTIALPOJO_EMBEDDED_SIGNATURE_CPT.intValue()) {
if (!claim.containsKey("credentialList")) {
return ErrorCode.CREDENTIAL_CLAIM_DATA_ILLEGAL;
Expand All @@ -675,6 +688,9 @@ private static ErrorCode verifyCptFormat(Integer cptId, Map<String, Object> clai
}
}
try {
if (offline) {
return ErrorCode.SUCCESS;
}
String claimStr = DataToolUtils.serialize(claim);
Cpt cpt = getCptService().queryCpt(cptId).getResult();
if (cpt == null) {
Expand Down Expand Up @@ -905,10 +921,10 @@ private static ResponseData<Boolean> verifyLiteCredential(
);
} catch (Exception e) {
logger.error("[verifyContent] verify signature fail.", e);
return new ResponseData<Boolean>(true, ErrorCode.CREDENTIAL_SIGNATURE_BROKEN);
return new ResponseData<Boolean>(false, ErrorCode.CREDENTIAL_SIGNATURE_BROKEN);
}
if (!result) {
return new ResponseData<Boolean>(true, ErrorCode.CREDENTIAL_SIGNATURE_BROKEN);
return new ResponseData<Boolean>(false, ErrorCode.CREDENTIAL_SIGNATURE_BROKEN);
}
return new ResponseData<Boolean>(true, ErrorCode.SUCCESS);
}
Expand Down Expand Up @@ -1333,7 +1349,7 @@ public ResponseData<Boolean> verify(String issuerWeId, CredentialPojo credential
if (isLiteCredential(credential)) {
return verifyLiteCredential(credential, null);
}
ErrorCode errorCode = verifyContent(credential, null);
ErrorCode errorCode = verifyContent(credential, null, false);
if (errorCode.getCode() != ErrorCode.SUCCESS.getCode()) {
logger.error("[verify] credential verify failed. error message :{}", errorCode);
return new ResponseData<Boolean>(false, errorCode);
Expand All @@ -1359,7 +1375,7 @@ public ResponseData<Boolean> verify(
if (isLiteCredential(credential)) {
return verifyLiteCredential(credential, issuerPublicKey.getPublicKey());
}
ErrorCode errorCode = verifyContent(credential, publicKey);
ErrorCode errorCode = verifyContent(credential, publicKey, false);
if (errorCode.getCode() != ErrorCode.SUCCESS.getCode()) {
return new ResponseData<Boolean>(false, errorCode);
}
Expand Down Expand Up @@ -1421,7 +1437,7 @@ public ResponseData<Boolean> verify(
return verifyZkpCredential(credential);

}
ErrorCode verifyCredentialResult = verifyContent(credential, null);
ErrorCode verifyCredentialResult = verifyContent(credential, null, false);
if (verifyCredentialResult.getCode() != ErrorCode.SUCCESS.getCode()) {
logger.error(
"[verify] verify credential {} failed.", credential);
Expand All @@ -1435,7 +1451,32 @@ public ResponseData<Boolean> verify(
return new ResponseData<Boolean>(false, ErrorCode.UNKNOW_ERROR);
}
}

/* (non-Javadoc)
* @see com.webank.weid.rpc.CredentialPojoService#verify(
* com.webank.weid.protocol.base.CredentialPojo,
* com.webank.weid.protocol.base.WeIdPublicKey
* )
*/
@Override
public ResponseData<Boolean> verifyOffline(
WeIdPublicKey issuerPublicKey,
CredentialPojo credential) {

String publicKey = issuerPublicKey.getPublicKey();
if (StringUtils.isEmpty(publicKey)) {
return new ResponseData<Boolean>(false, ErrorCode.CREDENTIAL_PUBLIC_KEY_NOT_EXISTS);
}
if (isLiteCredential(credential)) {
return verifyLiteCredential(credential, issuerPublicKey.getPublicKey());
}
ErrorCode errorCode = verifyContent(credential, publicKey, true);
if (errorCode.getCode() != ErrorCode.SUCCESS.getCode()) {
return new ResponseData<Boolean>(false, errorCode);
}
return new ResponseData<Boolean>(true, ErrorCode.SUCCESS);
}

@Override
public ResponseData<Boolean> verifyPresentationFromPdf(
String pdfTemplatePath,
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/com/webank/weid/util/DataToolUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,24 @@ public static boolean verifySignature(
BigInteger extractedPublicKey = signatureToPublicKey(message, signatureData);
return extractedPublicKey.equals(publicKey);
}


/**
* Verify whether the message and the Signature matches the given public Key.
*
* @param message This should be from the same plain-text source with the signature Data.
* @param signature this is a signature string of Base64.
* @param publicKey the string is a publicKey.
* @return true if yes, false otherwise
* @throws SignatureException Signature is the exception.
*/
public static boolean verifySignature(
String message,
String signature,
String publicKey)
throws SignatureException {
return verifySignature(message, signature, new BigInteger(publicKey));
}

/**
* eecrypt the data.
*
Expand Down

0 comments on commit 076cbc9

Please sign in to comment.