/extern/spongycastle/prov/src/main/java/org/spongycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java

https://gitlab.com/vizilo/fdroidclient · Java · 204 lines · 167 code · 36 blank · 1 comment · 17 complexity · 11de3141f074c7bf1a4721265db56f6e MD5 · raw file

  1. package org.spongycastle.jcajce.provider.asymmetric.dh;
  2. import java.io.IOException;
  3. import java.io.ObjectInputStream;
  4. import java.io.ObjectOutputStream;
  5. import java.math.BigInteger;
  6. import javax.crypto.interfaces.DHPublicKey;
  7. import javax.crypto.spec.DHParameterSpec;
  8. import javax.crypto.spec.DHPublicKeySpec;
  9. import org.spongycastle.asn1.ASN1Integer;
  10. import org.spongycastle.asn1.ASN1ObjectIdentifier;
  11. import org.spongycastle.asn1.ASN1Sequence;
  12. import org.spongycastle.asn1.pkcs.DHParameter;
  13. import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
  14. import org.spongycastle.asn1.x509.AlgorithmIdentifier;
  15. import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
  16. import org.spongycastle.asn1.x9.DHDomainParameters;
  17. import org.spongycastle.asn1.x9.X9ObjectIdentifiers;
  18. import org.spongycastle.crypto.params.DHPublicKeyParameters;
  19. import org.spongycastle.jcajce.provider.asymmetric.util.KeyUtil;
  20. public class BCDHPublicKey
  21. implements DHPublicKey
  22. {
  23. static final long serialVersionUID = -216691575254424324L;
  24. private BigInteger y;
  25. private transient DHParameterSpec dhSpec;
  26. private transient SubjectPublicKeyInfo info;
  27. BCDHPublicKey(
  28. DHPublicKeySpec spec)
  29. {
  30. this.y = spec.getY();
  31. this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
  32. }
  33. BCDHPublicKey(
  34. DHPublicKey key)
  35. {
  36. this.y = key.getY();
  37. this.dhSpec = key.getParams();
  38. }
  39. BCDHPublicKey(
  40. DHPublicKeyParameters params)
  41. {
  42. this.y = params.getY();
  43. this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL());
  44. }
  45. BCDHPublicKey(
  46. BigInteger y,
  47. DHParameterSpec dhSpec)
  48. {
  49. this.y = y;
  50. this.dhSpec = dhSpec;
  51. }
  52. public BCDHPublicKey(
  53. SubjectPublicKeyInfo info)
  54. {
  55. this.info = info;
  56. ASN1Integer derY;
  57. try
  58. {
  59. derY = (ASN1Integer)info.parsePublicKey();
  60. }
  61. catch (IOException e)
  62. {
  63. throw new IllegalArgumentException("invalid info structure in DH public key");
  64. }
  65. this.y = derY.getValue();
  66. ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters());
  67. ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm();
  68. // we need the PKCS check to handle older keys marked with the X9 oid.
  69. if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq))
  70. {
  71. DHParameter params = DHParameter.getInstance(seq);
  72. if (params.getL() != null)
  73. {
  74. this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue());
  75. }
  76. else
  77. {
  78. this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
  79. }
  80. }
  81. else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
  82. {
  83. DHDomainParameters params = DHDomainParameters.getInstance(seq);
  84. this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
  85. }
  86. else
  87. {
  88. throw new IllegalArgumentException("unknown algorithm type: " + id);
  89. }
  90. }
  91. public String getAlgorithm()
  92. {
  93. return "DH";
  94. }
  95. public String getFormat()
  96. {
  97. return "X.509";
  98. }
  99. public byte[] getEncoded()
  100. {
  101. if (info != null)
  102. {
  103. return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
  104. }
  105. return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(y));
  106. }
  107. public DHParameterSpec getParams()
  108. {
  109. return dhSpec;
  110. }
  111. public BigInteger getY()
  112. {
  113. return y;
  114. }
  115. private boolean isPKCSParam(ASN1Sequence seq)
  116. {
  117. if (seq.size() == 2)
  118. {
  119. return true;
  120. }
  121. if (seq.size() > 3)
  122. {
  123. return false;
  124. }
  125. ASN1Integer l = ASN1Integer.getInstance(seq.getObjectAt(2));
  126. ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(0));
  127. if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0)
  128. {
  129. return false;
  130. }
  131. return true;
  132. }
  133. public int hashCode()
  134. {
  135. return this.getY().hashCode() ^ this.getParams().getG().hashCode()
  136. ^ this.getParams().getP().hashCode() ^ this.getParams().getL();
  137. }
  138. public boolean equals(
  139. Object o)
  140. {
  141. if (!(o instanceof DHPublicKey))
  142. {
  143. return false;
  144. }
  145. DHPublicKey other = (DHPublicKey)o;
  146. return this.getY().equals(other.getY())
  147. && this.getParams().getG().equals(other.getParams().getG())
  148. && this.getParams().getP().equals(other.getParams().getP())
  149. && this.getParams().getL() == other.getParams().getL();
  150. }
  151. private void readObject(
  152. ObjectInputStream in)
  153. throws IOException, ClassNotFoundException
  154. {
  155. in.defaultReadObject();
  156. this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt());
  157. this.info = null;
  158. }
  159. private void writeObject(
  160. ObjectOutputStream out)
  161. throws IOException
  162. {
  163. out.defaultWriteObject();
  164. out.writeObject(dhSpec.getP());
  165. out.writeObject(dhSpec.getG());
  166. out.writeInt(dhSpec.getL());
  167. }
  168. }