Example usage for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER

List of usage examples for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER

Introduction

In this page you can find the example usage for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER.

Prototype

int CERTIFY_OTHER

To view the source code for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER.

Click Source Link

Usage

From source file:keygenerator.KeyGenerator.java

public final static PGPKeyRingGenerator generateKeyRingGenerator(String id, char[] pass, int s2kcount)
        throws Exception {
    // This object generates individual key-pairs.
    RSAKeyPairGenerator kpg = new RSAKeyPairGenerator();

    // Boilerplate RSA parameters, no need to change anything
    // except for the RSA key-size (2048). You can use whatever
    // key-size makes sense for you -- 4096, etc.
    kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 2048, 12));

    // First create the master (signing) key with the generator.
    PGPKeyPair rsakp_sign = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpg.generateKeyPair(), new Date());
    // Then an encryption subkey.
    PGPKeyPair rsakp_enc = new BcPGPKeyPair(PGPPublicKey.RSA_ENCRYPT, kpg.generateKeyPair(), new Date());

    // Add a self-signature on the id
    PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator();

    // Add signed metadata on the signature.
    // 1) Declare its purpose
    signhashgen.setKeyFlags(false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER);
    // 2) Set preferences for secondary crypto algorithms to use
    //    when sending messages to this key.
    signhashgen.setPreferredSymmetricAlgorithms(false, new int[] { SymmetricKeyAlgorithmTags.AES_256,
            SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 });
    signhashgen.setPreferredHashAlgorithms(false, new int[] { HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1,
            HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA224, });
    // 3) Request senders add additional checksums to the
    //    message (useful when verifying unsigned messages.)
    signhashgen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION);

    // Create a signature on the encryption subkey.
    PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator();
    // Add metadata to declare its purpose
    enchashgen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);

    // Objects used to encrypt the secret key.
    PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1);
    PGPDigestCalculator sha256Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA256);

    // bcpg 1.48 exposes this API that includes s2kcount. Earlier
    // versions use a default of 0x60.
    PBESecretKeyEncryptor pske = (new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha256Calc,
            s2kcount)).build(pass);/* w w  w.  ja va2  s  .c  o  m*/

    // Finally, create the keyring itself. The constructor
    // takes parameters that allow it to generate the self
    // signature.

    BcPGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(
            rsakp_sign.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1);

    PGPKeyRingGenerator keyRingGen;
    keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, id, sha1Calc,
            signhashgen.generate(), null, signerBuilder, pske);

    // Add our encryption subkey, together with its signature.
    keyRingGen.addSubKey(rsakp_enc, enchashgen.generate(), null);
    return keyRingGen;
}

From source file:org.sufficientlysecure.keychain.operations.BackupOperationTest.java

License:Open Source License

@BeforeClass
public static void setUpOnce() throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    oldShadowStream = ShadowLog.stream;/*from  w ww . ja  v  a 2 s  . com*/
    // ShadowLog.stream = System.out;

    PgpKeyOperation op = new PgpKeyOperation(null);

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("snips");
        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase1));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing1 = result.getRing();
    }

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("snails");
        parcel.setNewUnlock(new ChangeUnlockParcel(new Passphrase("1234")));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing2 = result.getRing();
        mStaticRing2 = UncachedKeyRing.forTestingOnlyAddDummyLocalSignature(mStaticRing2, "1234");
    }

}

From source file:org.sufficientlysecure.keychain.operations.CertifyOperationTest.java

License:Open Source License

@BeforeClass
public static void setUpOnce() throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    oldShadowStream = ShadowLog.stream;// w w  w  .ja  v  a2 s .  co  m
    // ShadowLog.stream = System.out;

    Random random = new Random();

    PgpKeyOperation op = new PgpKeyOperation(null);

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("derp");
        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase1));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        Assert.assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing1 = result.getRing();
    }

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));

        parcel.mAddUserIds.add("ditz");
        byte[] uatdata = new byte[random.nextInt(150) + 10];
        random.nextBytes(uatdata);
        parcel.mAddUserAttribute.add(WrappedUserAttribute.fromSubpacket(random.nextInt(100) + 1, uatdata));

        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase2));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        Assert.assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing2 = result.getRing();
    }

}

From source file:org.sufficientlysecure.keychain.operations.ExportTest.java

License:Open Source License

@BeforeClass
public static void setUpOnce() throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    oldShadowStream = ShadowLog.stream;//from  www  .  ja va 2s.c  om
    // ShadowLog.stream = System.out;

    PgpKeyOperation op = new PgpKeyOperation(null);

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("snips");
        parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhrase1);

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing1 = result.getRing();
    }

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("snails");
        parcel.mNewUnlock = new ChangeUnlockParcel(new Passphrase("1234"));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing2 = result.getRing();
        mStaticRing2 = UncachedKeyRing.forTestingOnlyAddDummyLocalSignature(mStaticRing2, "1234");
    }

}

From source file:org.sufficientlysecure.keychain.operations.PromoteKeyOperationTest.java

License:Open Source License

@BeforeClass
public static void setUpOnce() throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    oldShadowStream = ShadowLog.stream;/*from w  w  w  .  ja  va 2  s  .c  om*/
    // ShadowLog.stream = System.out;

    PgpKeyOperation op = new PgpKeyOperation(null);

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("derp");
        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase1));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        Assert.assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing = result.getRing();
    }

}

From source file:org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKey.java

License:Open Source License

public boolean canCertify() {
    // if key flags subpacket is available, honor it!
    if (getKeyUsage() != 0) {
        return (getKeyUsage() & KeyFlags.CERTIFY_OTHER) != 0;
    }//from ww  w  . j a  v  a2 s.  co m

    if (UncachedKeyRing.isSigningAlgo(mPublicKey.getAlgorithm())) {
        return true;
    }

    return false;
}

From source file:org.sufficientlysecure.keychain.pgp.PgpEncryptDecryptTest.java

License:Open Source License

@BeforeClass
public static void setUpOnce() throws Exception {
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
    oldShadowStream = ShadowLog.stream;/* w  w  w.ja  v  a  2 s  .  com*/
    // ShadowLog.stream = System.out;

    PgpKeyOperation op = new PgpKeyOperation(null);

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("bloom");
        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase1));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        Assert.assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing1 = result.getRing();
    }

    {
        SaveKeyringParcel parcel = new SaveKeyringParcel();
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.CERTIFY_OTHER, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDSA, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.SIGN_DATA, 0L));
        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Algorithm.ECDH, 0,
                SaveKeyringParcel.Curve.NIST_P256, KeyFlags.ENCRYPT_COMMS, 0L));
        parcel.mAddUserIds.add("belle");
        parcel.setNewUnlock(new ChangeUnlockParcel(mKeyPhrase2));

        PgpEditKeyResult result = op.createSecretKeyRing(parcel);
        Assert.assertTrue("initial test key creation must succeed", result.success());
        Assert.assertNotNull("initial test key creation must succeed", result.getRing());

        mStaticRing2 = result.getRing();
    }

    //        {
    //            // insecure (1024 bit) RSA key
    //            SaveKeyringParcel parcel = new SaveKeyringParcel();
    //            parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
    //                    Algorithm.RSA, 1024, null, KeyFlags.CERTIFY_OTHER, 0L));
    //            parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
    //                    Algorithm.RSA, 1024, null, KeyFlags.SIGN_DATA, 0L));
    //            parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(
    //                    Algorithm.RSA, 1024, null, KeyFlags.ENCRYPT_COMMS, 0L));
    //            parcel.mAddUserIds.add("eve");
    //            parcel.mNewUnlock = new ChangeUnlockParcel(mKeyPhraseInsecure);
    //
    //            PgpEditKeyResult result = op.createSecretKeyRing(parcel);
    //            Assert.assertTrue("initial test key creation must succeed", result.success());
    //            Assert.assertNotNull("initial test key creation must succeed", result.getRing());
    //
    //            mStaticRingInsecure = result.getRing();
    //        }

}

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();// w  w  w  . ja  v a 2 s . c om

        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.PgpKeyOperation.java

License:Open Source License

public PgpEditKeyResult createSecretKeyRing(SaveKeyringParcel saveParcel) {

    OperationLog log = new OperationLog();
    int indent = 0;

    try {/*from  w  w  w.  ja v a  2 s .  com*/

        log.add(LogType.MSG_CR, indent);
        progress(R.string.progress_building_key, 0);
        indent += 1;

        if (saveParcel.mAddSubKeys.isEmpty()) {
            log.add(LogType.MSG_CR_ERROR_NO_MASTER, indent);
            return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
        }

        if (saveParcel.mAddUserIds.isEmpty()) {
            log.add(LogType.MSG_CR_ERROR_NO_USER_ID, indent);
            return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
        }

        SubkeyAdd add = saveParcel.mAddSubKeys.remove(0);
        if ((add.mFlags & KeyFlags.CERTIFY_OTHER) != KeyFlags.CERTIFY_OTHER) {
            log.add(LogType.MSG_CR_ERROR_NO_CERTIFY, indent);
            return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
        }

        if (add.mExpiry == null) {
            log.add(LogType.MSG_CR_ERROR_NULL_EXPIRY, indent);
            return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
        }

        Date creationTime = new Date();

        subProgressPush(10, 30);
        PGPKeyPair keyPair = createKey(add, creationTime, log, indent);
        subProgressPop();

        // return null if this failed (an error will already have been logged by createKey)
        if (keyPair == null) {
            return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
        }

        progress(R.string.progress_building_master_key, 40);

        // Build key encrypter and decrypter based on passphrase
        PGPDigestCalculator encryptorHashCalc = new JcaPGPDigestCalculatorProviderBuilder().build()
                .get(PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_HASH_ALGO);
        PBESecretKeyEncryptor keyEncryptor = new JcePBESecretKeyEncryptorBuilder(
                PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_SYMMETRIC_ALGO, encryptorHashCalc,
                PgpSecurityConstants.SECRET_KEY_ENCRYPTOR_S2K_COUNT)
                        .setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build("".toCharArray());

        PGPDigestCalculator sha1Calc = new JcaPGPDigestCalculatorProviderBuilder().build()
                .get(PgpSecurityConstants.SECRET_KEY_SIGNATURE_CHECKSUM_HASH_ALGO);
        PGPSecretKey masterSecretKey = new PGPSecretKey(keyPair.getPrivateKey(), keyPair.getPublicKey(),
                sha1Calc, true, keyEncryptor);

        PGPSecretKeyRing sKR = new PGPSecretKeyRing(masterSecretKey.getEncoded(),
                new JcaKeyFingerprintCalculator());

        subProgressPush(50, 100);
        CryptoInputParcel cryptoInput = new CryptoInputParcel(creationTime, new Passphrase(""));
        return internal(sKR, masterSecretKey, add.mFlags, add.mExpiry, cryptoInput, saveParcel, log, indent);

    } catch (PGPException e) {
        log.add(LogType.MSG_CR_ERROR_INTERNAL_PGP, indent);
        Log.e(Constants.TAG, "pgp error encoding key", e);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    } catch (IOException e) {
        Log.e(Constants.TAG, "io error encoding key", e);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    }

}

From source file:org.sufficientlysecure.keychain.pgp.PgpKeyOperation.java

License:Open Source License

/** This method introduces a list of modifications specified by a SaveKeyringParcel to a
 * WrappedSecretKeyRing./*from ww w  .  j  ava  2s  .c om*/
 *
 * This method relies on WrappedSecretKeyRing's canonicalization property!
 *
 * Note that PGPPublicKeyRings can not be directly modified. Instead, the corresponding
 * PGPSecretKeyRing must be modified and consequently consolidated with its public counterpart.
 * This is a natural workflow since pgp keyrings are immutable data structures: Old semantics
 * are changed by adding new certificates, which implicitly override older certificates.
 *
 * Note that this method does not care about any "special" type of master key. If unlocking
 * with a passphrase fails, the operation will fail with an unlocking error. More specific
 * handling of errors should be done in UI code!
 *
 * If the passphrase is null, only a restricted subset of operations will be available,
 * namely stripping of subkeys and changing the protection mode of dummy keys.
 *
 */
public PgpEditKeyResult modifySecretKeyRing(CanonicalizedSecretKeyRing wsKR, CryptoInputParcel cryptoInput,
        SaveKeyringParcel saveParcel) {

    OperationLog log = new OperationLog();
    int indent = 0;

    /*
     * 1. Unlock private key
     * 2a. Add certificates for new user ids
     * 2b. Add revocations for revoked user ids
     * 3. If primary user id changed, generate new certificates for both old and new
     * 4a. For each subkey change, generate new subkey binding certificate
     * 4b. For each subkey revocation, generate new subkey revocation certificate
     * 5. Generate and add new subkeys
     * 6. If requested, change passphrase
     */

    log.add(LogType.MSG_MF, indent, KeyFormattingUtils.convertKeyIdToHex(wsKR.getMasterKeyId()));
    indent += 1;
    progress(R.string.progress_building_key, 0);

    // Make sure this is called with a proper SaveKeyringParcel
    if (saveParcel.mMasterKeyId == null || saveParcel.mMasterKeyId != wsKR.getMasterKeyId()) {
        log.add(LogType.MSG_MF_ERROR_KEYID, indent);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    }

    // We work on bouncycastle object level here
    PGPSecretKeyRing sKR = wsKR.getRing();
    PGPSecretKey masterSecretKey = sKR.getSecretKey();

    // Make sure the fingerprint matches
    if (saveParcel.mFingerprint == null
            || !Arrays.equals(saveParcel.mFingerprint, masterSecretKey.getPublicKey().getFingerprint())) {
        log.add(LogType.MSG_MF_ERROR_FINGERPRINT, indent);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    }

    if (saveParcel.isEmpty()) {
        log.add(LogType.MSG_MF_ERROR_NOOP, indent);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    }

    // Ensure we don't have multiple keys for the same slot.
    boolean hasSign = false;
    boolean hasEncrypt = false;
    boolean hasAuth = false;
    for (SaveKeyringParcel.SubkeyChange change : saveParcel.mChangeSubKeys) {
        if (change.mMoveKeyToSecurityToken) {
            // If this is a moveKeyToSecurityToken operation, see if it was completed: look for a hash
            // matching the given subkey ID in cryptoData.
            byte[] subKeyId = new byte[8];
            ByteBuffer buf = ByteBuffer.wrap(subKeyId);
            buf.putLong(change.mKeyId).rewind();

            byte[] serialNumber = cryptoInput.getCryptoData().get(buf);
            if (serialNumber != null) {
                change.mMoveKeyToSecurityToken = false;
                change.mSecurityTokenSerialNo = serialNumber;
            }
        }

        if (change.mMoveKeyToSecurityToken) {
            // Pending moveKeyToSecurityToken operation. Need to make sure that we don't have multiple
            // subkeys pending for the same slot.
            CanonicalizedSecretKey wsK = wsKR.getSecretKey(change.mKeyId);

            if ((wsK.canSign() || wsK.canCertify())) {
                if (hasSign) {
                    log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
                    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
                } else {
                    hasSign = true;
                }
            } else if ((wsK.canEncrypt())) {
                if (hasEncrypt) {
                    log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
                    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
                } else {
                    hasEncrypt = true;
                }
            } else if ((wsK.canAuthenticate())) {
                if (hasAuth) {
                    log.add(LogType.MSG_MF_ERROR_DUPLICATE_KEYTOCARD_FOR_SLOT, indent + 1);
                    return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
                } else {
                    hasAuth = true;
                }
            } else {
                log.add(LogType.MSG_MF_ERROR_INVALID_FLAGS_FOR_KEYTOCARD, indent + 1);
                return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
            }
        }
    }

    if (isDummy(masterSecretKey) && !saveParcel.isRestrictedOnly()) {
        log.add(LogType.MSG_EK_ERROR_DUMMY, indent);
        return new PgpEditKeyResult(PgpEditKeyResult.RESULT_ERROR, log, null);
    }

    if (isDummy(masterSecretKey) || saveParcel.isRestrictedOnly()) {
        log.add(LogType.MSG_MF_RESTRICTED_MODE, indent);
        return internalRestricted(sKR, saveParcel, log, indent + 1);
    }

    // Do we require a passphrase? If so, pass it along
    if (!isDivertToCard(masterSecretKey) && !cryptoInput.hasPassphrase()) {
        log.add(LogType.MSG_MF_REQUIRE_PASSPHRASE, indent);
        return new PgpEditKeyResult(log,
                RequiredInputParcel.createRequiredSignPassphrase(masterSecretKey.getKeyID(),
                        masterSecretKey.getKeyID(), cryptoInput.getSignatureTime()),
                cryptoInput);
    }

    // read masterKeyFlags, and use the same as before.
    // since this is the master key, this contains at least CERTIFY_OTHER
    PGPPublicKey masterPublicKey = masterSecretKey.getPublicKey();
    int masterKeyFlags = readKeyFlags(masterPublicKey) | KeyFlags.CERTIFY_OTHER;
    Date expiryTime = wsKR.getPublicKey().getExpiryTime();
    long masterKeyExpiry = expiryTime != null ? expiryTime.getTime() / 1000 : 0L;

    return internal(sKR, masterSecretKey, masterKeyFlags, masterKeyExpiry, cryptoInput, saveParcel, log,
            indent);

}