use upstream bouncycastle provider

This commit is contained in:
Vincent Breitmoser 2020-01-23 14:10:39 +01:00
parent a697d7e623
commit 4a4093854d
13 changed files with 68 additions and 66 deletions

View file

@ -56,11 +56,13 @@ dependencies {
implementation project(':openpgp-api-lib') implementation project(':openpgp-api-lib')
implementation project(':nfcsweetspot') implementation project(':nfcsweetspot')
implementation project(':sshauthentication-api') implementation project(':sshauthentication-api')
implementation project(':extern:bouncycastle:core')
implementation project(':extern:bouncycastle:pg')
implementation project(':extern:bouncycastle:prov')
implementation project(':extern:MaterialChipsInput') implementation project(':extern:MaterialChipsInput')
// implementation project(':openkeychain:extern:bouncycastle:core')
implementation 'org.bouncycastle:bcprov-jdk15on:1.65'
implementation project(':extern:bouncycastle:pg')
// implementation project(':openkeychain:extern:bouncycastle:prov')
implementation 'androidx.work:work-runtime:2.2.0' implementation 'androidx.work:work-runtime:2.2.0'
// Unit tests in the local JVM with Robolectric // Unit tests in the local JVM with Robolectric

View file

@ -1,17 +1,19 @@
package org.bouncycastle.openpgp.operator.jcajce; package org.bouncycastle.openpgp.operator.jcajce;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.EdDSAEngine; import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.spec.EdDSANamedCurveTable;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.spec.EdDSAParameterSpec;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPrivateKey; import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPRuntimeOperationException; import org.bouncycastle.openpgp.PGPRuntimeOperationException;
import org.bouncycastle.openpgp.operator.PGPContentSigner; import org.bouncycastle.openpgp.operator.PGPContentSigner;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.*; import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Signature;
import java.security.SignatureException;
public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSignerBuilder { public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSignerBuilder {
private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter(); private JcaPGPKeyConverter keyConverter = new JcaPGPKeyConverter();
@ -33,9 +35,8 @@ public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSigner
return this; return this;
} }
private Signature createSignature() throws NoSuchAlgorithmException { private Signature createSignature() throws PGPException {
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName("Ed25519"); return new OperatorHelper(new DefaultJcaJceHelper()).createSignature(keyAlgorithm, hashAlgorithm);
return new EdDSAEngine(MessageDigest.getInstance(spec.getHashAlgorithm()));
} }
public PGPContentSigner build(final int signatureType, final long keyID, final PrivateKey privateKey) public PGPContentSigner build(final int signatureType, final long keyID, final PrivateKey privateKey)
@ -43,12 +44,12 @@ public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSigner
Signature signatureEdDsa; Signature signatureEdDsa;
try { try {
signatureEdDsa = createSignature(); signatureEdDsa = createSignature();
} catch (NoSuchAlgorithmException e) { } catch (PGPException e) {
throw new PGPException("unable to create Signature.", e); throw new PGPException("unable to create Signature.", e);
} }
final Signature signature = signatureEdDsa; final Signature signature = signatureEdDsa;
final ByteArrayOutputStream dataOutputStream = new ByteArrayOutputStream(); final PGPDigestCalculator digestCalculator = new JcaPGPDigestCalculatorProviderBuilder().build().get(hashAlgorithm);
try { try {
signature.initSign(privateKey); signature.initSign(privateKey);
@ -74,11 +75,12 @@ public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSigner
} }
public OutputStream getOutputStream() { public OutputStream getOutputStream() {
return new SignatureOutputStream(signature); return digestCalculator.getOutputStream();
} }
public byte[] getSignature() { public byte[] getSignature() {
try { try {
signature.update(digestCalculator.getDigest());
return signature.sign(); return signature.sign();
} catch (SignatureException e) { } catch (SignatureException e) {
throw new PGPRuntimeOperationException("Unable to create signature: " + e.getMessage(), e); throw new PGPRuntimeOperationException("Unable to create signature: " + e.getMessage(), e);
@ -86,7 +88,7 @@ public class EdDsaAuthenticationContentSignerBuilder implements PGPContentSigner
} }
public byte[] getDigest() { public byte[] getDigest() {
return null; return digestCalculator.getDigest();
} }
}; };
} }

View file

@ -7,6 +7,15 @@
package org.bouncycastle.openpgp.operator.jcajce; package org.bouncycastle.openpgp.operator.jcajce;
import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Provider; import java.security.Provider;
@ -15,13 +24,6 @@ import javax.crypto.BadPaddingException;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
/** This is a builder for a special PBESecretKeyDecryptor which is parametrized by a /** This is a builder for a special PBESecretKeyDecryptor which is parametrized by a
@ -90,7 +92,7 @@ public class SessionKeySecretKeyDecryptorBuilder
{ {
Cipher c = helper.createCipher(PGPUtil.getSymmetricCipherName(encAlgorithm) + "/CFB/NoPadding"); Cipher c = helper.createCipher(PGPUtil.getSymmetricCipherName(encAlgorithm) + "/CFB/NoPadding");
c.init(Cipher.DECRYPT_MODE, PGPUtil.makeSymmetricKey(encAlgorithm, key), new IvParameterSpec(iv)); c.init(Cipher.DECRYPT_MODE, JcaJcePGPUtil.makeSymmetricKey(encAlgorithm, key), new IvParameterSpec(iv));
return c.doFinal(keyData, keyOff, keyLen); return c.doFinal(keyData, keyOff, keyLen);
} }

View file

@ -22,6 +22,7 @@ import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
@ -46,7 +47,11 @@ import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.Features;
import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.bcpg.sig.RevocationReasonTags; import org.bouncycastle.bcpg.sig.RevocationReasonTags;
import org.bouncycastle.jcajce.provider.asymmetric.eddsa.spec.EdDSAGenParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.jce.spec.ElGamalParameterSpec; import org.bouncycastle.jce.spec.ElGamalParameterSpec;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyFlags; import org.bouncycastle.openpgp.PGPKeyFlags;
@ -250,10 +255,8 @@ public class PgpKeyOperation {
return null; return null;
} }
progress(R.string.progress_generating_eddsa, 30); progress(R.string.progress_generating_eddsa, 30);
EdDSAGenParameterSpec edParamSpec = keyGen = KeyPairGenerator.getInstance("ED25519", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
new EdDSAGenParameterSpec("ed25519"); keyGen.initialize(256, new SecureRandom());
keyGen = KeyPairGenerator.getInstance("EdDSA", Constants.BOUNCY_CASTLE_PROVIDER_NAME);
keyGen.initialize(edParamSpec, new SecureRandom());
algorithm = PGPPublicKey.EDDSA; algorithm = PGPPublicKey.EDDSA;
break; break;
@ -281,7 +284,8 @@ public class PgpKeyOperation {
} }
// build new key pair // build new key pair
return new JcaPGPKeyPair(algorithm, keyGen.generateKeyPair(), creationTime); KeyPair keyPair = keyGen.generateKeyPair();
return new JcaPGPKeyPair(algorithm, keyPair, creationTime);
} catch(NoSuchProviderException | InvalidAlgorithmParameterException e) { } catch(NoSuchProviderException | InvalidAlgorithmParameterException e) {
throw new RuntimeException(e); throw new RuntimeException(e);

View file

@ -48,10 +48,10 @@ import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData; import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator; import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPSignatureGenerator; import org.bouncycastle.openpgp.PGPSignatureGenerator;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator; import org.bouncycastle.openpgp.operator.jcajce.JcePBEKeyEncryptionMethodGenerator;
import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder; import org.bouncycastle.openpgp.operator.jcajce.JcePGPDataEncryptorBuilder;
import org.bouncycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.jcajce.NfcSyncPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.PGPUtil;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.daos.KeyRepository; import org.sufficientlysecure.keychain.daos.KeyRepository;

View file

@ -19,13 +19,11 @@ package org.sufficientlysecure.keychain.pgp;
import org.bouncycastle.bcpg.DSAPublicBCPGKey; import org.bouncycastle.bcpg.DSAPublicBCPGKey;
import org.bouncycastle.bcpg.ECPublicBCPGKey; import org.bouncycastle.bcpg.ECPublicBCPGKey;
import org.bouncycastle.bcpg.EdDSAPublicBCPGKey;
import org.bouncycastle.bcpg.RSAPublicBCPGKey; import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPPublicKey;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
import org.sufficientlysecure.keychain.ssh.key.SshDSAPublicKey; import org.sufficientlysecure.keychain.ssh.key.SshDSAPublicKey;
import org.sufficientlysecure.keychain.ssh.key.SshECDSAPublicKey; import org.sufficientlysecure.keychain.ssh.key.SshECDSAPublicKey;
import org.sufficientlysecure.keychain.ssh.key.SshEd25519PublicKey;
import org.sufficientlysecure.keychain.ssh.key.SshRSAPublicKey; import org.sufficientlysecure.keychain.ssh.key.SshRSAPublicKey;
import org.sufficientlysecure.keychain.ssh.utils.SshUtils; import org.sufficientlysecure.keychain.ssh.utils.SshUtils;
@ -48,8 +46,9 @@ public class SshPublicKey {
return encodeRSAKey(key); return encodeRSAKey(key);
case PGPPublicKey.ECDSA: case PGPPublicKey.ECDSA:
return encodeECKey(key); return encodeECKey(key);
case PGPPublicKey.EDDSA: // TODO
return encodeEdDSAKey(key); // case PGPPublicKey.EDDSA:
// return encodeEdDSAKey(key);
case PGPPublicKey.DSA: case PGPPublicKey.DSA:
return encodeDSAKey(key); return encodeDSAKey(key);
default: default:
@ -76,13 +75,13 @@ public class SshPublicKey {
private String encodeEdDSAKey(PGPPublicKey publicKey) { // private String encodeEdDSAKey(PGPPublicKey publicKey) {
EdDSAPublicBCPGKey publicBCPGKey = (EdDSAPublicBCPGKey) publicKey.getPublicKeyPacket().getKey(); // EdDSAPublicBCPGKey publicBCPGKey = (EdDSAPublicBCPGKey) publicKey.getPublicKeyPacket().getKey();
//
SshEd25519PublicKey pubkey = new SshEd25519PublicKey(publicBCPGKey.getEdDSAEncodedPoint()); // SshEd25519PublicKey pubkey = new SshEd25519PublicKey(publicBCPGKey.getEdDSAEncodedPoint());
//
return pubkey.getPublicKeyBlob(); // return pubkey.getPublicKeyBlob();
} // }
private String encodeDSAKey(PGPPublicKey publicKey) { private String encodeDSAKey(PGPPublicKey publicKey) {
DSAPublicBCPGKey publicBCPGKey = (DSAPublicBCPGKey) publicKey.getPublicKeyPacket().getKey(); DSAPublicBCPGKey publicBCPGKey = (DSAPublicBCPGKey) publicKey.getPublicKeyPacket().getKey();

View file

@ -672,7 +672,7 @@ public class UncachedKeyRing {
} }
// If NO user ids remain, error out! // If NO user ids remain, error out!
if (modified == null || !modified.getUserIDs().hasNext()) { if (modified == null || !modified.getRawUserIDs().hasNext()) {
log.add(LogType.MSG_KC_ERROR_NO_UID, indent); log.add(LogType.MSG_KC_ERROR_NO_UID, indent);
return null; return null;
} }

View file

@ -18,21 +18,12 @@
package org.sufficientlysecure.keychain.securitytoken.operations; package org.sufficientlysecure.keychain.securitytoken.operations;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import javax.crypto.Cipher; import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.jcajce.util.MessageDigestUtils; import org.bouncycastle.jcajce.util.MessageDigestUtils;
import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
@ -48,6 +39,16 @@ import org.sufficientlysecure.keychain.securitytoken.KeyFormat;
import org.sufficientlysecure.keychain.securitytoken.ResponseApdu; import org.sufficientlysecure.keychain.securitytoken.ResponseApdu;
import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection; import org.sufficientlysecure.keychain.securitytoken.SecurityTokenConnection;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
/** This class implements the PSO:DECIPHER operation, as specified in OpenPGP card spec / 7.2.11 (p52 in v3.0.1). /** This class implements the PSO:DECIPHER operation, as specified in OpenPGP card spec / 7.2.11 (p52 in v3.0.1).
* *
@ -196,7 +197,8 @@ public class PsoDecryptTokenOp {
} }
private byte[] getEcDecipherPayload(ECKeyFormat eckf, byte[] encryptedPoint) throws CardException { private byte[] getEcDecipherPayload(ECKeyFormat eckf, byte[] encryptedPoint) throws CardException {
if (CustomNamedCurves.CV25519.equals(eckf.getCurveOID())) { // TODO is this the right curve?
if (CryptlibObjectIdentifiers.curvey25519.equals(eckf.getCurveOID())) {
return Arrays.copyOfRange(encryptedPoint, 1, 33); return Arrays.copyOfRange(encryptedPoint, 1, 33);
} else { } else {
X9ECParameters x9Params = ECNamedCurveTable.getByOID(eckf.getCurveOID()); X9ECParameters x9Params = ECNamedCurveTable.getByOID(eckf.getCurveOID());

View file

@ -39,7 +39,7 @@ import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.crypto.ec.CustomNamedCurves; import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.operator.jcajce.PGPUtil; import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import org.openintents.openpgp.OpenPgpDecryptionResult; import org.openintents.openpgp.OpenPgpDecryptionResult;
import org.openintents.openpgp.OpenPgpSignatureResult; import org.openintents.openpgp.OpenPgpSignatureResult;

View file

@ -21,15 +21,6 @@ allprojects {
} }
} }
// Ignore tests for external bouncycastle
project(':extern:bouncycastle') {
subprojects {
// Need to re-apply the plugin here otherwise the test property below can't be set.
apply plugin: 'java'
test.enabled = false
}
}
// SDK Version and Build Tools used by all subprojects // SDK Version and Build Tools used by all subprojects
// See http://tools.android.com/tech-docs/new-build-system/tips#TOC-Controlling-Android-properties-of-all-your-modules-from-the-main-project. // See http://tools.android.com/tech-docs/new-build-system/tips#TOC-Controlling-Android-properties-of-all-your-modules-from-the-main-project.
ext { ext {

2
extern/bouncycastle vendored

@ -1 +1 @@
Subproject commit c260cecf0b80c986e7461f63d3c12aed72d4be4d Subproject commit 596f050d09dc1a87c09b45e822c673399f41bab1

View file

@ -1,2 +1,3 @@
android.enableJetifier=true android.enableJetifier=true
android.useAndroidX=true android.useAndroidX=true
android.jetifier.blacklist=bcprov-jdk15on

View file

@ -2,7 +2,6 @@ include ':OpenKeychain'
include ':nfcsweetspot' include ':nfcsweetspot'
include ':extern:bouncycastle:core' include ':extern:bouncycastle:core'
include ':extern:bouncycastle:pg' include ':extern:bouncycastle:pg'
include ':extern:bouncycastle:prov'
include ':extern:minidns' include ':extern:minidns'
include ':extern:MaterialChipsInput:library' include ':extern:MaterialChipsInput:library'