328 lines
17 KiB
Java
328 lines
17 KiB
Java
|
package org.bouncycastle.jce.provider;
|
||
|
|
||
|
import java.io.IOException;
|
||
|
import java.io.ObjectInputStream;
|
||
|
import java.io.ObjectOutputStream;
|
||
|
import java.math.BigInteger;
|
||
|
import java.security.interfaces.ECPublicKey;
|
||
|
import java.security.spec.ECParameterSpec;
|
||
|
import java.security.spec.EllipticCurve;
|
||
|
import org.bouncycastle.asn1.ASN1Encodable;
|
||
|
import org.bouncycastle.asn1.ASN1Null;
|
||
|
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||
|
import org.bouncycastle.asn1.ASN1OctetString;
|
||
|
import org.bouncycastle.asn1.ASN1Primitive;
|
||
|
import org.bouncycastle.asn1.ASN1Sequence;
|
||
|
import org.bouncycastle.asn1.DERBitString;
|
||
|
import org.bouncycastle.asn1.DERNull;
|
||
|
import org.bouncycastle.asn1.DEROctetString;
|
||
|
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
|
||
|
import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
|
||
|
import org.bouncycastle.asn1.cryptopro.GOST3410PublicKeyAlgParameters;
|
||
|
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||
|
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||
|
import org.bouncycastle.asn1.x9.X962Parameters;
|
||
|
import org.bouncycastle.asn1.x9.X9ECParameters;
|
||
|
import org.bouncycastle.asn1.x9.X9ECPoint;
|
||
|
import org.bouncycastle.asn1.x9.X9IntegerConverter;
|
||
|
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
|
||
|
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||
|
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
|
||
|
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
|
||
|
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
|
||
|
import org.bouncycastle.jce.ECGOST3410NamedCurveTable;
|
||
|
import org.bouncycastle.jce.interfaces.ECPointEncoder;
|
||
|
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
|
||
|
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
|
||
|
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||
|
import org.bouncycastle.math.ec.ECCurve;
|
||
|
import org.bouncycastle.math.ec.ECPoint;
|
||
|
import org.bouncycastle.util.Strings;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class JCEECPublicKey implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder {
|
||
|
private String algorithm;
|
||
|
private ECParameterSpec ecSpec;
|
||
|
private GOST3410PublicKeyAlgParameters gostParams;
|
||
|
private ECPoint q;
|
||
|
private boolean withCompression;
|
||
|
|
||
|
public String toString() {
|
||
|
StringBuffer stringBuffer = new StringBuffer("EC Public Key");
|
||
|
String lineSeparator = Strings.lineSeparator();
|
||
|
stringBuffer.append(lineSeparator);
|
||
|
stringBuffer.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(lineSeparator);
|
||
|
stringBuffer.append(" Y: ").append(this.q.getAffineYCoord().toBigInteger().toString(16)).append(lineSeparator);
|
||
|
return stringBuffer.toString();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.jce.interfaces.ECPointEncoder
|
||
|
public void setPointFormat(String str) {
|
||
|
this.withCompression = !"UNCOMPRESSED".equalsIgnoreCase(str);
|
||
|
}
|
||
|
|
||
|
public int hashCode() {
|
||
|
return engineGetQ().hashCode() ^ engineGetSpec().hashCode();
|
||
|
}
|
||
|
|
||
|
@Override // java.security.interfaces.ECPublicKey
|
||
|
public java.security.spec.ECPoint getW() {
|
||
|
return new java.security.spec.ECPoint(this.q.getAffineXCoord().toBigInteger(), this.q.getAffineYCoord().toBigInteger());
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.jce.interfaces.ECPublicKey
|
||
|
public ECPoint getQ() {
|
||
|
return this.ecSpec == null ? this.q.getDetachedPoint() : this.q;
|
||
|
}
|
||
|
|
||
|
@Override // java.security.interfaces.ECKey
|
||
|
public ECParameterSpec getParams() {
|
||
|
return this.ecSpec;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.jce.interfaces.ECKey
|
||
|
public org.bouncycastle.jce.spec.ECParameterSpec getParameters() {
|
||
|
ECParameterSpec eCParameterSpec = this.ecSpec;
|
||
|
if (eCParameterSpec == null) {
|
||
|
return null;
|
||
|
}
|
||
|
return EC5Util.convertSpec(eCParameterSpec, this.withCompression);
|
||
|
}
|
||
|
|
||
|
@Override // java.security.Key
|
||
|
public String getFormat() {
|
||
|
return "X.509";
|
||
|
}
|
||
|
|
||
|
@Override // java.security.Key
|
||
|
public byte[] getEncoded() {
|
||
|
X962Parameters x962Parameters;
|
||
|
SubjectPublicKeyInfo subjectPublicKeyInfo;
|
||
|
if (this.algorithm.equals("ECGOST3410")) {
|
||
|
ASN1Encodable aSN1Encodable = this.gostParams;
|
||
|
if (aSN1Encodable == null) {
|
||
|
ECParameterSpec eCParameterSpec = this.ecSpec;
|
||
|
if (eCParameterSpec instanceof ECNamedCurveSpec) {
|
||
|
aSN1Encodable = new GOST3410PublicKeyAlgParameters(ECGOST3410NamedCurves.getOID(((ECNamedCurveSpec) eCParameterSpec).getName()), CryptoProObjectIdentifiers.gostR3411_94_CryptoProParamSet);
|
||
|
} else {
|
||
|
ECCurve convertCurve = EC5Util.convertCurve(eCParameterSpec.getCurve());
|
||
|
aSN1Encodable = new X962Parameters(new X9ECParameters(convertCurve, EC5Util.convertPoint(convertCurve, this.ecSpec.getGenerator(), this.withCompression), this.ecSpec.getOrder(), BigInteger.valueOf(this.ecSpec.getCofactor()), this.ecSpec.getCurve().getSeed()));
|
||
|
}
|
||
|
}
|
||
|
BigInteger bigInteger = this.q.getAffineXCoord().toBigInteger();
|
||
|
BigInteger bigInteger2 = this.q.getAffineYCoord().toBigInteger();
|
||
|
byte[] bArr = new byte[64];
|
||
|
extractBytes(bArr, 0, bigInteger);
|
||
|
extractBytes(bArr, 32, bigInteger2);
|
||
|
try {
|
||
|
subjectPublicKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, aSN1Encodable), new DEROctetString(bArr));
|
||
|
} catch (IOException unused) {
|
||
|
return null;
|
||
|
}
|
||
|
} else {
|
||
|
ECParameterSpec eCParameterSpec2 = this.ecSpec;
|
||
|
if (eCParameterSpec2 instanceof ECNamedCurveSpec) {
|
||
|
ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec) eCParameterSpec2).getName());
|
||
|
if (namedCurveOid == null) {
|
||
|
namedCurveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec) this.ecSpec).getName());
|
||
|
}
|
||
|
x962Parameters = new X962Parameters(namedCurveOid);
|
||
|
} else if (eCParameterSpec2 == null) {
|
||
|
x962Parameters = new X962Parameters((ASN1Null) DERNull.INSTANCE);
|
||
|
} else {
|
||
|
ECCurve convertCurve2 = EC5Util.convertCurve(eCParameterSpec2.getCurve());
|
||
|
x962Parameters = new X962Parameters(new X9ECParameters(convertCurve2, EC5Util.convertPoint(convertCurve2, this.ecSpec.getGenerator(), this.withCompression), this.ecSpec.getOrder(), BigInteger.valueOf(this.ecSpec.getCofactor()), this.ecSpec.getCurve().getSeed()));
|
||
|
}
|
||
|
subjectPublicKeyInfo = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, x962Parameters), ((ASN1OctetString) new X9ECPoint(engineGetQ().getCurve().createPoint(getQ().getAffineXCoord().toBigInteger(), getQ().getAffineYCoord().toBigInteger(), this.withCompression)).toASN1Primitive()).getOctets());
|
||
|
}
|
||
|
return KeyUtil.getEncodedSubjectPublicKeyInfo(subjectPublicKeyInfo);
|
||
|
}
|
||
|
|
||
|
@Override // java.security.Key
|
||
|
public String getAlgorithm() {
|
||
|
return this.algorithm;
|
||
|
}
|
||
|
|
||
|
public boolean equals(Object obj) {
|
||
|
if (!(obj instanceof JCEECPublicKey)) {
|
||
|
return false;
|
||
|
}
|
||
|
JCEECPublicKey jCEECPublicKey = (JCEECPublicKey) obj;
|
||
|
return engineGetQ().equals(jCEECPublicKey.engineGetQ()) && engineGetSpec().equals(jCEECPublicKey.engineGetSpec());
|
||
|
}
|
||
|
|
||
|
org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() {
|
||
|
ECParameterSpec eCParameterSpec = this.ecSpec;
|
||
|
return eCParameterSpec != null ? EC5Util.convertSpec(eCParameterSpec, this.withCompression) : BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
|
||
|
}
|
||
|
|
||
|
public ECPoint engineGetQ() {
|
||
|
return this.q;
|
||
|
}
|
||
|
|
||
|
private void writeObject(ObjectOutputStream objectOutputStream) throws IOException {
|
||
|
objectOutputStream.writeObject(getEncoded());
|
||
|
objectOutputStream.writeObject(this.algorithm);
|
||
|
objectOutputStream.writeBoolean(this.withCompression);
|
||
|
}
|
||
|
|
||
|
private void readObject(ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
|
||
|
populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray((byte[]) objectInputStream.readObject())));
|
||
|
this.algorithm = (String) objectInputStream.readObject();
|
||
|
this.withCompression = objectInputStream.readBoolean();
|
||
|
}
|
||
|
|
||
|
private void populateFromPubKeyInfo(SubjectPublicKeyInfo subjectPublicKeyInfo) {
|
||
|
ECCurve curve;
|
||
|
ECParameterSpec eCParameterSpec;
|
||
|
ECCurve curve2;
|
||
|
byte[] bytes;
|
||
|
ASN1OctetString dEROctetString;
|
||
|
byte b;
|
||
|
if (subjectPublicKeyInfo.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001)) {
|
||
|
DERBitString publicKeyData = subjectPublicKeyInfo.getPublicKeyData();
|
||
|
this.algorithm = "ECGOST3410";
|
||
|
try {
|
||
|
byte[] octets = ((ASN1OctetString) ASN1Primitive.fromByteArray(publicKeyData.getBytes())).getOctets();
|
||
|
byte[] bArr = new byte[32];
|
||
|
byte[] bArr2 = new byte[32];
|
||
|
for (int i = 0; i != 32; i++) {
|
||
|
bArr[i] = octets[31 - i];
|
||
|
}
|
||
|
for (int i2 = 0; i2 != 32; i2++) {
|
||
|
bArr2[i2] = octets[63 - i2];
|
||
|
}
|
||
|
GOST3410PublicKeyAlgParameters gOST3410PublicKeyAlgParameters = new GOST3410PublicKeyAlgParameters((ASN1Sequence) subjectPublicKeyInfo.getAlgorithmId().getParameters());
|
||
|
this.gostParams = gOST3410PublicKeyAlgParameters;
|
||
|
ECNamedCurveParameterSpec parameterSpec = ECGOST3410NamedCurveTable.getParameterSpec(ECGOST3410NamedCurves.getName(gOST3410PublicKeyAlgParameters.getPublicKeyParamSet()));
|
||
|
ECCurve curve3 = parameterSpec.getCurve();
|
||
|
EllipticCurve convertCurve = EC5Util.convertCurve(curve3, parameterSpec.getSeed());
|
||
|
this.q = curve3.createPoint(new BigInteger(1, bArr), new BigInteger(1, bArr2), false);
|
||
|
this.ecSpec = new ECNamedCurveSpec(ECGOST3410NamedCurves.getName(this.gostParams.getPublicKeyParamSet()), convertCurve, new java.security.spec.ECPoint(parameterSpec.getG().getAffineXCoord().toBigInteger(), parameterSpec.getG().getAffineYCoord().toBigInteger()), parameterSpec.getN(), parameterSpec.getH());
|
||
|
return;
|
||
|
} catch (IOException unused) {
|
||
|
throw new IllegalArgumentException("error recovering public key");
|
||
|
}
|
||
|
}
|
||
|
X962Parameters x962Parameters = new X962Parameters((ASN1Primitive) subjectPublicKeyInfo.getAlgorithmId().getParameters());
|
||
|
if (x962Parameters.isNamedCurve()) {
|
||
|
ASN1ObjectIdentifier aSN1ObjectIdentifier = (ASN1ObjectIdentifier) x962Parameters.getParameters();
|
||
|
X9ECParameters namedCurveByOid = ECUtil.getNamedCurveByOid(aSN1ObjectIdentifier);
|
||
|
curve = namedCurveByOid.getCurve();
|
||
|
eCParameterSpec = new ECNamedCurveSpec(ECUtil.getCurveName(aSN1ObjectIdentifier), EC5Util.convertCurve(curve, namedCurveByOid.getSeed()), new java.security.spec.ECPoint(namedCurveByOid.getG().getAffineXCoord().toBigInteger(), namedCurveByOid.getG().getAffineYCoord().toBigInteger()), namedCurveByOid.getN(), namedCurveByOid.getH());
|
||
|
} else {
|
||
|
if (x962Parameters.isImplicitlyCA()) {
|
||
|
this.ecSpec = null;
|
||
|
curve2 = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve();
|
||
|
bytes = subjectPublicKeyInfo.getPublicKeyData().getBytes();
|
||
|
dEROctetString = new DEROctetString(bytes);
|
||
|
if (bytes[0] == 4 && bytes[1] == bytes.length - 2 && (((b = bytes[2]) == 2 || b == 3) && new X9IntegerConverter().getByteLength(curve2) >= bytes.length - 3)) {
|
||
|
try {
|
||
|
dEROctetString = (ASN1OctetString) ASN1Primitive.fromByteArray(bytes);
|
||
|
} catch (IOException unused2) {
|
||
|
throw new IllegalArgumentException("error recovering public key");
|
||
|
}
|
||
|
}
|
||
|
this.q = new X9ECPoint(curve2, dEROctetString).getPoint();
|
||
|
}
|
||
|
X9ECParameters x9ECParameters = X9ECParameters.getInstance(x962Parameters.getParameters());
|
||
|
curve = x9ECParameters.getCurve();
|
||
|
eCParameterSpec = new ECParameterSpec(EC5Util.convertCurve(curve, x9ECParameters.getSeed()), new java.security.spec.ECPoint(x9ECParameters.getG().getAffineXCoord().toBigInteger(), x9ECParameters.getG().getAffineYCoord().toBigInteger()), x9ECParameters.getN(), x9ECParameters.getH().intValue());
|
||
|
}
|
||
|
this.ecSpec = eCParameterSpec;
|
||
|
curve2 = curve;
|
||
|
bytes = subjectPublicKeyInfo.getPublicKeyData().getBytes();
|
||
|
dEROctetString = new DEROctetString(bytes);
|
||
|
if (bytes[0] == 4) {
|
||
|
dEROctetString = (ASN1OctetString) ASN1Primitive.fromByteArray(bytes);
|
||
|
}
|
||
|
this.q = new X9ECPoint(curve2, dEROctetString).getPoint();
|
||
|
}
|
||
|
|
||
|
private void extractBytes(byte[] bArr, int i, BigInteger bigInteger) {
|
||
|
byte[] byteArray = bigInteger.toByteArray();
|
||
|
if (byteArray.length < 32) {
|
||
|
byte[] bArr2 = new byte[32];
|
||
|
System.arraycopy(byteArray, 0, bArr2, 32 - byteArray.length, byteArray.length);
|
||
|
byteArray = bArr2;
|
||
|
}
|
||
|
for (int i2 = 0; i2 != 32; i2++) {
|
||
|
bArr[i + i2] = byteArray[(byteArray.length - 1) - i2];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters eCDomainParameters) {
|
||
|
return new ECParameterSpec(ellipticCurve, new java.security.spec.ECPoint(eCDomainParameters.getG().getAffineXCoord().toBigInteger(), eCDomainParameters.getG().getAffineYCoord().toBigInteger()), eCDomainParameters.getN(), eCDomainParameters.getH().intValue());
|
||
|
}
|
||
|
|
||
|
JCEECPublicKey(SubjectPublicKeyInfo subjectPublicKeyInfo) {
|
||
|
this.algorithm = "EC";
|
||
|
populateFromPubKeyInfo(subjectPublicKeyInfo);
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(ECPublicKey eCPublicKey) {
|
||
|
this.algorithm = "EC";
|
||
|
this.algorithm = eCPublicKey.getAlgorithm();
|
||
|
ECParameterSpec params = eCPublicKey.getParams();
|
||
|
this.ecSpec = params;
|
||
|
this.q = EC5Util.convertPoint(params, eCPublicKey.getW(), false);
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, ECPublicKeySpec eCPublicKeySpec) {
|
||
|
ECParameterSpec eCParameterSpec;
|
||
|
this.algorithm = str;
|
||
|
this.q = eCPublicKeySpec.getQ();
|
||
|
if (eCPublicKeySpec.getParams() != null) {
|
||
|
eCParameterSpec = EC5Util.convertSpec(EC5Util.convertCurve(eCPublicKeySpec.getParams().getCurve(), eCPublicKeySpec.getParams().getSeed()), eCPublicKeySpec.getParams());
|
||
|
} else {
|
||
|
if (this.q.getCurve() == null) {
|
||
|
this.q = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa().getCurve().createPoint(this.q.getAffineXCoord().toBigInteger(), this.q.getAffineYCoord().toBigInteger(), false);
|
||
|
}
|
||
|
eCParameterSpec = null;
|
||
|
}
|
||
|
this.ecSpec = eCParameterSpec;
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, JCEECPublicKey jCEECPublicKey) {
|
||
|
this.algorithm = str;
|
||
|
this.q = jCEECPublicKey.q;
|
||
|
this.ecSpec = jCEECPublicKey.ecSpec;
|
||
|
this.withCompression = jCEECPublicKey.withCompression;
|
||
|
this.gostParams = jCEECPublicKey.gostParams;
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, ECPublicKeyParameters eCPublicKeyParameters, org.bouncycastle.jce.spec.ECParameterSpec eCParameterSpec) {
|
||
|
this.algorithm = "EC";
|
||
|
ECDomainParameters parameters = eCPublicKeyParameters.getParameters();
|
||
|
this.algorithm = str;
|
||
|
this.q = eCPublicKeyParameters.getQ();
|
||
|
this.ecSpec = eCParameterSpec == null ? createSpec(EC5Util.convertCurve(parameters.getCurve(), parameters.getSeed()), parameters) : EC5Util.convertSpec(EC5Util.convertCurve(eCParameterSpec.getCurve(), eCParameterSpec.getSeed()), eCParameterSpec);
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, ECPublicKeyParameters eCPublicKeyParameters, ECParameterSpec eCParameterSpec) {
|
||
|
this.algorithm = "EC";
|
||
|
ECDomainParameters parameters = eCPublicKeyParameters.getParameters();
|
||
|
this.algorithm = str;
|
||
|
this.q = eCPublicKeyParameters.getQ();
|
||
|
if (eCParameterSpec == null) {
|
||
|
this.ecSpec = createSpec(EC5Util.convertCurve(parameters.getCurve(), parameters.getSeed()), parameters);
|
||
|
} else {
|
||
|
this.ecSpec = eCParameterSpec;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, ECPublicKeyParameters eCPublicKeyParameters) {
|
||
|
this.algorithm = str;
|
||
|
this.q = eCPublicKeyParameters.getQ();
|
||
|
this.ecSpec = null;
|
||
|
}
|
||
|
|
||
|
public JCEECPublicKey(String str, java.security.spec.ECPublicKeySpec eCPublicKeySpec) {
|
||
|
this.algorithm = str;
|
||
|
ECParameterSpec params = eCPublicKeySpec.getParams();
|
||
|
this.ecSpec = params;
|
||
|
this.q = EC5Util.convertPoint(params, eCPublicKeySpec.getW(), false);
|
||
|
}
|
||
|
}
|