Search in sources :

Example 1 with SignatureAlgorithmInterface

use of de.uni_koblenz.aggrimm.icp.crypto.sign.algorithm.SignatureAlgorithmInterface in project webofneeds by researchstudio-sat.

the class WonVerifier method verify.

// TODO exceptions
public boolean verify(Map<String, PublicKey> publicKeys) throws Exception {
    // check if there are any signatures at all
    if (verificationState.getSignatures().size() == 0) {
        verificationState.verificationFailed("No signatures found");
        return verificationState.isVerificationPassed();
    }
    // check that the default graph is empty
    if (dataset.getDefaultModel().listStatements().hasNext()) {
        verificationState.verificationFailed("unsigned data found in default graph");
        return verificationState.isVerificationPassed();
    }
    // Get algorithms to use from signature data
    SignatureAlgorithmInterface canonicAlgorithm = new SignatureAlgorithmFisteus2010();
    SignatureAlgorithmInterface hashingAlgorithm = canonicAlgorithm;
    MessageDigest messageDigest = MessageDigest.getInstance(ENV_HASH_ALGORITHM, SIGNING_ALGORITHM_PROVIDER);
    // verify each signature's graph
    for (WonSignatureData wonSignatureData : verificationState.getSignatures()) {
        // make sure the signed graph specified in signature exists in the message
        if (!dataset.containsNamedModel(wonSignatureData.getSignedGraphUri())) {
            logger.debug("cannot verify signature {} as it is not part of this message ", wonSignatureData.getSignatureUri());
            continue;
        // TODO: fetch the external reference and check it here
        // verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "No signed graph found for " +
        // "signature " + wonSignatureData.getSignatureUri());
        // return verificationState.isVerificationPassed();
        }
        // is the signature there?
        String sigString = wonSignatureData.getSignatureValue();
        if (sigString == null) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "Failed to compute a signature value " + wonSignatureData.getSignatureUri());
            return verificationState.isVerificationPassed();
        }
        if (sigString.length() == 0) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "Computed an empty signature value " + wonSignatureData.getSignatureUri());
            return verificationState.isVerificationPassed();
        }
        // do we have the public key?
        PublicKey publicKey = publicKeys.get(wonSignatureData.getVerificationCertificateUri());
        if (publicKey == null) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "No public key found for " + wonSignatureData.getSignatureUri());
            return verificationState.isVerificationPassed();
        }
        // check if its fingerprint matches the fingerprint in the signature
        String fingerprint = Base64.getEncoder().encodeToString(messageDigest.digest(publicKey.getEncoded()));
        if (!wonSignatureData.getPublicKeyFingerprint().equals(fingerprint)) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "Fingerprint computed for the " + "specified public key " + wonSignatureData.getVerificationCertificateUri() + " is " + fingerprint + ", " + "which differs from the value found in signature " + wonSignatureData.getSignatureUri());
            return verificationState.isVerificationPassed();
        }
        // normalize, hash and post-hash signed graph data
        GraphCollection inputGraph = ModelConverter.modelToGraphCollection(wonSignatureData.getSignedGraphUri(), dataset);
        canonicAlgorithm.canonicalize(inputGraph);
        canonicAlgorithm.postCanonicalize(inputGraph);
        hashingAlgorithm.hash(inputGraph, ENV_HASH_ALGORITHM);
        hashingAlgorithm.postHash(inputGraph);
        // check the hash of the data. It must be identical to the hash in the signature
        BigInteger hashValue = inputGraph.getSignature().getHash();
        String hashString = Base64.getEncoder().encodeToString(hashValue.toByteArray());
        if (!wonSignatureData.getHash().equals(hashString)) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "Computed hash value " + hashString + " differs from value " + wonSignatureData.getHash() + " found in signature " + wonSignatureData.getSignatureUri());
            if (logger.isDebugEnabled()) {
                StringWriter sw = new StringWriter();
                RDFDataMgr.write(sw, dataset.getNamedModel(wonSignatureData.getSignedGraphUri()), Lang.TRIG);
                logger.debug("wrong signature hash for graph {} with content: {}", wonSignatureData.getSignedGraphUri(), sw.toString());
            }
            return verificationState.isVerificationPassed();
        }
        // verify the signature
        Signature sig = Signature.getInstance(WonSigner.SIGNING_ALGORITHM_NAME, SIGNING_ALGORITHM_PROVIDER);
        sig.initVerify(publicKey);
        sig.update(hashValue.toByteArray());
        // Verify
        byte[] sigBytes = Base64.getDecoder().decode(sigString);
        if (!sig.verify(sigBytes)) {
            verificationState.setVerificationFailed(wonSignatureData.getSignatureUri(), "Failed to verify " + wonSignatureData.getSignatureUri() + " with public key " + wonSignatureData.getVerificationCertificateUri());
            // interrupt verification process if one of the graph's verification fails
            return verificationState.isVerificationPassed();
        }
    }
    return verificationState.isVerificationPassed();
}
Also used : GraphCollection(de.uni_koblenz.aggrimm.icp.crypto.sign.graph.GraphCollection) StringWriter(java.io.StringWriter) PublicKey(java.security.PublicKey) Signature(java.security.Signature) WonSignatureData(won.protocol.message.WonSignatureData) BigInteger(java.math.BigInteger) SignatureAlgorithmInterface(de.uni_koblenz.aggrimm.icp.crypto.sign.algorithm.SignatureAlgorithmInterface) SignatureAlgorithmFisteus2010(de.uni_koblenz.aggrimm.icp.crypto.sign.algorithm.algorithm.SignatureAlgorithmFisteus2010) MessageDigest(java.security.MessageDigest)

Aggregations

SignatureAlgorithmInterface (de.uni_koblenz.aggrimm.icp.crypto.sign.algorithm.SignatureAlgorithmInterface)1 SignatureAlgorithmFisteus2010 (de.uni_koblenz.aggrimm.icp.crypto.sign.algorithm.algorithm.SignatureAlgorithmFisteus2010)1 GraphCollection (de.uni_koblenz.aggrimm.icp.crypto.sign.graph.GraphCollection)1 StringWriter (java.io.StringWriter)1 BigInteger (java.math.BigInteger)1 MessageDigest (java.security.MessageDigest)1 PublicKey (java.security.PublicKey)1 Signature (java.security.Signature)1 WonSignatureData (won.protocol.message.WonSignatureData)1