List of usage examples for org.bouncycastle.bcpg BCPGInputStream BCPGInputStream
public BCPGInputStream(InputStream in)
From source file:org.sufficientlysecure.keychain.pgp.PgpEncryptDecryptTest.java
License:Open Source License
@Test public void testMultiSubkeyEncryptSkipStripOrBadFlag() throws Exception { String plaintext = "dies ist ein plaintext " + TestingUtils.genPassphrase(true); byte[] ciphertext; long encKeyId1; { // encrypt data with key ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application, new ProviderHelper(RuntimeEnvironment.application), null); InputData data = new InputData(in, in.available()); PgpSignEncryptData pgpData = new PgpSignEncryptData(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); ciphertext = out.toByteArray();//from ww w . j a v a2 s . c o m Iterator<RawPacket> packets = KeyringTestingHelper.parseKeyring(ciphertext); RawPacket enc1 = packets.next(), enc2 = packets.next(); Assert.assertEquals("last packet must be encrypted data packet", PacketTags.SYM_ENC_INTEGRITY_PRO, packets.next().tag); Assert.assertFalse("no further packets", packets.hasNext()); Packet p; p = new BCPGInputStream(new ByteArrayInputStream(enc1.buf)).readPacket(); Assert.assertTrue("first packet must be session packet", p instanceof PublicKeyEncSessionPacket); encKeyId1 = ((PublicKeyEncSessionPacket) p).getKeyID(); p = new BCPGInputStream(new ByteArrayInputStream(enc2.buf)).readPacket(); Assert.assertTrue("second packet must be session packet", p instanceof PublicKeyEncSessionPacket); long encKeyId2 = ((PublicKeyEncSessionPacket) p).getKeyID(); Assert.assertNotEquals("encrypted-to subkey ids must not be equal", encKeyId1, encKeyId2); Assert.assertThat("first packet must be encrypted to one of the subkeys", KeyringTestingHelper.getSubkeyId(mStaticRing1, 2), anyOf(is(encKeyId1), is(encKeyId2))); Assert.assertThat("second packet must be encrypted to one of the subkeys", KeyringTestingHelper.getSubkeyId(mStaticRing1, 3), anyOf(is(encKeyId1), is(encKeyId2))); } { // strip first encrypted subkey, decryption should skip it SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, true, false)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList<RawPacket>(), new ArrayList<RawPacket>(), new CryptoInputParcel(new Date(), mKeyPhrase1)); ProviderHelper providerHelper = new ProviderHelper(RuntimeEnvironment.application); providerHelper.saveSecretKeyRing(modified, new ProgressScaler()); PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, new ProviderHelper(RuntimeEnvironment.application), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); Assert.assertTrue("decryption must have skipped first key", result.getLog().containsType(LogType.MSG_DC_ASKIP_UNAVAILABLE)); } { // change flags of second encrypted subkey, decryption should skip it SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); parcel.mChangeSubKeys.add(new SubkeyChange(encKeyId1, KeyFlags.CERTIFY_OTHER, null)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList<RawPacket>(), new ArrayList<RawPacket>(), new CryptoInputParcel(new Date(), mKeyPhrase1)); ProviderHelper providerHelper = new ProviderHelper(RuntimeEnvironment.application); providerHelper.saveSecretKeyRing(modified, new ProgressScaler()); PgpDecryptVerifyOperation op = new PgpDecryptVerifyOperation(RuntimeEnvironment.application, new ProviderHelper(RuntimeEnvironment.application), null); PgpDecryptVerifyInputParcel input = new PgpDecryptVerifyInputParcel(ciphertext); DecryptVerifyResult result = op.execute(input, new CryptoInputParcel(mKeyPhrase1)); Assert.assertTrue("decryption must succeed", result.success()); Assert.assertTrue("decryption must have skipped first key", result.getLog().containsType(LogType.MSG_DC_ASKIP_BAD_FLAGS)); } }
From source file:org.sufficientlysecure.keychain.pgp.PgpEncryptDecryptTest.java
License:Open Source License
@Test public void testMultiSubkeyEncryptSkipRevoked() throws Exception { String plaintext = "dies ist ein plaintext " + TestingUtils.genPassphrase(true); { // revoke first encryption subkey of keyring in database SaveKeyringParcel parcel = new SaveKeyringParcel(mStaticRing1.getMasterKeyId(), mStaticRing1.getFingerprint()); parcel.mRevokeSubKeys.add(KeyringTestingHelper.getSubkeyId(mStaticRing1, 2)); UncachedKeyRing modified = PgpKeyOperationTest.applyModificationWithChecks(parcel, mStaticRing1, new ArrayList<RawPacket>(), new ArrayList<RawPacket>(), new CryptoInputParcel(new Date(), mKeyPhrase1)); ProviderHelper providerHelper = new ProviderHelper(RuntimeEnvironment.application); providerHelper.saveSecretKeyRing(modified, new ProgressScaler()); }/*ww w.j a v a 2s . c om*/ { // encrypt to this keyring, make sure it's not encrypted to the revoked subkey ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayInputStream in = new ByteArrayInputStream(plaintext.getBytes()); PgpSignEncryptOperation op = new PgpSignEncryptOperation(RuntimeEnvironment.application, new ProviderHelper(RuntimeEnvironment.application), null); InputData data = new InputData(in, in.available()); PgpSignEncryptData pgpData = new PgpSignEncryptData(); pgpData.setEncryptionMasterKeyIds(new long[] { mStaticRing1.getMasterKeyId() }); pgpData.setSymmetricEncryptionAlgorithm( PgpSecurityConstants.OpenKeychainSymmetricKeyAlgorithmTags.AES_128); PgpSignEncryptInputParcel input = new PgpSignEncryptInputParcel(pgpData); PgpSignEncryptResult result = op.execute(input, new CryptoInputParcel(new Date()), data, out); Assert.assertTrue("encryption must succeed", result.success()); byte[] ciphertext = out.toByteArray(); Iterator<RawPacket> packets = KeyringTestingHelper.parseKeyring(ciphertext); RawPacket enc1 = packets.next(); Assert.assertEquals("last packet must be encrypted data packet", PacketTags.SYM_ENC_INTEGRITY_PRO, packets.next().tag); Assert.assertFalse("no further packets", packets.hasNext()); Packet p; p = new BCPGInputStream(new ByteArrayInputStream(enc1.buf)).readPacket(); Assert.assertTrue("first packet must be session packet", p instanceof PublicKeyEncSessionPacket); Assert.assertEquals("first packet must be encrypted to second enc subkey", KeyringTestingHelper.getSubkeyId(mStaticRing1, 3), ((PublicKeyEncSessionPacket) p).getKeyID()); } }
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;/*from www . jav a 2 s . c o 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;//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 testMasterRevoke() throws Exception { parcel.reset();//w ww. ja v a 2s . c o m parcel.mRevokeSubKeys.add(ring.getMasterKeyId()); UncachedKeyRing modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB); 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.KEY_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().isMaybeRevoked()); }
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;/*from w ww.ja v a2 s. co 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.PgpKeyOperationTest.java
License:Open Source License
@Test public void testSubkeyStrip() throws Exception { long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); applyModificationWithChecks(parcel, ring, 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 secret subkey", PacketTags.SECRET_SUBKEY, onlyA.get(0).tag); Assert.assertEquals("new packet must be secret subkey", PacketTags.SECRET_SUBKEY, onlyB.get(0).tag); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertEquals("new packet should have GNU_DUMMY S2K type", S2K.GNU_DUMMY_S2K, ((SecretSubkeyPacket) p).getS2K().getType()); Assert.assertEquals("new packet should have GNU_DUMMY protection mode 0x1", 0x1, ((SecretSubkeyPacket) p).getS2K().getProtectionMode()); Assert.assertEquals("new packet secret key data should have length zero", 0, ((SecretSubkeyPacket) p).getSecretKeyData().length); Assert.assertNull("new packet should have no iv data", ((SecretSubkeyPacket) p).getIV()); }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testMasterStrip() throws Exception { long keyId = ring.getMasterKeyId(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); applyModificationWithChecks(parcel, ring, 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 secret key", PacketTags.SECRET_KEY, onlyA.get(0).tag); Assert.assertEquals("new packet must be secret key", PacketTags.SECRET_KEY, onlyB.get(0).tag); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertEquals("new packet should have GNU_DUMMY S2K type", S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType()); Assert.assertEquals("new packet should have GNU_DUMMY protection mode 0x1", 0x1, ((SecretKeyPacket) p).getS2K().getProtectionMode()); Assert.assertEquals("new packet secret key data should have length zero", 0, ((SecretKeyPacket) p).getSecretKeyData().length); Assert.assertNull("new packet should have no iv data", ((SecretKeyPacket) p).getIV()); }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testRestrictedStrip() throws Exception { long keyId = KeyringTestingHelper.getSubkeyId(ring, 1); UncachedKeyRing modified;/* w w w .j a va2 s. c o m*/ { // we should be able to change the stripped status of subkeys without passphrase parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); modified = applyModificationWithChecks(parcel, ring, onlyA, onlyB, new CryptoInputParcel()); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertEquals("new packet should have GNU_DUMMY S2K type", S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType()); Assert.assertEquals("new packet should have GNU_DUMMY protection mode stripped", S2K.GNU_PROTECTION_MODE_NO_PRIVATE_KEY, ((SecretKeyPacket) p).getS2K().getProtectionMode()); } { // trying to edit a subkey with signing capability should fail parcel.reset(); parcel.mChangeSubKeys.add(new SubkeyChange(keyId, true)); assertModifyFailure("subkey modification for signing-enabled but stripped subkey should fail", modified, parcel, LogType.MSG_MF_ERROR_SUB_STRIPPED); } }
From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperationTest.java
License:Open Source License
@Test public void testKeyToSecurityToken() throws Exception { // Special keyring for security token tests with 2048 bit RSA as a subkey SaveKeyringParcel parcelKey = new SaveKeyringParcel(); parcelKey.mAddSubKeys// www . j ava2 s . c om .add(new SaveKeyringParcel.SubkeyAdd(Algorithm.DSA, 2048, null, KeyFlags.CERTIFY_OTHER, 0L)); parcelKey.mAddSubKeys .add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, 2048, null, KeyFlags.SIGN_DATA, 0L)); parcelKey.mAddSubKeys .add(new SaveKeyringParcel.SubkeyAdd(Algorithm.RSA, 3072, null, KeyFlags.ENCRYPT_COMMS, 0L)); parcelKey.mAddUserIds.add("yubikey"); parcelKey.setNewUnlock(new ChangeUnlockParcel(passphrase)); PgpKeyOperation opSecurityToken = new PgpKeyOperation(null); PgpEditKeyResult resultSecurityToken = opSecurityToken.createSecretKeyRing(parcelKey); Assert.assertTrue("initial test key creation must succeed", resultSecurityToken.success()); Assert.assertNotNull("initial test key creation must succeed", resultSecurityToken.getRing()); UncachedKeyRing ringSecurityToken = resultSecurityToken.getRing(); SaveKeyringParcel parcelSecurityToken = new SaveKeyringParcel(); parcelSecurityToken.mMasterKeyId = ringSecurityToken.getMasterKeyId(); parcelSecurityToken.mFingerprint = ringSecurityToken.getFingerprint(); UncachedKeyRing modified; { // moveKeyToSecurityToken should fail with BAD_NFC_SIZE when presented with the RSA-3072 key long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 2); parcelSecurityToken.reset(); parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); assertModifyFailure("moveKeyToSecurityToken operation should fail on invalid key size", ringSecurityToken, parcelSecurityToken, cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_SIZE); } { // moveKeyToSecurityToken should fail with BAD_NFC_ALGO when presented with the DSA-1024 key long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 0); parcelSecurityToken.reset(); parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); assertModifyFailure("moveKeyToSecurityToken operation should fail on invalid key algorithm", ringSecurityToken, parcelSecurityToken, cryptoInput, LogType.MSG_MF_ERROR_BAD_SECURITY_TOKEN_ALGO); } long keyId = KeyringTestingHelper.getSubkeyId(ringSecurityToken, 1); { // moveKeyToSecurityToken should return a pending SECURITY_TOKEN_MOVE_KEY_TO_CARD result when presented with the RSA-2048 // key, and then make key divert-to-card when it gets a serial in the cryptoInputParcel. parcelSecurityToken.reset(); parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, false, true)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(ringSecurityToken.getEncoded(), false, 0); PgpKeyOperation op = new PgpKeyOperation(null); PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken); Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending()); Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD", result.getRequiredInputParcel().mType, RequiredInputType.SECURITY_TOKEN_MOVE_KEY_TO_CARD); // Create a cryptoInputParcel that matches what the SecurityTokenOperationActivity would return. byte[] keyIdBytes = new byte[8]; ByteBuffer buf = ByteBuffer.wrap(keyIdBytes); buf.putLong(keyId).rewind(); byte[] serial = new byte[] { 0x6a, 0x6f, 0x6c, 0x6f, 0x73, 0x77, 0x61, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; CryptoInputParcel inputParcel = new CryptoInputParcel(); inputParcel.addCryptoData(keyIdBytes, serial); modified = applyModificationWithChecks(parcelSecurityToken, ringSecurityToken, onlyA, onlyB, inputParcel); Assert.assertEquals("one extra packet in modified", 1, onlyB.size()); Packet p = new BCPGInputStream(new ByteArrayInputStream(onlyB.get(0).buf)).readPacket(); Assert.assertEquals("new packet should have GNU_DUMMY S2K type", S2K.GNU_DUMMY_S2K, ((SecretKeyPacket) p).getS2K().getType()); Assert.assertEquals("new packet should have GNU_DUMMY protection mode divert-to-card", S2K.GNU_PROTECTION_MODE_DIVERT_TO_CARD, ((SecretKeyPacket) p).getS2K().getProtectionMode()); Assert.assertArrayEquals("new packet should have correct serial number as iv", serial, ((SecretKeyPacket) p).getIV()); } { // editing a signing subkey requires a primary key binding sig -> pendinginput parcelSecurityToken.reset(); parcelSecurityToken.mChangeSubKeys.add(new SubkeyChange(keyId, true)); CanonicalizedSecretKeyRing secretRing = new CanonicalizedSecretKeyRing(modified.getEncoded(), false, 0); PgpKeyOperation op = new PgpKeyOperation(null); PgpEditKeyResult result = op.modifySecretKeyRing(secretRing, cryptoInput, parcelSecurityToken); Assert.assertTrue("moveKeyToSecurityToken operation should be pending", result.isPending()); Assert.assertEquals("required input should be RequiredInputType.SECURITY_TOKEN_SIGN", RequiredInputType.SECURITY_TOKEN_SIGN, result.getRequiredInputParcel().mType); } }