Home | History | Annotate | Download | only in provider
      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