@@ -492,6 +492,79 @@ contract Identity is Storage, IIdentity, Version {
492
492
return false ;
493
493
}
494
494
495
+ /**
496
+ * @dev Checks if a claim is valid. Claims issued by the identity are self-attested claims. They do not have a
497
+ * built-in revocation mechanism and are considered valid as long as their signature is valid and they are still
498
+ * stored by the identity contract.
499
+ * @param _identity the identity contract related to the claim
500
+ * @param claimTopic the claim topic of the claim
501
+ * @param sig the signature of the claim
502
+ * @param data the data field of the claim
503
+ * @return claimValid true if the claim is valid, false otherwise
504
+ */
505
+ function isClaimValid (
506
+ IIdentity _identity ,
507
+ uint256 claimTopic ,
508
+ bytes memory sig ,
509
+ bytes memory data )
510
+ public override virtual view returns (bool claimValid )
511
+ {
512
+ bytes32 dataHash = keccak256 (abi.encode (_identity, claimTopic, data));
513
+ // Use abi.encodePacked to concatenate the message prefix and the message to sign.
514
+ bytes32 prefixedHash = keccak256 (abi.encodePacked ("\x19Ethereum Signed Message:\n32 " , dataHash));
515
+
516
+ // Recover address of data signer
517
+ address recovered = getRecoveredAddress (sig, prefixedHash);
518
+
519
+ // Take hash of recovered address
520
+ bytes32 hashedAddr = keccak256 (abi.encode (recovered));
521
+
522
+ // Does the trusted identifier have they key which signed the user's claim?
523
+ // && (isClaimRevoked(_claimId) == false)
524
+ if (keyHasPurpose (hashedAddr, 3 )) {
525
+ return true ;
526
+ }
527
+
528
+ return false ;
529
+ }
530
+
531
+ /**
532
+ * @dev returns the address that signed the given data
533
+ * @param sig the signature of the data
534
+ * @param dataHash the data that was signed
535
+ * returns the address that signed dataHash and created the signature sig
536
+ */
537
+ function getRecoveredAddress (bytes memory sig , bytes32 dataHash )
538
+ public
539
+ pure
540
+ returns (address addr )
541
+ {
542
+ bytes32 ra;
543
+ bytes32 sa;
544
+ uint8 va;
545
+
546
+ // Check the signature length
547
+ if (sig.length != 65 ) {
548
+ return address (0 );
549
+ }
550
+
551
+ // Divide the signature in r, s and v variables
552
+ // solhint-disable-next-line no-inline-assembly
553
+ assembly {
554
+ ra := mload (add (sig, 32 ))
555
+ sa := mload (add (sig, 64 ))
556
+ va := byte (0 , mload (add (sig, 96 )))
557
+ }
558
+
559
+ if (va < 27 ) {
560
+ va += 27 ;
561
+ }
562
+
563
+ address recoveredAddress = ecrecover (dataHash, va, ra, sa);
564
+
565
+ return (recoveredAddress);
566
+ }
567
+
495
568
/**
496
569
* @notice Initializer internal function for the Identity contract.
497
570
*
0 commit comments