List of usage examples for org.bouncycastle.openpgp PGPKeyValidationException PGPKeyValidationException
public PGPKeyValidationException(String message)
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; }