Example usage for org.bouncycastle.bcpg PacketTags SYM_ENC_INTEGRITY_PRO

List of usage examples for org.bouncycastle.bcpg PacketTags SYM_ENC_INTEGRITY_PRO

Introduction

In this page you can find the example usage for org.bouncycastle.bcpg PacketTags SYM_ENC_INTEGRITY_PRO.

Prototype

int SYM_ENC_INTEGRITY_PRO

To view the source code for org.bouncycastle.bcpg PacketTags SYM_ENC_INTEGRITY_PRO.

Click Source Link

Usage

From source file:divconq.pgp.EncryptedFileStream.java

License:Open Source License

public void init() throws PGPException, IOException, InvalidKeyException, InvalidAlgorithmParameterException,
        NoSuchAlgorithmException, NoSuchPaddingException {
    if (this.algorithm != SymmetricKeyAlgorithmTags.NULL) {
        // *******************************************************************
        // public key packet(s)
        // *******************************************************************

        if ((methods.size() == 1) && (methods.get(0) instanceof PBEKeyEncryptionMethodGenerator)) {
            PBEKeyEncryptionMethodGenerator method = (PBEKeyEncryptionMethodGenerator) methods.get(0);

            this.key = method.getKey(algorithm);

            ContainedPacket packet1 = method.generate(algorithm, null);

            byte[] encoded1 = packet1.getEncoded();

            this.ensureBuffer(encoded1.length);

            this.out.writeBytes(encoded1);
        } else {/*from w w  w. j  a  v a  2s  .co  m*/
            this.key = org.bouncycastle.openpgp.PGPUtil.makeRandomKey(algorithm, rand);

            byte[] sessionInfo = new byte[key.length + 3];

            // add algorithm
            sessionInfo[0] = (byte) algorithm;

            // add key
            System.arraycopy(key, 0, sessionInfo, 1, key.length);

            // add checksum 
            int check = 0;

            for (int i = 1; i != sessionInfo.length - 2; i++)
                check += sessionInfo[i] & 0xff;

            sessionInfo[sessionInfo.length - 2] = (byte) (check >> 8);
            sessionInfo[sessionInfo.length - 1] = (byte) (check);

            for (PGPKeyEncryptionMethodGenerator method : methods) {
                ContainedPacket packet1 = method.generate(algorithm, sessionInfo);

                byte[] encoded1 = packet1.getEncoded();

                this.ensureBuffer(encoded1.length);

                this.out.writeBytes(encoded1);
            }
        }

        // *******************************************************************
        // encrypt packet, add IV to encryption though
        // *******************************************************************

        this.ensureBuffer(3);

        this.out.writeByte(0xC0 | PacketTags.SYM_ENC_INTEGRITY_PRO);
        this.out.writeByte(0); // unknown size
        this.out.writeByte(1); // version number

        // ******************** start encryption **********************

        String cName = PGPUtil.getSymmetricCipherName(algorithm) + "/CFB/NoPadding";

        DefaultJcaJceHelper helper = new DefaultJcaJceHelper();

        this.cipher = helper.createCipher(cName);

        byte[] iv = new byte[this.cipher.getBlockSize()];

        this.cipher.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(algorithm, key),
                new IvParameterSpec(iv));

        this.digest = MessageDigest.getInstance("SHA-1");

        // --- encrypt checksum for encrypt packet, part of the encrypted output --- 

        byte[] inLineIv = new byte[this.cipher.getBlockSize() + 2];

        rand.nextBytes(inLineIv);

        inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3];
        inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4];

        this.writeDataInternal(inLineIv, 0, inLineIv.length);
    }

    // ******************* Optionally add Compression **************************

    // TODO set compressor 

    // ******************** Literal data packet ***********************

    this.ensureBuffer(1);
    this.writeDataInternal((byte) (0xC0 | PacketTags.LITERAL_DATA));
}

From source file:divconq.test.pgp.PGPWriter.java

License:Open Source License

public void open(int algorithm, PGPKeyEncryptionMethodGenerator... methods)
        throws IOException, PGPException, IllegalStateException {
    if (methods.length == 0)
        throw new IllegalStateException("no encryption methods specified");

    this.algorithm = algorithm;

    // *******************************************************************
    // public key packet
    // *******************************************************************

    // TODO this condition untested and perhaps not helpful, review (PBE - password based encryption)
    if ((methods.length == 1) && (methods[0] instanceof PBEKeyEncryptionMethodGenerator)) {
        PBEKeyEncryptionMethodGenerator m = (PBEKeyEncryptionMethodGenerator) methods[0];

        this.key = m.getKey(algorithm);

        this.writePacket(m.generate(algorithm, null));
    } else {/*w ww  . j av a  2s.co  m*/
        this.key = org.bouncycastle.openpgp.PGPUtil.makeRandomKey(algorithm, rand);

        byte[] sessionInfo = this.createSessionInfo();

        for (int i = 0; i < methods.length; i++) {
            PGPKeyEncryptionMethodGenerator m = (PGPKeyEncryptionMethodGenerator) methods[i];

            this.writePacket(m.generate(algorithm, sessionInfo));
        }
    }

    int packet1 = this.out.writerIndex();

    System.out.println("packet 1: " + packet1 + " final bytes: "
            + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet1 - 5, 5));

    // *******************************************************************
    // encrypt packet, add IV to 
    // *******************************************************************

    try {
        String cName = PGPUtil.getSymmetricCipherName(algorithm) + "/CFB/NoPadding";

        DefaultJcaJceHelper helper = new DefaultJcaJceHelper();

        this.cipher = helper.createCipher(cName);

        byte[] iv = new byte[this.cipher.getBlockSize()];

        this.cipher.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(algorithm, this.key),
                new IvParameterSpec(iv));

        //
        // we have to add block size + 2 for the generated IV and + 1 + 22 if integrity protected
        //

        this.ensureBuffer(this.cipher.getBlockSize() + 2 + 1 + 22);

        this.startPartialPacket(PacketTags.SYM_ENC_INTEGRITY_PRO); //, this.cipher.getBlockSize() + 2 + 1 + 22);

        this.out.writeByte(1); // version number

        byte[] inLineIv = new byte[this.cipher.getBlockSize() + 2];

        this.rand.nextBytes(inLineIv);

        inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3];
        inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4];

        // TODO
        byte[] any = this.cipher.update(inLineIv);

        if (any != null)
            this.out.writeBytes(any); // we may include this in digest, TODO review
    } catch (InvalidKeyException e) {
        throw new PGPException("invalid key: " + e.getMessage(), e);
    } catch (InvalidAlgorithmParameterException e) {
        throw new PGPException("imvalid algorithm parameter: " + e.getMessage(), e);
    } catch (GeneralSecurityException e) {
        throw new PGPException("cannot create cipher: " + e.getMessage(), e);
    }

    int packet2 = this.out.writerIndex();

    System.out.println("packet 2: first bytes: "
            + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet1, 25));
    System.out.println("packet 2: " + packet2 + " final bytes: "
            + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet2 - 5, 5));

    // *******************************************************************
    // TODO compress packet, if any
    // *******************************************************************

    int packet3 = this.out.writerIndex();

    //System.out.println("packet 3: first bytes: " + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet2, 25));
    //System.out.println("packet 3: " + packet3 + " final bytes: " + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet3 - 5, 5));

    // *******************************************************************
    // literal packet start
    // *******************************************************************

    this.startPartialPacket(PacketTags.LITERAL_DATA);

    byte[] encName = Utf8Encoder.encode(this.fileName);

    // TODO don't hard code
    int len = 1 + 1 + encName.length + 4 + 99; // type + name length + name + mod time + file content

    //out.writeByte(len);

    this.writeNewPacketLength(len);

    out.writeByte(PGPLiteralData.BINARY);

    out.writeByte((byte) encName.length);

    out.writeBytes(encName);

    long modDate = this.modificationTime / 1000;

    out.writeByte((byte) (modDate >> 24));
    out.writeByte((byte) (modDate >> 16));
    out.writeByte((byte) (modDate >> 8));
    out.writeByte((byte) (modDate));

    int packet4 = this.out.writerIndex();

    System.out.println("packet 4: first bytes: "
            + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet3, 25));
    System.out.println("packet 4: " + packet4 + " final bytes: "
            + HexUtil.bufferToHex(this.out.array(), this.out.arrayOffset() + packet4 - 5, 5));

    // TODO new SHA1PGPDigestCalculator();
    //if (digestCalc != null)
    //   genOut = new TeeOutputStream(digestCalc.getOutputStream(), genOut);
}

From source file:divconq.test.pgp.PGPWriter2.java

License:Open Source License

@SuppressWarnings("resource")
public void test2(String srcpath, String destpath, String keyring) throws Exception {
    Path src = Paths.get(srcpath);

    // file data 
    byte[] fileData = Files.readAllBytes(src);

    // dest//from   w  ww.  jav  a  2  s . c  o m
    OutputStream dest = new BufferedOutputStream(new FileOutputStream(destpath));

    // encryption key
    PGPPublicKey pubKey = null;

    InputStream keyIn = new BufferedInputStream(new FileInputStream(keyring));

    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
            org.bouncycastle.openpgp.PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());

    //
    // we just loop through the collection till we find a key suitable for encryption, in the real
    // world you would probably want to be a bit smarter about this.
    //

    @SuppressWarnings("rawtypes")
    Iterator keyRingIter = pgpPub.getKeyRings();

    while (keyRingIter.hasNext() && (pubKey == null)) {
        PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();

        @SuppressWarnings("rawtypes")
        Iterator keyIter = keyRing.getPublicKeys();

        while (keyIter.hasNext() && (pubKey == null)) {
            PGPPublicKey key = (PGPPublicKey) keyIter.next();

            if (key.isEncryptionKey())
                pubKey = key;
        }
    }

    if (pubKey == null)
        throw new IllegalArgumentException("Can't find encryption key in key ring.");

    String fileName = src.getFileName().toString();
    byte[] encName = Utf8Encoder.encode(fileName);
    long modificationTime = System.currentTimeMillis();

    SecureRandom rand = new SecureRandom();
    int algorithm = PGPEncryptedData.AES_256;

    Cipher cipher = null;

    ByteBuf leadingbuf = Hub.instance.getBufferAllocator().heapBuffer(1024 * 1024); // 1 mb
    ByteBuf encbuf = Hub.instance.getBufferAllocator().heapBuffer(1024 * 1024); // 1 mb

    // *******************************************************************
    // public key packet
    // *******************************************************************

    PGPKeyEncryptionMethodGenerator method = new JcePublicKeyKeyEncryptionMethodGenerator(pubKey);

    byte[] key = org.bouncycastle.openpgp.PGPUtil.makeRandomKey(algorithm, rand);

    byte[] sessionInfo = new byte[key.length + 3];

    // add algorithm
    sessionInfo[0] = (byte) algorithm;

    // add key
    System.arraycopy(key, 0, sessionInfo, 1, key.length);

    // add checksum 
    int check = 0;

    for (int i = 1; i != sessionInfo.length - 2; i++)
        check += sessionInfo[i] & 0xff;

    sessionInfo[sessionInfo.length - 2] = (byte) (check >> 8);
    sessionInfo[sessionInfo.length - 1] = (byte) (check);

    ContainedPacket packet1 = method.generate(algorithm, sessionInfo);

    byte[] encoded1 = packet1.getEncoded();

    leadingbuf.writeBytes(encoded1);

    // *******************************************************************
    // encrypt packet, add IV to encryption though
    // *******************************************************************

    leadingbuf.writeByte(0xC0 | PacketTags.SYM_ENC_INTEGRITY_PRO);

    this.writePacketLength(leadingbuf, 0); // 0 = we don't know

    leadingbuf.writeByte(1); // version number

    String cName = PGPUtil.getSymmetricCipherName(algorithm) + "/CFB/NoPadding";

    DefaultJcaJceHelper helper = new DefaultJcaJceHelper();

    cipher = helper.createCipher(cName);

    byte[] iv = new byte[cipher.getBlockSize()];

    cipher.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(algorithm, key), new IvParameterSpec(iv));

    // ******************** start encryption **********************

    // --- encrypt checksum for encrypt packet, part of the encrypted output --- 

    byte[] inLineIv = new byte[cipher.getBlockSize() + 2];

    rand.nextBytes(inLineIv);

    inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3];
    inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4];

    encbuf.writeBytes(inLineIv);

    System.out.println("bytes written a: " + encbuf.readableBytes());

    // --- data packet ---

    int chunkpos = 0;

    int headerlen = 1 // format
            + 1 // name length
            + encName.length // file name
            + 4; // time

    encbuf.writeByte(0xC0 | PacketTags.LITERAL_DATA);

    int packetsize = 512 - headerlen;

    if (fileData.length - chunkpos < packetsize) {
        packetsize = fileData.length - chunkpos;

        this.writePacketLength(encbuf, headerlen + packetsize);
    } else {
        encbuf.writeByte(0xE9); // 512 packet length
    }

    System.out.println("bytes written b: " + encbuf.readableBytes());

    encbuf.writeByte(PGPLiteralData.BINARY); // data format

    encbuf.writeByte((byte) encName.length); // file name

    encbuf.writeBytes(encName);

    encbuf.writeInt((int) (modificationTime / 1000)); // mod time

    System.out.println("bytes written c: " + encbuf.readableBytes());

    encbuf.writeBytes(fileData, chunkpos, packetsize);

    System.out.println("bytes written d: " + encbuf.readableBytes());

    chunkpos += packetsize;

    // write one or more literal packets
    while (chunkpos < fileData.length) {
        packetsize = 512;

        // check if this is the final packet
        if (fileData.length - chunkpos <= packetsize) {
            packetsize = fileData.length - chunkpos;

            this.writePacketLength(encbuf, packetsize);
        } else {
            encbuf.writeByte(0xE9); // full 512 packet length
        }

        encbuf.writeBytes(fileData, chunkpos, packetsize);

        chunkpos += packetsize;
    }

    // protection packet
    encbuf.writeByte(0xC0 | PacketTags.MOD_DETECTION_CODE);
    encbuf.writeByte(20); // packet length

    MessageDigest md = MessageDigest.getInstance("SHA-1");
    md.update(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    byte[] rv = md.digest();

    encbuf.writeBytes(rv);

    System.out.println("Pre-Encrypted Hex");

    this.hexDump(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    System.out.println();
    System.out.println();

    // ***** encryption data ready *********

    byte[] encdata = cipher.doFinal(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    // add encrypted data to main buffer
    leadingbuf.writeBytes(encdata);

    System.out.println("Final Hex");

    this.hexDump(leadingbuf.array(), leadingbuf.arrayOffset(), leadingbuf.writerIndex());

    System.out.println();
    System.out.println();

    // write to file
    dest.write(leadingbuf.array(), leadingbuf.arrayOffset(), leadingbuf.writerIndex());

    dest.flush();
    dest.close();
}

From source file:divconq.test.pgp.PGPWriter2.java

License:Open Source License

@SuppressWarnings("resource")
public void test1(String srcpath, String destpath, String keyring) throws Exception {
    Path src = Paths.get(srcpath);

    // file data 
    byte[] story = Files.readAllBytes(src);

    // dest//  ww  w.ja va  2 s  . c  om
    OutputStream dest = new BufferedOutputStream(new FileOutputStream(destpath));

    // encryption key
    PGPPublicKey pubKey = null;

    InputStream keyIn = new BufferedInputStream(new FileInputStream(keyring));

    PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
            org.bouncycastle.openpgp.PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());

    //
    // we just loop through the collection till we find a key suitable for encryption, in the real
    // world you would probably want to be a bit smarter about this.
    //

    @SuppressWarnings("rawtypes")
    Iterator keyRingIter = pgpPub.getKeyRings();

    while (keyRingIter.hasNext() && (pubKey == null)) {
        PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next();

        @SuppressWarnings("rawtypes")
        Iterator keyIter = keyRing.getPublicKeys();

        while (keyIter.hasNext() && (pubKey == null)) {
            PGPPublicKey key = (PGPPublicKey) keyIter.next();

            if (key.isEncryptionKey())
                pubKey = key;
        }
    }

    if (pubKey == null)
        throw new IllegalArgumentException("Can't find encryption key in key ring.");

    String fileName = src.getFileName().toString();
    byte[] encName = Utf8Encoder.encode(fileName);
    long modificationTime = System.currentTimeMillis();

    SecureRandom rand = new SecureRandom();
    int algorithm = PGPEncryptedData.AES_256;

    Cipher cipher = null;

    ByteBuf leadingbuf = Hub.instance.getBufferAllocator().heapBuffer(1024 * 1024); // 1 mb
    ByteBuf encbuf = Hub.instance.getBufferAllocator().heapBuffer(1024 * 1024); // 1 mb

    // *******************************************************************
    // public key packet
    // *******************************************************************

    PGPKeyEncryptionMethodGenerator method = new JcePublicKeyKeyEncryptionMethodGenerator(pubKey);

    byte[] key = org.bouncycastle.openpgp.PGPUtil.makeRandomKey(algorithm, rand);

    byte[] sessionInfo = new byte[key.length + 3];

    // add algorithm
    sessionInfo[0] = (byte) algorithm;

    // add key
    System.arraycopy(key, 0, sessionInfo, 1, key.length);

    // add checksum 
    int check = 0;

    for (int i = 1; i != sessionInfo.length - 2; i++)
        check += sessionInfo[i] & 0xff;

    sessionInfo[sessionInfo.length - 2] = (byte) (check >> 8);
    sessionInfo[sessionInfo.length - 1] = (byte) (check);

    ContainedPacket packet1 = method.generate(algorithm, sessionInfo);

    byte[] encoded1 = packet1.getEncoded();

    leadingbuf.writeBytes(encoded1);

    // *******************************************************************
    // encrypt packet, add IV to 
    // *******************************************************************

    String cName = PGPUtil.getSymmetricCipherName(algorithm) + "/CFB/NoPadding";

    DefaultJcaJceHelper helper = new DefaultJcaJceHelper();

    cipher = helper.createCipher(cName);

    byte[] iv = new byte[cipher.getBlockSize()];

    cipher.init(Cipher.ENCRYPT_MODE, PGPUtil.makeSymmetricKey(algorithm, key), new IvParameterSpec(iv));

    // ******************** start encryption **********************

    // --- encrypt checksum for encrypt packet, part of the encrypted output --- 

    byte[] inLineIv = new byte[cipher.getBlockSize() + 2];

    rand.nextBytes(inLineIv);

    inLineIv[inLineIv.length - 1] = inLineIv[inLineIv.length - 3];
    inLineIv[inLineIv.length - 2] = inLineIv[inLineIv.length - 4];

    encbuf.writeBytes(inLineIv);

    // --- data packet ---

    encbuf.writeByte(0xC0 | PacketTags.LITERAL_DATA);

    this.writePacketLength(encbuf, 1 // format
            + 1 // name length
            + encName.length // file name
            + 4 // time
            + story.length // data
    );

    encbuf.writeByte(PGPLiteralData.BINARY);

    encbuf.writeByte((byte) encName.length);

    encbuf.writeBytes(encName);

    encbuf.writeInt((int) (modificationTime / 1000));

    encbuf.writeBytes(story);

    // protection packet
    encbuf.writeByte(0xC0 | PacketTags.MOD_DETECTION_CODE);
    encbuf.writeByte(20); // packet length

    MessageDigest md = MessageDigest.getInstance("SHA-1");
    md.update(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    byte[] rv = md.digest();

    encbuf.writeBytes(rv);

    System.out.println("Encrypted Hex");

    this.hexDump(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    System.out.println();
    System.out.println();

    // ***** encryption data ready *********

    byte[] encdata = cipher.doFinal(encbuf.array(), encbuf.arrayOffset(), encbuf.writerIndex());

    leadingbuf.writeByte(0xC0 | PacketTags.SYM_ENC_INTEGRITY_PRO);

    /*
    this.writePacketLength(leadingbuf, 
     1      // version 
     + encdata.length       // encrypted data
       );
       */

    this.writePacketLength(leadingbuf, 0); // 0 = we don't know

    leadingbuf.writeByte(1); // version number

    // add encrypted data to main buffer
    leadingbuf.writeBytes(encdata);

    System.out.println("Final Hex");

    this.hexDump(leadingbuf.array(), leadingbuf.arrayOffset(), leadingbuf.writerIndex());

    System.out.println();
    System.out.println();

    // write to file
    dest.write(leadingbuf.array(), leadingbuf.arrayOffset(), leadingbuf.writerIndex());

    dest.flush();
    dest.close();
}

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();/*ww w .ja  v a 2 s.  co 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());
    }/*from w ww. j a v a  2  s . c o m*/

    { // 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());

    }

}