1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 package com.android.org.bouncycastle.jce.provider; 3 4 import java.io.IOException; 5 import java.io.ObjectInputStream; 6 import java.io.ObjectOutputStream; 7 import java.math.BigInteger; 8 import java.security.interfaces.ECPrivateKey; 9 import java.security.spec.ECParameterSpec; 10 import java.security.spec.ECPoint; 11 import java.security.spec.ECPrivateKeySpec; 12 import java.security.spec.EllipticCurve; 13 import java.util.Enumeration; 14 15 import com.android.org.bouncycastle.asn1.ASN1Encodable; 16 import com.android.org.bouncycastle.asn1.ASN1Encoding; 17 import com.android.org.bouncycastle.asn1.ASN1Integer; 18 import com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier; 19 import com.android.org.bouncycastle.asn1.ASN1Primitive; 20 import com.android.org.bouncycastle.asn1.ASN1Sequence; 21 import com.android.org.bouncycastle.asn1.DERBitString; 22 import com.android.org.bouncycastle.asn1.DERNull; 23 // Android-removed: Unsupported algorithms 24 // import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; 25 // import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; 26 import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 27 import com.android.org.bouncycastle.asn1.sec.ECPrivateKeyStructure; 28 import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier; 29 import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 30 import com.android.org.bouncycastle.asn1.x9.X962Parameters; 31 import com.android.org.bouncycastle.asn1.x9.X9ECParameters; 32 import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 33 import com.android.org.bouncycastle.crypto.params.ECDomainParameters; 34 import com.android.org.bouncycastle.crypto.params.ECPrivateKeyParameters; 35 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; 36 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil; 37 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl; 38 import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder; 39 import com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier; 40 import com.android.org.bouncycastle.jce.spec.ECNamedCurveSpec; 41 import com.android.org.bouncycastle.math.ec.ECCurve; 42 import com.android.org.bouncycastle.util.Strings; 43 44 /** 45 * @hide This class is not part of the Android public SDK API 46 */ 47 public class JCEECPrivateKey 48 implements ECPrivateKey, com.android.org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder 49 { 50 private String algorithm = "EC"; 51 private BigInteger d; 52 private ECParameterSpec ecSpec; 53 private boolean withCompression; 54 55 private DERBitString publicKey; 56 57 private PKCS12BagAttributeCarrierImpl attrCarrier = new PKCS12BagAttributeCarrierImpl(); 58 59 protected JCEECPrivateKey() 60 { 61 } 62 63 public JCEECPrivateKey( 64 ECPrivateKey key) 65 { 66 this.d = key.getS(); 67 this.algorithm = key.getAlgorithm(); 68 this.ecSpec = key.getParams(); 69 } 70 71 public JCEECPrivateKey( 72 String algorithm, 73 com.android.org.bouncycastle.jce.spec.ECPrivateKeySpec spec) 74 { 75 this.algorithm = algorithm; 76 this.d = spec.getD(); 77 78 if (spec.getParams() != null) // can be null if implicitlyCA 79 { 80 ECCurve curve = spec.getParams().getCurve(); 81 EllipticCurve ellipticCurve; 82 83 ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed()); 84 85 this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams()); 86 } 87 else 88 { 89 this.ecSpec = null; 90 } 91 } 92 93 94 public JCEECPrivateKey( 95 String algorithm, 96 ECPrivateKeySpec spec) 97 { 98 this.algorithm = algorithm; 99 this.d = spec.getS(); 100 this.ecSpec = spec.getParams(); 101 } 102 103 public JCEECPrivateKey( 104 String algorithm, 105 JCEECPrivateKey key) 106 { 107 this.algorithm = algorithm; 108 this.d = key.d; 109 this.ecSpec = key.ecSpec; 110 this.withCompression = key.withCompression; 111 this.attrCarrier = key.attrCarrier; 112 this.publicKey = key.publicKey; 113 } 114 115 public JCEECPrivateKey( 116 String algorithm, 117 ECPrivateKeyParameters params, 118 JCEECPublicKey pubKey, 119 ECParameterSpec spec) 120 { 121 this.algorithm = algorithm; 122 this.d = params.getD(); 123 124 if (spec == null) 125 { 126 ECDomainParameters dp = params.getParameters(); 127 EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); 128 129 this.ecSpec = new ECParameterSpec( 130 ellipticCurve, 131 EC5Util.convertPoint(dp.getG()), 132 dp.getN(), 133 dp.getH().intValue()); 134 } 135 else 136 { 137 this.ecSpec = spec; 138 } 139 140 publicKey = getPublicKeyDetails(pubKey); 141 } 142 143 public JCEECPrivateKey( 144 String algorithm, 145 ECPrivateKeyParameters params, 146 JCEECPublicKey pubKey, 147 com.android.org.bouncycastle.jce.spec.ECParameterSpec spec) 148 { 149 this.algorithm = algorithm; 150 this.d = params.getD(); 151 152 if (spec == null) 153 { 154 ECDomainParameters dp = params.getParameters(); 155 EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed()); 156 157 this.ecSpec = new ECParameterSpec( 158 ellipticCurve, 159 EC5Util.convertPoint(dp.getG()), 160 dp.getN(), 161 dp.getH().intValue()); 162 } 163 else 164 { 165 EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed()); 166 167 this.ecSpec = new ECParameterSpec( 168 ellipticCurve, 169 EC5Util.convertPoint(spec.getG()), 170 spec.getN(), 171 spec.getH().intValue()); 172 } 173 174 publicKey = getPublicKeyDetails(pubKey); 175 } 176 177 public JCEECPrivateKey( 178 String algorithm, 179 ECPrivateKeyParameters params) 180 { 181 this.algorithm = algorithm; 182 this.d = params.getD(); 183 this.ecSpec = null; 184 } 185 186 JCEECPrivateKey( 187 PrivateKeyInfo info) 188 throws IOException 189 { 190 populateFromPrivKeyInfo(info); 191 } 192 193 private void populateFromPrivKeyInfo(PrivateKeyInfo info) 194 throws IOException 195 { 196 X962Parameters params = new X962Parameters((ASN1Primitive)info.getPrivateKeyAlgorithm().getParameters()); 197 198 if (params.isNamedCurve()) 199 { 200 ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters()); 201 X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid); 202 203 // BEGIN Android-removed: Unsupported algorithms 204 /* 205 if (ecP == null) // GOST Curve 206 { 207 ECDomainParameters gParam = ECGOST3410NamedCurves.getByOID(oid); 208 EllipticCurve ellipticCurve = EC5Util.convertCurve(gParam.getCurve(), gParam.getSeed()); 209 210 ecSpec = new ECNamedCurveSpec( 211 ECGOST3410NamedCurves.getName(oid), 212 ellipticCurve, 213 EC5Util.convertPoint(gParam.getG()), 214 gParam.getN(), 215 gParam.getH()); 216 } 217 else 218 */ 219 // END Android-removed: Unsupported algorithms 220 { 221 EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); 222 223 ecSpec = new ECNamedCurveSpec( 224 ECUtil.getCurveName(oid), 225 ellipticCurve, 226 EC5Util.convertPoint(ecP.getG()), 227 ecP.getN(), 228 ecP.getH()); 229 } 230 } 231 else if (params.isImplicitlyCA()) 232 { 233 ecSpec = null; 234 } 235 else 236 { 237 X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); 238 EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed()); 239 240 this.ecSpec = new ECParameterSpec( 241 ellipticCurve, 242 EC5Util.convertPoint(ecP.getG()), 243 ecP.getN(), 244 ecP.getH().intValue()); 245 } 246 247 ASN1Encodable privKey = info.parsePrivateKey(); 248 if (privKey instanceof ASN1Integer) 249 { 250 ASN1Integer derD = ASN1Integer.getInstance(privKey); 251 252 this.d = derD.getValue(); 253 } 254 else 255 { 256 ECPrivateKeyStructure ec = new ECPrivateKeyStructure((ASN1Sequence)privKey); 257 258 this.d = ec.getKey(); 259 this.publicKey = ec.getPublicKey(); 260 } 261 } 262 263 public String getAlgorithm() 264 { 265 return algorithm; 266 } 267 268 /** 269 * return the encoding format we produce in getEncoded(). 270 * 271 * @return the string "PKCS#8" 272 */ 273 public String getFormat() 274 { 275 return "PKCS#8"; 276 } 277 278 /** 279 * Return a PKCS8 representation of the key. The sequence returned 280 * represents a full PrivateKeyInfo object. 281 * 282 * @return a PKCS8 representation of the key. 283 */ 284 public byte[] getEncoded() 285 { 286 X962Parameters params; 287 288 if (ecSpec instanceof ECNamedCurveSpec) 289 { 290 ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName()); 291 if (curveOid == null) // guess it's the OID 292 { 293 curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName()); 294 } 295 params = new X962Parameters(curveOid); 296 } 297 else if (ecSpec == null) 298 { 299 params = new X962Parameters(DERNull.INSTANCE); 300 } 301 else 302 { 303 ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); 304 305 X9ECParameters ecP = new X9ECParameters( 306 curve, 307 EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), 308 ecSpec.getOrder(), 309 BigInteger.valueOf(ecSpec.getCofactor()), 310 ecSpec.getCurve().getSeed()); 311 312 params = new X962Parameters(ecP); 313 } 314 315 PrivateKeyInfo info; 316 ECPrivateKeyStructure keyStructure; 317 318 if (publicKey != null) 319 { 320 keyStructure = new ECPrivateKeyStructure(this.getS(), publicKey, params); 321 } 322 else 323 { 324 keyStructure = new ECPrivateKeyStructure(this.getS(), params); 325 } 326 327 try 328 { 329 // BEGIN Android-removed: Unsupported algorithms 330 // if (algorithm.equals("ECGOST3410")) 331 // { 332 // info = new PrivateKeyInfo(new AlgorithmIdentifier(CryptoProObjectIdentifiers.gostR3410_2001, params.toASN1Primitive()), keyStructure.toASN1Primitive()); 333 // } 334 // else 335 // END Android-removed: Unsupported algorithms 336 { 337 338 info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params.toASN1Primitive()), keyStructure.toASN1Primitive()); 339 } 340 341 return info.getEncoded(ASN1Encoding.DER); 342 } 343 catch (IOException e) 344 { 345 return null; 346 } 347 } 348 349 public ECParameterSpec getParams() 350 { 351 return ecSpec; 352 } 353 354 public com.android.org.bouncycastle.jce.spec.ECParameterSpec getParameters() 355 { 356 if (ecSpec == null) 357 { 358 return null; 359 } 360 361 return EC5Util.convertSpec(ecSpec, withCompression); 362 } 363 364 com.android.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec() 365 { 366 if (ecSpec != null) 367 { 368 return EC5Util.convertSpec(ecSpec, withCompression); 369 } 370 371 return BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 372 } 373 374 public BigInteger getS() 375 { 376 return d; 377 } 378 379 public BigInteger getD() 380 { 381 return d; 382 } 383 384 public void setBagAttribute( 385 ASN1ObjectIdentifier oid, 386 ASN1Encodable attribute) 387 { 388 attrCarrier.setBagAttribute(oid, attribute); 389 } 390 391 public ASN1Encodable getBagAttribute( 392 ASN1ObjectIdentifier oid) 393 { 394 return attrCarrier.getBagAttribute(oid); 395 } 396 397 public Enumeration getBagAttributeKeys() 398 { 399 return attrCarrier.getBagAttributeKeys(); 400 } 401 402 public void setPointFormat(String style) 403 { 404 withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style)); 405 } 406 407 public boolean equals(Object o) 408 { 409 if (!(o instanceof JCEECPrivateKey)) 410 { 411 return false; 412 } 413 414 JCEECPrivateKey other = (JCEECPrivateKey)o; 415 416 return getD().equals(other.getD()) && (engineGetSpec().equals(other.engineGetSpec())); 417 } 418 419 public int hashCode() 420 { 421 return getD().hashCode() ^ engineGetSpec().hashCode(); 422 } 423 424 public String toString() 425 { 426 StringBuffer buf = new StringBuffer(); 427 String nl = Strings.lineSeparator(); 428 429 buf.append("EC Private Key").append(nl); 430 buf.append(" S: ").append(this.d.toString(16)).append(nl); 431 432 return buf.toString(); 433 434 } 435 436 private DERBitString getPublicKeyDetails(JCEECPublicKey pub) 437 { 438 try 439 { 440 SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); 441 442 return info.getPublicKeyData(); 443 } 444 catch (IOException e) 445 { // should never happen 446 return null; 447 } 448 } 449 450 private void readObject( 451 ObjectInputStream in) 452 throws IOException, ClassNotFoundException 453 { 454 byte[] enc = (byte[])in.readObject(); 455 456 populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc))); 457 458 this.algorithm = (String)in.readObject(); 459 this.withCompression = in.readBoolean(); 460 this.attrCarrier = new PKCS12BagAttributeCarrierImpl(); 461 462 attrCarrier.readObject(in); 463 } 464 465 private void writeObject( 466 ObjectOutputStream out) 467 throws IOException 468 { 469 out.writeObject(this.getEncoded()); 470 out.writeObject(algorithm); 471 out.writeBoolean(withCompression); 472 473 attrCarrier.writeObject(out); 474 } 475 } 476