List of usage examples for org.bouncycastle.openpgp PGPSignature SUBKEY_BINDING
int SUBKEY_BINDING
To view the source code for org.bouncycastle.openpgp PGPSignature SUBKEY_BINDING.
Click Source Link
From source file:com.google.e2e.bcdriver.KeyChecker.java
License:Apache License
private static final void maybeAddSubkey(List<Subkey> subkeys, PGPPublicKey masterpk, PGPPublicKey subkey, StringBuilder errors) throws PGPException, SignatureException, IOException { Iterator<PGPSignature> sigit = Util.getTypedIterator(subkey.getSignatures(), PGPSignature.class); if (sigit == null) { errors.append("Reject subkey " + nicePk(subkey) + " because no binding signatures were found.\n"); return;// w ww .j a v a 2 s . c o m } PGPSignature validSig = null; long validTs = -1L; while (sigit.hasNext()) { PGPSignature sig = sigit.next(); switch (sig.getSignatureType()) { case PGPSignature.SUBKEY_BINDING: case PGPSignature.SUBKEY_REVOCATION: if (isGoodSubkeySignature(sig, masterpk, subkey, errors)) { if (sig.getSignatureType() == PGPSignature.SUBKEY_REVOCATION) { // Reject this subkey permanently. errors.append("Subkey " + nicePk(subkey) + " revoked by " + niceSig(sig) + "\n"); return; } // signing subkeys must have an embedded back signature. if (!Util.hasKeyFlag(sig, KeyFlags.SIGN_DATA) || isGoodBackSignature(sig, masterpk, subkey, errors)) { long ts = getSignatureTimestamp(sig, errors); if (ts > validTs) { validSig = sig; validTs = ts; } } } break; default: errors.append("Ignore " + niceSig(sig) + " for subkey " + nicePk(subkey) + "\n"); break; } } // We need atleast one good binding. if (validSig == null) { errors.append( "Subkey " + nicePk(subkey) + " rejected because no valid binding signatures were found.\n"); return; } subkeys.add(new Subkey(subkey, validSig)); }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperation.java
License:Open Source License
static PGPSignature generateSubkeyBindingSignature(PGPSignatureGenerator sGen, Date creationTime, PGPPublicKey masterPublicKey, PGPPrivateKey masterPrivateKey, PGPSignatureGenerator subSigGen, PGPPrivateKey subPrivateKey, PGPPublicKey pKey, int flags, long expiry) throws IOException, PGPException, SignatureException { PGPSignatureSubpacketGenerator unhashedPacketsGen = new PGPSignatureSubpacketGenerator(); // If this key can sign, we need a primary key binding signature if ((flags & KeyFlags.SIGN_DATA) > 0) { // cross-certify signing keys PGPSignatureSubpacketGenerator subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); subHashedPacketsGen.setSignatureCreationTime(false, creationTime); subSigGen.init(PGPSignature.PRIMARYKEY_BINDING, subPrivateKey); subSigGen.setHashedSubpackets(subHashedPacketsGen.generate()); PGPSignature certification = subSigGen.generateCertification(masterPublicKey, pKey); unhashedPacketsGen.setEmbeddedSignature(true, certification); }//from ww w. j av a 2 s. c o m PGPSignatureSubpacketGenerator hashedPacketsGen; { hashedPacketsGen = new PGPSignatureSubpacketGenerator(); hashedPacketsGen.setSignatureCreationTime(true, creationTime); hashedPacketsGen.setKeyFlags(true, flags); if (expiry > 0) { hashedPacketsGen.setKeyExpirationTime(true, expiry - pKey.getCreationTime().getTime() / 1000); } } sGen.init(PGPSignature.SUBKEY_BINDING, masterPrivateKey); sGen.setHashedSubpackets(hashedPacketsGen.generate()); sGen.setUnhashedSubpackets(unhashedPacketsGen.generate()); return sGen.generateCertification(masterPublicKey, pKey); }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testSubkeyAdd() throws Exception { long expiry = new Date().getTime() / 1000 + 159; int flags = KeyFlags.SIGN_DATA; parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, flags, expiry)); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly two extra packets in modified", 2, onlyB.size()); Packet p;/* w w w .j a va 2 s. co m*/ p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("first new packet must be secret subkey", p instanceof SecretSubkeyPacket); p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(1).buf)).readPacket(); Assert.assertTrue("second new packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("signature type must be subkey binding certificate", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); // get new key from ring. it should be the last one (add a check to make sure?) UncachedPublicKey newKey = null; { Iterator<UncachedPublicKey> it = modified.getPublicKeys(); while (it.hasNext()) { newKey = it.next(); } } Assert.assertNotNull("new key is not null", newKey); Assert.assertNotNull("added key must have an expiry date", newKey.getUnsafeExpiryTimeForTesting()); Assert.assertEquals("added key must have expected expiry date", expiry, newKey.getUnsafeExpiryTimeForTesting().getTime() / 1000); Assert.assertEquals("added key must have expected flags", flags, (long) newKey.getKeyUsage()); { // bad keysize should fail parcel.reset(); parcel.mAddSubKeys .add(new SubkeyAdd(Algorithm.RSA, new Random().nextInt(512), null, KeyFlags.SIGN_DATA, 0L)); assertModifyFailure("creating a subkey with keysize < 2048 should fail", ring, parcel, LogType.MSG_CR_ERROR_KEYSIZE_2048); } { // null expiry should fail parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, null)); assertModifyFailure("creating master key with null expiry should fail", ring, parcel, LogType.MSG_MF_ERROR_NULL_EXPIRY); } { // a past expiry should fail parcel.reset(); parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0, SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, new Date().getTime() / 1000 - 10)); assertModifyFailure("creating subkey with past expiry date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); } }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testSubkeyModify() throws Exception { long expiry = new Date().getTime() / 1000 + 1024; long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); UncachedKeyRing modified = ring;//from w w w. j a v a 2s . c o m { parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("one extra packet in original", 1, onlyA.size()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); Assert.assertEquals("old packet must be signature", PacketTags.SIGNATURE, onlyA.get(0).tag); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("first new packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("signature type must be subkey binding certificate", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); Assert.assertNotNull("modified key must have an expiry date", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); Assert.assertEquals("modified key must have expected expiry date", expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime() / 1000); Assert.assertEquals("modified key must have same flags as before", ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage()); } { // change expiry expiry += 60 * 60 * 24; parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, expiry)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertNotNull("modified key must have an expiry date", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); Assert.assertEquals("modified key must have expected expiry date", expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime() / 1000); Assert.assertEquals("modified key must have same flags as before", ring.getPublicKey(keyId).getKeyUsage(), modified.getPublicKey(keyId).getKeyUsage()); } { int flags = KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS; parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, flags, null)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", PacketTags.SIGNATURE, onlyA.get(0).tag); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("first new packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("signature type must be subkey binding certificate", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); Assert.assertEquals("modified key must have expected flags", flags, (long) modified.getPublicKey(keyId).getKeyUsage()); Assert.assertNotNull("key must retain its expiry", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); Assert.assertEquals("key expiry must be unchanged", expiry, modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting().getTime() / 1000); } { // expiry of 0 should be "no expiry" parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, 0L)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("old packet must be signature", PacketTags.SIGNATURE, onlyA.get(0).tag); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("first new packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("signature type must be subkey binding certificate", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); Assert.assertNull("key must not expire anymore", modified.getPublicKey(keyId).getUnsafeExpiryTimeForTesting()); } { // a past expiry should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, null, new Date().getTime() / 1000 - 10)); assertModifyFailure("setting subkey expiry to a past date should fail", ring, parcel, LogType.MSG_MF_ERROR_PAST_EXPIRY); } { // modifying nonexistent subkey should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(123, null, null)); assertModifyFailure("modifying non-existent subkey should fail", ring, parcel, LogType.MSG_MF_ERROR_SUBKEY_MISSING); } }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testSubkeyRevoke() throws Exception { long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); int flags = ring.getPublicKey(keyId).getKeyUsage(); UncachedKeyRing modified;//w w w .j a va2s .c o m { parcel.reset(); parcel.mRevokeSubKeys.add(123L); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ring.getEncoded(), false, 0); UncachedKeyRing otherModified = op.modifySecretKeyRing(secretRing, cryptoInput, parcel).getRing(); Assert.assertNull("revoking a nonexistent subkey should fail", otherModified); } { // revoked second subkey parcel.reset(); parcel.mRevokeSubKeys.add(keyId); modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, new CryptoInputParcel(new Date(), passphrase)); Assert.assertEquals("no extra packets in original", 0, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); Packet p; p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("first new packet must be secret subkey", p instanceof SignaturePacket); Assert.assertEquals("signature type must be subkey binding certificate", PGPSignature.SUBKEY_REVOCATION, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); Assert.assertTrue("subkey must actually be revoked", modified.getPublicKey(keyId).isMaybeRevoked()); } { // re-add second subkey parcel.reset(); // re-certify the revoked subkey parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); modified = applyModificationWithChecks(parcel, modified, onlyA, onlyB); Assert.assertEquals("exactly two outdated packets in original", 2, onlyA.size()); Assert.assertEquals("exactly one extra packet in modified", 1, onlyB.size()); Packet p; p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(0).buf)).readPacket(); Assert.assertTrue("first outdated packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("first outdated signature type must be subkey binding certification", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("first outdated signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); p = new BCPGInputStream(new ByteArrayInputStream(onlyA.get(1).buf)).readPacket(); Assert.assertTrue("second outdated packet must be signature", p instanceof SignaturePacket); Assert.assertEquals("second outdated signature type must be subkey revocation", PGPSignature.SUBKEY_REVOCATION, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("second outdated signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertTrue("new packet must be signature ", p instanceof SignaturePacket); Assert.assertEquals("new signature type must be subkey binding certification", PGPSignature.SUBKEY_BINDING, ((SignaturePacket) p).getSignatureType()); Assert.assertEquals("signature must have been created by master key", ring.getMasterKeyId(), ((SignaturePacket) p).getKeyID()); Assert.assertFalse("subkey must no longer be revoked", modified.getPublicKey(keyId).isMaybeRevoked()); Assert.assertEquals("subkey must have the same usage flags as before", flags, (long) modified.getPublicKey(keyId).getKeyUsage()); } }
From source file:org.sufficientlysecure.keychain.pgp.UncachedKeyRing.java
License:Open Source License
/** "Canonicalizes" a public key, removing inconsistencies in the process. * * More specifically://w w w.j av a 2 s. c o m * - Remove all non-verifying self-certificates * - Remove all "future" self-certificates * - Remove all certificates flagged as "local" * - For UID certificates, remove all certificates which are * superseded by a newer one on the same target, including * revocations with later re-certifications. * - For subkey certifications, remove all certificates which * are superseded by a newer one on the same target, unless * it encounters a revocation certificate. The revocation * certificate is considered to permanently revoke the key, * even if contains later re-certifications. * This is the "behavior in practice" used by (e.g.) GnuPG, and * the rationale for both can be found as comments in the GnuPG * source. * UID signatures: * https://github.com/mtigas/gnupg/blob/50c98c7ed6b542857ee2f902eca36cda37407737/g10/getkey.c#L1668-L1674 * Subkey signatures: * https://github.com/mtigas/gnupg/blob/50c98c7ed6b542857ee2f902eca36cda37407737/g10/getkey.c#L1990-L1997 * - Remove all certificates in other positions if not of known type: * - key revocation signatures on the master key * - subkey binding signatures for subkeys * - certifications and certification revocations for user ids * - If a subkey retains no valid subkey binding certificate, remove it * - If a user id retains no valid self certificate, remove it * - If the key is a secret key, remove all certificates by foreign keys * - If no valid user id remains, log an error and return null * * This operation writes an OperationLog which can be used as part of an OperationResultParcel. * * @param forExport if this is true, non-exportable signatures will be removed * @return A canonicalized key, or null on fatal error (log will include a message in this case) * */ @SuppressWarnings("ConstantConditions") public CanonicalizedKeyRing canonicalize(OperationLog log, int indent, boolean forExport) { log.add(isSecret() ? LogType.MSG_KC_SECRET : LogType.MSG_KC_PUBLIC, indent, KeyFormattingUtils.convertKeyIdToHex(getMasterKeyId())); indent += 1; // do not accept v3 keys if (getVersion() <= 3) { log.add(LogType.MSG_KC_ERROR_V3, indent); return null; } Calendar nowCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); // allow for diverging clocks up to one day when checking creation time nowCal.add(Calendar.DAY_OF_YEAR, 1); final Date nowPlusOneDay = nowCal.getTime(); int redundantCerts = 0, badCerts = 0; PGPKeyRing ring = mRing; PGPPublicKey masterKey = mRing.getPublicKey(); final long masterKeyId = masterKey.getKeyID(); if (Arrays.binarySearch(KNOWN_ALGORITHMS, masterKey.getAlgorithm()) < 0) { log.add(LogType.MSG_KC_ERROR_MASTER_ALGO, indent, Integer.toString(masterKey.getAlgorithm())); return null; } { log.add(LogType.MSG_KC_MASTER, indent, KeyFormattingUtils.convertKeyIdToHex(masterKey.getKeyID())); indent += 1; PGPPublicKey modified = masterKey; PGPSignature revocation = null; PGPSignature notation = null; for (PGPSignature zert : new IterableIterator<PGPSignature>(masterKey.getKeySignatures())) { int type = zert.getSignatureType(); // These should most definitely not be here... if (type == PGPSignature.NO_CERTIFICATION || type == PGPSignature.DEFAULT_CERTIFICATION || type == PGPSignature.CASUAL_CERTIFICATION || type == PGPSignature.POSITIVE_CERTIFICATION || type == PGPSignature.CERTIFICATION_REVOCATION) { log.add(LogType.MSG_KC_MASTER_BAD_TYPE_UID, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } WrappedSignature cert = new WrappedSignature(zert); if (type != PGPSignature.KEY_REVOCATION && type != PGPSignature.DIRECT_KEY) { // Unknown type, just remove log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent, "0x" + Integer.toString(type, 16)); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } if (cert.getCreationTime().after(nowPlusOneDay)) { // Creation date in the future? No way! log.add(LogType.MSG_KC_MASTER_BAD_TIME, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } try { cert.init(masterKey); if (!cert.verifySignature(masterKey)) { log.add(LogType.MSG_KC_MASTER_BAD, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } } catch (PgpGeneralException e) { log.add(LogType.MSG_KC_MASTER_BAD_ERR, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } // if this is for export, we always remove any non-exportable certs if (forExport && cert.isLocal()) { // Remove revocation certs with "local" flag log.add(LogType.MSG_KC_MASTER_LOCAL, indent); modified = PGPPublicKey.removeCertification(modified, zert); continue; } // special case: non-exportable, direct key signatures for notations! if (cert.getSignatureType() == PGPSignature.DIRECT_KEY) { // must be local, otherwise strip! if (!cert.isLocal()) { log.add(LogType.MSG_KC_MASTER_BAD_TYPE, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } // first notation? fine then. if (notation == null) { notation = zert; // more notations? at least one is superfluous, then. } else if (notation.getCreationTime().before(zert.getCreationTime())) { log.add(LogType.MSG_KC_NOTATION_DUP, indent); modified = PGPPublicKey.removeCertification(modified, notation); redundantCerts += 1; notation = zert; } else { log.add(LogType.MSG_KC_NOTATION_DUP, indent); modified = PGPPublicKey.removeCertification(modified, zert); redundantCerts += 1; } continue; } else if (cert.isLocal()) { // Remove revocation certs with "local" flag log.add(LogType.MSG_KC_MASTER_BAD_LOCAL, indent); modified = PGPPublicKey.removeCertification(modified, zert); badCerts += 1; continue; } // first revocation? fine then. if (revocation == null) { revocation = zert; // more revocations? at least one is superfluous, then. } else if (revocation.getCreationTime().before(zert.getCreationTime())) { log.add(LogType.MSG_KC_REVOKE_DUP, indent); modified = PGPPublicKey.removeCertification(modified, revocation); redundantCerts += 1; revocation = zert; } else { log.add(LogType.MSG_KC_REVOKE_DUP, indent); modified = PGPPublicKey.removeCertification(modified, zert); redundantCerts += 1; } } // If we have a notation packet, check if there is even any data in it? if (notation != null) { // If there isn't, might as well strip it if (new WrappedSignature(notation).getNotation().isEmpty()) { log.add(LogType.MSG_KC_NOTATION_EMPTY, indent); modified = PGPPublicKey.removeCertification(modified, notation); redundantCerts += 1; } } ArrayList<String> processedUserIds = new ArrayList<>(); for (byte[] rawUserId : new IterableIterator<byte[]>(masterKey.getRawUserIDs())) { String userId = Utf8Util.fromUTF8ByteArrayReplaceBadEncoding(rawUserId); // warn if user id was made with bad encoding if (!Utf8Util.isValidUTF8(rawUserId)) { log.add(LogType.MSG_KC_UID_WARN_ENCODING, indent); } // check for duplicate user ids if (processedUserIds.contains(userId)) { log.add(LogType.MSG_KC_UID_DUP, indent, userId); // strip out the first found user id with this name modified = PGPPublicKey.removeCertification(modified, rawUserId); } if (processedUserIds.size() > CANONICALIZE_MAX_USER_IDS) { log.add(LogType.MSG_KC_UID_TOO_MANY, indent, userId); // strip out the user id modified = PGPPublicKey.removeCertification(modified, rawUserId); } processedUserIds.add(userId); PGPSignature selfCert = null; revocation = null; // look through signatures for this specific user id @SuppressWarnings("unchecked") Iterator<PGPSignature> signaturesIt = masterKey.getSignaturesForID(rawUserId); if (signaturesIt != null) { for (PGPSignature zert : new IterableIterator<>(signaturesIt)) { WrappedSignature cert = new WrappedSignature(zert); long certId = cert.getKeyId(); int type = zert.getSignatureType(); if (type != PGPSignature.DEFAULT_CERTIFICATION && type != PGPSignature.NO_CERTIFICATION && type != PGPSignature.CASUAL_CERTIFICATION && type != PGPSignature.POSITIVE_CERTIFICATION && type != PGPSignature.CERTIFICATION_REVOCATION) { log.add(LogType.MSG_KC_UID_BAD_TYPE, indent, "0x" + Integer.toString(zert.getSignatureType(), 16)); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; continue; } if (cert.getCreationTime().after(nowPlusOneDay)) { // Creation date in the future? No way! log.add(LogType.MSG_KC_UID_BAD_TIME, indent); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; continue; } if (cert.isLocal()) { // Creation date in the future? No way! log.add(LogType.MSG_KC_UID_BAD_LOCAL, indent); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; continue; } // If this is a foreign signature, ... if (certId != masterKeyId) { // never mind any further for public keys, but remove them from secret ones if (isSecret()) { log.add(LogType.MSG_KC_UID_FOREIGN, indent, KeyFormattingUtils.convertKeyIdToHex(certId)); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; } continue; } // Otherwise, first make sure it checks out try { cert.init(masterKey); if (!cert.verifySignature(masterKey, rawUserId)) { log.add(LogType.MSG_KC_UID_BAD, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; continue; } } catch (PgpGeneralException e) { log.add(LogType.MSG_KC_UID_BAD_ERR, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); badCerts += 1; continue; } switch (type) { case PGPSignature.DEFAULT_CERTIFICATION: case PGPSignature.NO_CERTIFICATION: case PGPSignature.CASUAL_CERTIFICATION: case PGPSignature.POSITIVE_CERTIFICATION: if (selfCert == null) { selfCert = zert; } else if (selfCert.getCreationTime().before(cert.getCreationTime())) { log.add(LogType.MSG_KC_UID_CERT_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, selfCert); redundantCerts += 1; selfCert = zert; } else { log.add(LogType.MSG_KC_UID_CERT_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); redundantCerts += 1; } // If there is a revocation certificate, and it's older than this, drop it if (revocation != null && revocation.getCreationTime().before(selfCert.getCreationTime())) { log.add(LogType.MSG_KC_UID_REVOKE_OLD, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, revocation); revocation = null; redundantCerts += 1; } break; case PGPSignature.CERTIFICATION_REVOCATION: // If this is older than the (latest) self cert, drop it if (selfCert != null && selfCert.getCreationTime().after(zert.getCreationTime())) { log.add(LogType.MSG_KC_UID_REVOKE_OLD, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); redundantCerts += 1; continue; } // first revocation? remember it. if (revocation == null) { revocation = zert; // more revocations? at least one is superfluous, then. } else if (revocation.getCreationTime().before(cert.getCreationTime())) { log.add(LogType.MSG_KC_UID_REVOKE_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, revocation); redundantCerts += 1; revocation = zert; } else { log.add(LogType.MSG_KC_UID_REVOKE_DUP, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId, zert); redundantCerts += 1; } break; } } } // If no valid certificate (if only a revocation) remains, drop it if (selfCert == null && revocation == null) { log.add(LogType.MSG_KC_UID_REMOVE, indent, userId); modified = PGPPublicKey.removeCertification(modified, rawUserId); } } // If NO user ids remain, error out! if (modified == null || !modified.getUserIDs().hasNext()) { log.add(LogType.MSG_KC_ERROR_NO_UID, indent); return null; } ArrayList<PGPUserAttributeSubpacketVector> processedUserAttributes = new ArrayList<>(); for (PGPUserAttributeSubpacketVector userAttribute : new IterableIterator<PGPUserAttributeSubpacketVector>( masterKey.getUserAttributes())) { if (userAttribute.getSubpacket(UserAttributeSubpacketTags.IMAGE_ATTRIBUTE) != null) { log.add(LogType.MSG_KC_UAT_JPEG, indent); } else { log.add(LogType.MSG_KC_UAT_UNKNOWN, indent); } try { indent += 1; // check for duplicate user attributes if (processedUserAttributes.contains(userAttribute)) { log.add(LogType.MSG_KC_UAT_DUP, indent); // strip out the first found user id with this name modified = PGPPublicKey.removeCertification(modified, userAttribute); } processedUserAttributes.add(userAttribute); PGPSignature selfCert = null; revocation = null; // look through signatures for this specific user id @SuppressWarnings("unchecked") Iterator<PGPSignature> signaturesIt = masterKey.getSignaturesForUserAttribute(userAttribute); if (signaturesIt != null) { for (PGPSignature zert : new IterableIterator<>(signaturesIt)) { WrappedSignature cert = new WrappedSignature(zert); long certId = cert.getKeyId(); int type = zert.getSignatureType(); if (type != PGPSignature.DEFAULT_CERTIFICATION && type != PGPSignature.NO_CERTIFICATION && type != PGPSignature.CASUAL_CERTIFICATION && type != PGPSignature.POSITIVE_CERTIFICATION && type != PGPSignature.CERTIFICATION_REVOCATION) { log.add(LogType.MSG_KC_UAT_BAD_TYPE, indent, "0x" + Integer.toString(zert.getSignatureType(), 16)); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; continue; } if (cert.getCreationTime().after(nowPlusOneDay)) { // Creation date in the future? No way! log.add(LogType.MSG_KC_UAT_BAD_TIME, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; continue; } if (cert.isLocal()) { // Creation date in the future? No way! log.add(LogType.MSG_KC_UAT_BAD_LOCAL, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; continue; } // If this is a foreign signature, ... if (certId != masterKeyId) { // never mind any further for public keys, but remove them from secret ones if (isSecret()) { log.add(LogType.MSG_KC_UAT_FOREIGN, indent, KeyFormattingUtils.convertKeyIdToHex(certId)); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; } continue; } // Otherwise, first make sure it checks out try { cert.init(masterKey); if (!cert.verifySignature(masterKey, userAttribute)) { log.add(LogType.MSG_KC_UAT_BAD, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; continue; } } catch (PgpGeneralException e) { log.add(LogType.MSG_KC_UAT_BAD_ERR, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); badCerts += 1; continue; } switch (type) { case PGPSignature.DEFAULT_CERTIFICATION: case PGPSignature.NO_CERTIFICATION: case PGPSignature.CASUAL_CERTIFICATION: case PGPSignature.POSITIVE_CERTIFICATION: if (selfCert == null) { selfCert = zert; } else if (selfCert.getCreationTime().before(cert.getCreationTime())) { log.add(LogType.MSG_KC_UAT_CERT_DUP, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, selfCert); redundantCerts += 1; selfCert = zert; } else { log.add(LogType.MSG_KC_UAT_CERT_DUP, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); redundantCerts += 1; } // If there is a revocation certificate, and it's older than this, drop it if (revocation != null && revocation.getCreationTime().before(selfCert.getCreationTime())) { log.add(LogType.MSG_KC_UAT_REVOKE_OLD, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, revocation); revocation = null; redundantCerts += 1; } break; case PGPSignature.CERTIFICATION_REVOCATION: // If this is older than the (latest) self cert, drop it if (selfCert != null && selfCert.getCreationTime().after(zert.getCreationTime())) { log.add(LogType.MSG_KC_UAT_REVOKE_OLD, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); redundantCerts += 1; continue; } // first revocation? remember it. if (revocation == null) { revocation = zert; // more revocations? at least one is superfluous, then. } else if (revocation.getCreationTime().before(cert.getCreationTime())) { log.add(LogType.MSG_KC_UAT_REVOKE_DUP, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, revocation); redundantCerts += 1; revocation = zert; } else { log.add(LogType.MSG_KC_UAT_REVOKE_DUP, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute, zert); redundantCerts += 1; } break; } } } // If no valid certificate (if only a revocation) remains, drop it if (selfCert == null && revocation == null) { log.add(LogType.MSG_KC_UAT_REMOVE, indent); modified = PGPPublicKey.removeCertification(modified, userAttribute); } } finally { indent -= 1; } } // Replace modified key in the keyring ring = replacePublicKey(ring, modified); indent -= 1; } // Keep track of ids we encountered so far Set<Long> knownIds = new HashSet<>(); // Process all keys for (PGPPublicKey key : new IterableIterator<PGPPublicKey>(ring.getPublicKeys())) { // Make sure this is not a duplicate, avoid undefined behavior! if (knownIds.contains(key.getKeyID())) { log.add(LogType.MSG_KC_ERROR_DUP_KEY, indent, KeyFormattingUtils.convertKeyIdToHex(key.getKeyID())); return null; } // Add the key id to known knownIds.add(key.getKeyID()); // Don't care about the master key any further, that one gets special treatment above if (key.isMasterKey()) { continue; } log.add(LogType.MSG_KC_SUB, indent, KeyFormattingUtils.convertKeyIdToHex(key.getKeyID())); indent += 1; if (Arrays.binarySearch(KNOWN_ALGORITHMS, key.getAlgorithm()) < 0) { ring = removeSubKey(ring, key); log.add(LogType.MSG_KC_SUB_UNKNOWN_ALGO, indent, Integer.toString(key.getAlgorithm())); indent -= 1; continue; } Date keyCreationTime = key.getCreationTime(), keyCreationTimeLenient; { Calendar keyCreationCal = Calendar.getInstance(); keyCreationCal.setTime(keyCreationTime); // allow for diverging clocks up to one day when checking creation time keyCreationCal.add(Calendar.MINUTE, -5); keyCreationTimeLenient = keyCreationCal.getTime(); } // A subkey needs exactly one subkey binding certificate, and optionally one revocation // certificate. PGPPublicKey modified = key; PGPSignature selfCert = null, revocation = null; uids: for (PGPSignature zert : new IterableIterator<PGPSignature>(key.getSignatures())) { // remove from keyring (for now) modified = PGPPublicKey.removeCertification(modified, zert); WrappedSignature cert = new WrappedSignature(zert); int type = cert.getSignatureType(); // filter out bad key types... if (cert.getKeyId() != masterKey.getKeyID()) { log.add(LogType.MSG_KC_SUB_BAD_KEYID, indent); badCerts += 1; continue; } if (type != PGPSignature.SUBKEY_BINDING && type != PGPSignature.SUBKEY_REVOCATION) { log.add(LogType.MSG_KC_SUB_BAD_TYPE, indent, "0x" + Integer.toString(type, 16)); badCerts += 1; continue; } if (cert.getCreationTime().after(nowPlusOneDay)) { // Creation date in the future? No way! log.add(LogType.MSG_KC_SUB_BAD_TIME, indent); badCerts += 1; continue; } if (cert.getCreationTime().before(keyCreationTime)) { // Signature is earlier than key creation time log.add(LogType.MSG_KC_SUB_BAD_TIME_EARLY, indent); // due to an earlier accident, we generated keys which had creation timestamps // a few seconds after their signature timestamp. for compatibility, we only // error out with some margin of error if (cert.getCreationTime().before(keyCreationTimeLenient)) { badCerts += 1; continue; } } if (cert.isLocal()) { // Creation date in the future? No way! log.add(LogType.MSG_KC_SUB_BAD_LOCAL, indent); badCerts += 1; continue; } if (type == PGPSignature.SUBKEY_BINDING) { // make sure the certificate checks out try { cert.init(masterKey); if (!cert.verifySignature(masterKey, key)) { log.add(LogType.MSG_KC_SUB_BAD, indent); badCerts += 1; continue; } } catch (PgpGeneralException e) { log.add(LogType.MSG_KC_SUB_BAD_ERR, indent); badCerts += 1; continue; } boolean needsPrimaryBinding = false; // If the algorithm is even suitable for signing if (isSigningAlgo(key.getAlgorithm())) { // If this certificate says it allows signing for the key if (zert.getHashedSubPackets() != null && zert.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.KEY_FLAGS)) { int flags = ((KeyFlags) zert.getHashedSubPackets() .getSubpacket(SignatureSubpacketTags.KEY_FLAGS)).getFlags(); if ((flags & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA) { needsPrimaryBinding = true; } } else { // If there are no key flags, we STILL require this because the key can sign! needsPrimaryBinding = true; } } // If this key can sign, it MUST have a primary key binding certificate if (needsPrimaryBinding) { boolean ok = false; if (zert.getUnhashedSubPackets() != null) try { // Check all embedded signatures, if any of them fits PGPSignatureList list = zert.getUnhashedSubPackets().getEmbeddedSignatures(); for (int i = 0; i < list.size(); i++) { WrappedSignature subsig = new WrappedSignature(list.get(i)); if (subsig.getSignatureType() == PGPSignature.PRIMARYKEY_BINDING) { subsig.init(key); if (subsig.verifySignature(masterKey, key)) { ok = true; } else { log.add(LogType.MSG_KC_SUB_PRIMARY_BAD, indent); badCerts += 1; continue uids; } } } } catch (Exception e) { log.add(LogType.MSG_KC_SUB_PRIMARY_BAD_ERR, indent); badCerts += 1; continue; } // if it doesn't, get rid of this! if (!ok) { log.add(LogType.MSG_KC_SUB_PRIMARY_NONE, indent); badCerts += 1; continue; } } // if we already have a cert, and this one is older: skip it if (selfCert != null && cert.getCreationTime().before(selfCert.getCreationTime())) { log.add(LogType.MSG_KC_SUB_DUP, indent); redundantCerts += 1; continue; } selfCert = zert; // it must be a revocation, then (we made sure above) } else { // make sure the certificate checks out try { cert.init(masterKey); if (!cert.verifySignature(masterKey, key)) { log.add(LogType.MSG_KC_SUB_REVOKE_BAD, indent); badCerts += 1; continue; } } catch (PgpGeneralException e) { log.add(LogType.MSG_KC_SUB_REVOKE_BAD_ERR, indent); badCerts += 1; continue; } // If we already have a newer revocation cert, skip this one. if (revocation != null && revocation.getCreationTime().after(cert.getCreationTime())) { log.add(LogType.MSG_KC_SUB_REVOKE_DUP, indent); redundantCerts += 1; continue; } revocation = zert; } } // it is not properly bound? error! if (selfCert == null) { ring = removeSubKey(ring, key); log.add(LogType.MSG_KC_SUB_NO_CERT, indent, KeyFormattingUtils.convertKeyIdToHex(key.getKeyID())); indent -= 1; continue; } // If we have flags, check if the algorithm supports all of them if (selfCert.getHashedSubPackets() != null && selfCert.getHashedSubPackets().hasSubpacket(SignatureSubpacketTags.KEY_FLAGS)) { int flags = ((KeyFlags) selfCert.getHashedSubPackets() .getSubpacket(SignatureSubpacketTags.KEY_FLAGS)).getFlags(); int algo = key.getAlgorithm(); // If this is a signing key, but not a signing algorithm, warn the user if (!isSigningAlgo(algo) && (flags & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA) { log.add(LogType.MSG_KC_SUB_ALGO_BAD_SIGN, indent); } // If this is an encryption key, but not an encryption algorithm, warn the user if (!isEncryptionAlgo(algo) && ((flags & KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE || (flags & KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS)) { log.add(LogType.MSG_KC_SUB_ALGO_BAD_ENCRYPT, indent); } } // re-add certification modified = PGPPublicKey.addCertification(modified, selfCert); // add revocation, if any if (revocation != null) { modified = PGPPublicKey.addCertification(modified, revocation); } // replace pubkey in keyring ring = replacePublicKey(ring, modified); indent -= 1; } if (badCerts > 0 && redundantCerts > 0) { // multi plural would make this complex, just leaving this as is... log.add(LogType.MSG_KC_SUCCESS_BAD_AND_RED, indent, Integer.toString(badCerts), Integer.toString(redundantCerts)); } else if (badCerts > 0) { log.add(LogType.MSG_KC_SUCCESS_BAD, indent, badCerts); } else if (redundantCerts > 0) { log.add(LogType.MSG_KC_SUCCESS_REDUNDANT, indent, redundantCerts); } else { log.add(LogType.MSG_KC_SUCCESS, indent); } return isSecret() ? new CanonicalizedSecretKeyRing((PGPSecretKeyRing) ring, 1) : new CanonicalizedPublicKeyRing((PGPPublicKeyRing) ring, 0); }
From source file:org.sufficientlysecure.keychain.pgp.UncachedKeyringCanonicalizeTest.java
License:Open Source License
@Test public void testSubkeyBindingNoPKB() throws Exception { UncachedPublicKey pKey = KeyringTestingHelper.getNth(ring.getPublicKeys(), 1); PGPSignature sig;/* w w w.java2 s . co m*/ subHashedPacketsGen.setKeyFlags(false, KeyFlags.SIGN_DATA); { // forge a (newer) signature, which has the sign flag but no primary key binding sig PGPSignatureSubpacketGenerator unhashedSubs = new PGPSignatureSubpacketGenerator(); // just add any random signature, because why not unhashedSubs.setEmbeddedSignature(false, forgeSignature(secretKey, PGPSignature.POSITIVE_CERTIFICATION, subHashedPacketsGen, secretKey.getPublicKey())); sig = forgeSignature(secretKey, PGPSignature.SUBKEY_BINDING, subHashedPacketsGen, unhashedSubs, secretKey.getPublicKey(), pKey.getPublicKey()); // inject in the right position UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 8); // canonicalize, and check if we lose the bad signature CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0); Assert.assertFalse("subkey binding signature should be gone after canonicalization", KeyringTestingHelper.diffKeyrings(ring.getEncoded(), canonicalized.getEncoded(), onlyA, onlyB)); } { // now try one with a /bad/ primary key binding signature PGPSignatureSubpacketGenerator unhashedSubs = new PGPSignatureSubpacketGenerator(); // this one is signed by the primary key itself, not the subkey - but it IS primary binding unhashedSubs.setEmbeddedSignature(false, forgeSignature(secretKey, PGPSignature.PRIMARYKEY_BINDING, subHashedPacketsGen, secretKey.getPublicKey(), pKey.getPublicKey())); sig = forgeSignature(secretKey, PGPSignature.SUBKEY_BINDING, subHashedPacketsGen, unhashedSubs, secretKey.getPublicKey(), pKey.getPublicKey()); // inject in the right position UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig.getEncoded(), 8); // canonicalize, and check if we lose the bad signature CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0); Assert.assertFalse("subkey binding signature should be gone after canonicalization", KeyringTestingHelper.diffKeyrings(ring.getEncoded(), canonicalized.getEncoded(), onlyA, onlyB)); } }
From source file:org.sufficientlysecure.keychain.pgp.UncachedKeyringCanonicalizeTest.java
License:Open Source License
@Test public void testSubkeyBindingRedundant() throws Exception { UncachedPublicKey pKey = KeyringTestingHelper.getNth(ring.getPublicKeys(), 2); subHashedPacketsGen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS); PGPSignature sig2 = forgeSignature(secretKey, PGPSignature.SUBKEY_BINDING, subHashedPacketsGen, secretKey.getPublicKey(), pKey.getPublicKey()); subHashedPacketsGen.setSignatureCreationTime(false, new Date(new Date().getTime() - 1000 * 1000)); PGPSignature sig1 = forgeSignature(secretKey, PGPSignature.SUBKEY_REVOCATION, subHashedPacketsGen, secretKey.getPublicKey(), pKey.getPublicKey()); subHashedPacketsGen = new PGPSignatureSubpacketGenerator(); subHashedPacketsGen.setSignatureCreationTime(false, new Date(new Date().getTime() - 100 * 1000)); PGPSignature sig3 = forgeSignature(secretKey, PGPSignature.SUBKEY_BINDING, subHashedPacketsGen, secretKey.getPublicKey(), pKey.getPublicKey()); UncachedKeyRing modified = KeyringTestingHelper.injectPacket(ring, sig1.getEncoded(), 10); modified = KeyringTestingHelper.injectPacket(modified, sig2.getEncoded(), 11); modified = KeyringTestingHelper.injectPacket(modified, sig1.getEncoded(), 12); modified = KeyringTestingHelper.injectPacket(modified, sig3.getEncoded(), 13); // canonicalize, and check if we lose the bad signature CanonicalizedKeyRing canonicalized = modified.canonicalize(log, 0); Assert.assertTrue("subkey binding signature should be gone after canonicalization", KeyringTestingHelper.diffKeyrings(modified.getEncoded(), canonicalized.getEncoded(), onlyA, onlyB)); Assert.assertEquals("canonicalized keyring should have lost two packets", 3, onlyA.size()); Assert.assertEquals("canonicalized keyring should have no extra packets", 0, onlyB.size()); Assert.assertEquals("first missing packet should be the subkey", PacketTags.SIGNATURE, onlyA.get(0).tag); Assert.assertEquals("second missing packet should be a signature", PacketTags.SIGNATURE, onlyA.get(1).tag); Assert.assertEquals("second missing packet should be a signature", PacketTags.SIGNATURE, onlyA.get(2).tag); }
From source file:org.sufficientlysecure.keychain.pgp.UncachedPublicKey.java
License:Open Source License
/** Get all key usage flags. * If at least one key flag subpacket is present return these. If no * subpacket is present it returns null. * * Note that this method has package visiblity because it is used in test * cases. Certificates of UncachedPublicKey instances can NOT be assumed to * be verified or even by the correct key, so the result of this method * should never be used in other places! *//*from www. ja v a 2 s .c om*/ @SuppressWarnings("unchecked") Integer getKeyUsage() { if (mCacheUsage == null) { PGPSignature mostRecentSig = null; for (PGPSignature sig : new IterableIterator<PGPSignature>(mPublicKey.getSignatures())) { if (mPublicKey.isMasterKey() && sig.getKeyID() != mPublicKey.getKeyID()) { continue; } switch (sig.getSignatureType()) { case PGPSignature.DEFAULT_CERTIFICATION: case PGPSignature.POSITIVE_CERTIFICATION: case PGPSignature.CASUAL_CERTIFICATION: case PGPSignature.NO_CERTIFICATION: case PGPSignature.SUBKEY_BINDING: break; // if this is not one of the above types, don't care default: continue; } // If we have no sig yet, take the first we can get if (mostRecentSig == null) { mostRecentSig = sig; continue; } // If the new sig is less recent, skip it if (mostRecentSig.getCreationTime().after(sig.getCreationTime())) { continue; } // Otherwise, note it down as the new "most recent" one mostRecentSig = sig; } // Initialize to 0 as cached but empty value, if there is no sig (can't happen // for canonicalized keyring), or there is no KEY_FLAGS packet in the sig mCacheUsage = 0; if (mostRecentSig != null) { // If a mostRecentSig has been found, (cache and) return its flags PGPSignatureSubpacketVector hashed = mostRecentSig.getHashedSubPackets(); if (hashed != null && hashed.getSubpacket(SignatureSubpacketTags.KEY_FLAGS) != null) { mCacheUsage = hashed.getKeyFlags(); } } } return mCacheUsage; }
From source file:org.sufficientlysecure.keychain.support.KeyringBuilder.java
License:Open Source License
private static SignaturePacket createSubkeySignaturePacket() { int signatureType = PGPSignature.SUBKEY_BINDING; int keyAlgorithm = SignaturePacket.RSA_GENERAL; int hashAlgorithm = HashAlgorithmTags.SHA1; SignatureSubpacket[] hashedData = new SignatureSubpacket[] { new SignatureCreationTime(false, SIGNATURE_DATE), new KeyFlags(false, KeyFlags.ENCRYPT_COMMS + KeyFlags.ENCRYPT_STORAGE), new KeyExpirationTime(false, TimeUnit.DAYS.toSeconds(2)), }; SignatureSubpacket[] unhashedData = new SignatureSubpacket[] { new IssuerKeyID(false, false, KEY_ID.toByteArray()) }; byte[] fingerPrint = new BigInteger("234a", 16).toByteArray(); MPInteger[] signature = new MPInteger[] { new MPInteger(CORRECT_SUBKEY_SIGNATURE) }; return new SignaturePacket(signatureType, KEY_ID.longValue(), keyAlgorithm, hashAlgorithm, hashedData, unhashedData, fingerPrint, signature); }