Example usage for org.bouncycastle.openpgp PGPKeyValidationException PGPKeyValidationException

List of usage examples for org.bouncycastle.openpgp PGPKeyValidationException PGPKeyValidationException

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp PGPKeyValidationException PGPKeyValidationException.

Prototype

public PGPKeyValidationException(String message) 

Source Link

Usage

From source file:org.kontalk.xmppserver.pgp.PGPUtils.java

License:Open Source License

public static PGPPublicKeyRing merge(PGPPublicKeyRing oldRing, PGPPublicKeyRing newRing)
        throws PGPException, IOException {
    if (!equals(oldRing, newRing)) {
        throw new PGPKeyValidationException("keys are not equal");
    }//from   ww w .j av a2 s  .  c o  m

    // remember which certs we already added. this is cheaper than semantic deduplication
    Set<byte[]> certs = new TreeSet<>(new Comparator<byte[]>() {
        public int compare(byte[] left, byte[] right) {
            // check for length equality
            if (left.length != right.length) {
                return left.length - right.length;
            }
            // compare byte-by-byte
            for (int i = 0; i < left.length; i++) {
                if (left[i] != right[i]) {
                    return (left[i] & 0xff) - (right[i] & 0xff);
                }
            }
            // ok they're the same
            return 0;
        }
    });

    PGPPublicKeyRing result = oldRing;
    PGPPublicKeyRing candidate = newRing;

    // Pre-load all existing certificates
    for (@SuppressWarnings("unchecked")
    Iterator<PGPPublicKey> i = result.getPublicKeys(); i.hasNext();) {
        PGPPublicKey key = i.next();
        for (@SuppressWarnings("unchecked")
        Iterator<PGPSignature> j = key.getSignatures(); j.hasNext();) {
            PGPSignature cert = j.next();
            certs.add(cert.getEncoded());
        }
    }

    for (@SuppressWarnings("unchecked")
    Iterator<PGPPublicKey> i = candidate.getPublicKeys(); i.hasNext();) {
        PGPPublicKey key = i.next();

        final PGPPublicKey resultKey = result.getPublicKey(key.getKeyID());
        if (resultKey == null) {
            // otherwise, just insert the public key
            result = PGPPublicKeyRing.insertPublicKey(result, key);
            continue;
        }

        // Modifiable version of the old key, which we merge stuff into (keep old for comparison)
        PGPPublicKey modified = resultKey;

        // Iterate certifications
        for (@SuppressWarnings("unchecked")
        Iterator<PGPSignature> j = key.getSignatures(); j.hasNext();) {
            PGPSignature cert = j.next();
            byte[] encoded = cert.getEncoded();
            // Known cert, skip it
            if (certs.contains(encoded)) {
                continue;
            }
            certs.add(encoded);
            modified = PGPPublicKey.addCertification(modified, cert);
        }

        // If this is a subkey, merge it in and stop here
        if (!key.isMasterKey()) {
            if (modified != resultKey) {
                result = PGPPublicKeyRing.insertPublicKey(result, modified);
            }
            continue;
        }

        // Copy over all user id certificates
        for (@SuppressWarnings("unchecked")
        Iterator<byte[]> r = key.getRawUserIDs(); r.hasNext();) {
            byte[] rawUserId = r.next();

            @SuppressWarnings("unchecked")
            Iterator<PGPSignature> signaturesIt = key.getSignaturesForID(rawUserId);
            // no signatures for this User ID, skip it
            if (signaturesIt == null) {
                continue;
            }
            while (signaturesIt.hasNext()) {
                PGPSignature cert = signaturesIt.next();
                byte[] encoded = cert.getEncoded();
                // Known cert, skip it
                if (certs.contains(encoded)) {
                    continue;
                }
                certs.add(encoded);
                modified = PGPPublicKey.addCertification(modified, rawUserId, cert);
            }
        }

        // Copy over all user attribute certificates
        for (@SuppressWarnings("unchecked")
        Iterator<PGPUserAttributeSubpacketVector> v = key.getUserAttributes(); v.hasNext();) {
            PGPUserAttributeSubpacketVector vector = v.next();

            @SuppressWarnings("unchecked")
            Iterator<PGPSignature> signaturesIt = key.getSignaturesForUserAttribute(vector);
            // no signatures for this user attribute attribute, skip it
            if (signaturesIt == null) {
                continue;
            }
            while (signaturesIt.hasNext()) {
                PGPSignature cert = signaturesIt.next();
                byte[] encoded = cert.getEncoded();
                // Known cert, skip it
                if (certs.contains(encoded)) {
                    continue;
                }
                certs.add(encoded);
                modified = PGPPublicKey.addCertification(modified, vector, cert);
            }
        }

        // If anything change, save the updated (sub)key
        if (modified != resultKey) {
            result = PGPPublicKeyRing.insertPublicKey(result, modified);
        }

    }

    return result;
}