Home | History | Annotate | Download | only in ec
      1 /* GENERATED SOURCE. DO NOT MODIFY. */
      2 package com.android.org.bouncycastle.jcajce.provider.asymmetric.ec;
      3 
      4 import java.io.IOException;
      5 import java.io.ObjectInputStream;
      6 import java.io.ObjectOutputStream;
      7 import java.security.interfaces.ECPublicKey;
      8 import java.security.spec.ECParameterSpec;
      9 import java.security.spec.ECPoint;
     10 import java.security.spec.ECPublicKeySpec;
     11 import java.security.spec.EllipticCurve;
     12 
     13 import com.android.org.bouncycastle.asn1.ASN1Encodable;
     14 import com.android.org.bouncycastle.asn1.ASN1OctetString;
     15 import com.android.org.bouncycastle.asn1.ASN1Primitive;
     16 import com.android.org.bouncycastle.asn1.DERBitString;
     17 import com.android.org.bouncycastle.asn1.DEROctetString;
     18 import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     19 import com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
     20 import com.android.org.bouncycastle.asn1.x9.X962Parameters;
     21 import com.android.org.bouncycastle.asn1.x9.X9ECPoint;
     22 import com.android.org.bouncycastle.asn1.x9.X9IntegerConverter;
     23 import com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
     24 import com.android.org.bouncycastle.crypto.params.ECDomainParameters;
     25 import com.android.org.bouncycastle.crypto.params.ECPublicKeyParameters;
     26 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
     27 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
     28 import com.android.org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
     29 import com.android.org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
     30 import com.android.org.bouncycastle.jce.interfaces.ECPointEncoder;
     31 import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
     32 import com.android.org.bouncycastle.math.ec.ECCurve;
     33 
     34 /**
     35  * @hide This class is not part of the Android public SDK API
     36  */
     37 public class BCECPublicKey
     38     implements ECPublicKey, com.android.org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
     39 {
     40     static final long serialVersionUID = 2422789860422731812L;
     41 
     42     private String    algorithm = "EC";
     43     private boolean   withCompression;
     44 
     45     private transient ECPublicKeyParameters   ecPublicKey;
     46     private transient ECParameterSpec         ecSpec;
     47     private transient ProviderConfiguration   configuration;
     48 
     49     public BCECPublicKey(
     50         String algorithm,
     51         BCECPublicKey key)
     52     {
     53         this.algorithm = algorithm;
     54         this.ecPublicKey = key.ecPublicKey;
     55         this.ecSpec = key.ecSpec;
     56         this.withCompression = key.withCompression;
     57         this.configuration = key.configuration;
     58     }
     59 
     60     public BCECPublicKey(
     61         String algorithm,
     62         ECPublicKeySpec spec,
     63         ProviderConfiguration configuration)
     64     {
     65         this.algorithm = algorithm;
     66         this.ecSpec = spec.getParams();
     67         this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW(), false), EC5Util.getDomainParameters(configuration, spec.getParams()));
     68         this.configuration = configuration;
     69     }
     70 
     71     public BCECPublicKey(
     72         String algorithm,
     73         com.android.org.bouncycastle.jce.spec.ECPublicKeySpec spec,
     74         ProviderConfiguration configuration)
     75     {
     76         this.algorithm = algorithm;
     77 
     78         if (spec.getParams() != null) // can be null if implictlyCa
     79         {
     80             ECCurve curve = spec.getParams().getCurve();
     81             EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
     82 
     83             // this may seem a little long-winded but it's how we pick up the custom curve.
     84             this.ecPublicKey = new ECPublicKeyParameters(
     85                 spec.getQ(), ECUtil.getDomainParameters(configuration, spec.getParams()));
     86             this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
     87         }
     88         else
     89         {
     90             com.android.org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa();
     91 
     92             this.ecPublicKey = new ECPublicKeyParameters(s.getCurve().createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger()), EC5Util.getDomainParameters(configuration, (ECParameterSpec)null));
     93             this.ecSpec = null;
     94         }
     95 
     96         this.configuration = configuration;
     97     }
     98 
     99     public BCECPublicKey(
    100         String algorithm,
    101         ECPublicKeyParameters params,
    102         ECParameterSpec spec,
    103         ProviderConfiguration configuration)
    104     {
    105         ECDomainParameters      dp = params.getParameters();
    106 
    107         this.algorithm = algorithm;
    108         this.ecPublicKey = params;
    109 
    110         if (spec == null)
    111         {
    112             EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
    113 
    114             this.ecSpec = createSpec(ellipticCurve, dp);
    115         }
    116         else
    117         {
    118             this.ecSpec = spec;
    119         }
    120 
    121         this.configuration = configuration;
    122     }
    123 
    124     public BCECPublicKey(
    125         String algorithm,
    126         ECPublicKeyParameters params,
    127         com.android.org.bouncycastle.jce.spec.ECParameterSpec spec,
    128         ProviderConfiguration configuration)
    129     {
    130         ECDomainParameters      dp = params.getParameters();
    131 
    132         this.algorithm = algorithm;
    133 
    134         if (spec == null)
    135         {
    136             EllipticCurve ellipticCurve = EC5Util.convertCurve(dp.getCurve(), dp.getSeed());
    137 
    138             this.ecSpec = createSpec(ellipticCurve, dp);
    139         }
    140         else
    141         {
    142             EllipticCurve ellipticCurve = EC5Util.convertCurve(spec.getCurve(), spec.getSeed());
    143 
    144             this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
    145         }
    146 
    147         this.ecPublicKey = params;
    148         this.configuration = configuration;
    149     }
    150 
    151     /*
    152      * called for implicitCA
    153      */
    154     public BCECPublicKey(
    155         String algorithm,
    156         ECPublicKeyParameters params,
    157         ProviderConfiguration configuration)
    158     {
    159         this.algorithm = algorithm;
    160         this.ecPublicKey = params;
    161         this.ecSpec = null;
    162         this.configuration = configuration;
    163     }
    164 
    165     public BCECPublicKey(
    166         ECPublicKey key,
    167         ProviderConfiguration configuration)
    168     {
    169         this.algorithm = key.getAlgorithm();
    170         this.ecSpec = key.getParams();
    171         this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW(), false), EC5Util.getDomainParameters(configuration, key.getParams()));
    172     }
    173 
    174     BCECPublicKey(
    175         String algorithm,
    176         SubjectPublicKeyInfo info,
    177         ProviderConfiguration configuration)
    178     {
    179         this.algorithm = algorithm;
    180         this.configuration = configuration;
    181         populateFromPubKeyInfo(info);
    182     }
    183 
    184     private ECParameterSpec createSpec(EllipticCurve ellipticCurve, ECDomainParameters dp)
    185     {
    186         return new ECParameterSpec(
    187             ellipticCurve,
    188             EC5Util.convertPoint(dp.getG()),
    189             dp.getN(),
    190             dp.getH().intValue());
    191     }
    192 
    193     private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
    194     {
    195         X962Parameters params = X962Parameters.getInstance(info.getAlgorithm().getParameters());
    196         ECCurve curve = EC5Util.getCurve(configuration, params);
    197         ecSpec = EC5Util.convertToSpec(params, curve);
    198 
    199         DERBitString    bits = info.getPublicKeyData();
    200         byte[]          data = bits.getBytes();
    201         ASN1OctetString key = new DEROctetString(data);
    202 
    203         //
    204         // extra octet string - one of our old certs...
    205         //
    206         if (data[0] == 0x04 && data[1] == data.length - 2
    207             && (data[2] == 0x02 || data[2] == 0x03))
    208         {
    209             int qLength = new X9IntegerConverter().getByteLength(curve);
    210 
    211             if (qLength >= data.length - 3)
    212             {
    213                 try
    214                 {
    215                     key = (ASN1OctetString) ASN1Primitive.fromByteArray(data);
    216                 }
    217                 catch (IOException ex)
    218                 {
    219                     throw new IllegalArgumentException("error recovering public key");
    220                 }
    221             }
    222         }
    223 
    224         X9ECPoint derQ = new X9ECPoint(curve, key);
    225 
    226         this.ecPublicKey = new ECPublicKeyParameters(derQ.getPoint(), ECUtil.getDomainParameters(configuration, params));
    227     }
    228 
    229     public String getAlgorithm()
    230     {
    231         return algorithm;
    232     }
    233 
    234     public String getFormat()
    235     {
    236         return "X.509";
    237     }
    238 
    239     public byte[] getEncoded()
    240     {
    241         ASN1Encodable   params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
    242         ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(ecPublicKey.getQ(), withCompression).toASN1Primitive());
    243 
    244         // stored curve is null if ImplicitlyCa
    245         SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
    246 
    247         return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
    248     }
    249 
    250     public ECParameterSpec getParams()
    251     {
    252         return ecSpec;
    253     }
    254 
    255     public com.android.org.bouncycastle.jce.spec.ECParameterSpec getParameters()
    256     {
    257         if (ecSpec == null)     // implictlyCA
    258         {
    259             return null;
    260         }
    261 
    262         return EC5Util.convertSpec(ecSpec, withCompression);
    263     }
    264 
    265     public ECPoint getW()
    266     {
    267         return EC5Util.convertPoint(ecPublicKey.getQ());
    268     }
    269 
    270     public com.android.org.bouncycastle.math.ec.ECPoint getQ()
    271     {
    272         com.android.org.bouncycastle.math.ec.ECPoint q = ecPublicKey.getQ();
    273 
    274         if (ecSpec == null)
    275         {
    276             return q.getDetachedPoint();
    277         }
    278 
    279         return q;
    280     }
    281 
    282     ECPublicKeyParameters engineGetKeyParameters()
    283     {
    284         return ecPublicKey;
    285     }
    286 
    287     com.android.org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
    288     {
    289         if (ecSpec != null)
    290         {
    291             return EC5Util.convertSpec(ecSpec, withCompression);
    292         }
    293 
    294         return configuration.getEcImplicitlyCa();
    295     }
    296 
    297     public String toString()
    298     {
    299         return ECUtil.publicKeyToString("EC", ecPublicKey.getQ(), engineGetSpec());
    300     }
    301 
    302     public void setPointFormat(String style)
    303     {
    304        withCompression = !("UNCOMPRESSED".equalsIgnoreCase(style));
    305     }
    306 
    307     public boolean equals(Object o)
    308     {
    309         if (!(o instanceof BCECPublicKey))
    310         {
    311             return false;
    312         }
    313 
    314         BCECPublicKey other = (BCECPublicKey)o;
    315 
    316         return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
    317     }
    318 
    319     public int hashCode()
    320     {
    321         return ecPublicKey.getQ().hashCode() ^ engineGetSpec().hashCode();
    322     }
    323 
    324     private void readObject(
    325         ObjectInputStream in)
    326         throws IOException, ClassNotFoundException
    327     {
    328         in.defaultReadObject();
    329 
    330         byte[] enc = (byte[])in.readObject();
    331 
    332         this.configuration = BouncyCastleProvider.CONFIGURATION;
    333 
    334         populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
    335     }
    336 
    337     private void writeObject(
    338         ObjectOutputStream out)
    339         throws IOException
    340     {
    341         out.defaultWriteObject();
    342 
    343         out.writeObject(this.getEncoded());
    344     }
    345 }
    346