List of usage examples for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER
int CERTIFY_OTHER
To view the source code for org.bouncycastle.bcpg.sig KeyFlags CERTIFY_OTHER.
Click Source Link
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); }