ECUtil.java revision a198e1ecc615e26a167d0f2dca9fa7e5fc62de10
1package org.bouncycastle.jcajce.provider.asymmetric.util; 2 3import java.security.InvalidKeyException; 4import java.security.PrivateKey; 5import java.security.PublicKey; 6 7import org.bouncycastle.asn1.ASN1ObjectIdentifier; 8// BEGIN android-removed 9// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves; 10// END android-removed 11import org.bouncycastle.asn1.nist.NISTNamedCurves; 12import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 13import org.bouncycastle.asn1.sec.SECNamedCurves; 14// BEGIN android-removed 15// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves; 16// END android-removed 17import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 18import org.bouncycastle.asn1.x9.X962NamedCurves; 19import org.bouncycastle.asn1.x9.X9ECParameters; 20import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 21import org.bouncycastle.crypto.params.ECDomainParameters; 22import org.bouncycastle.crypto.params.ECPrivateKeyParameters; 23import org.bouncycastle.crypto.params.ECPublicKeyParameters; 24import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; 25import org.bouncycastle.jce.interfaces.ECPrivateKey; 26import org.bouncycastle.jce.interfaces.ECPublicKey; 27import org.bouncycastle.jce.provider.BouncyCastleProvider; 28import org.bouncycastle.jce.spec.ECParameterSpec; 29 30/** 31 * utility class for converting jce/jca ECDSA, ECDH, and ECDHC 32 * objects into their org.bouncycastle.crypto counterparts. 33 */ 34public class ECUtil 35{ 36 /** 37 * Returns a sorted array of middle terms of the reduction polynomial. 38 * @param k The unsorted array of middle terms of the reduction polynomial 39 * of length 1 or 3. 40 * @return the sorted array of middle terms of the reduction polynomial. 41 * This array always has length 3. 42 */ 43 static int[] convertMidTerms( 44 int[] k) 45 { 46 int[] res = new int[3]; 47 48 if (k.length == 1) 49 { 50 res[0] = k[0]; 51 } 52 else 53 { 54 if (k.length != 3) 55 { 56 throw new IllegalArgumentException("Only Trinomials and pentanomials supported"); 57 } 58 59 if (k[0] < k[1] && k[0] < k[2]) 60 { 61 res[0] = k[0]; 62 if (k[1] < k[2]) 63 { 64 res[1] = k[1]; 65 res[2] = k[2]; 66 } 67 else 68 { 69 res[1] = k[2]; 70 res[2] = k[1]; 71 } 72 } 73 else if (k[1] < k[2]) 74 { 75 res[0] = k[1]; 76 if (k[0] < k[2]) 77 { 78 res[1] = k[0]; 79 res[2] = k[2]; 80 } 81 else 82 { 83 res[1] = k[2]; 84 res[2] = k[0]; 85 } 86 } 87 else 88 { 89 res[0] = k[2]; 90 if (k[0] < k[1]) 91 { 92 res[1] = k[0]; 93 res[2] = k[1]; 94 } 95 else 96 { 97 res[1] = k[1]; 98 res[2] = k[0]; 99 } 100 } 101 } 102 103 return res; 104 } 105 106 public static AsymmetricKeyParameter generatePublicKeyParameter( 107 PublicKey key) 108 throws InvalidKeyException 109 { 110 if (key instanceof ECPublicKey) 111 { 112 ECPublicKey k = (ECPublicKey)key; 113 ECParameterSpec s = k.getParameters(); 114 115 if (s == null) 116 { 117 s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 118 119 return new ECPublicKeyParameters( 120 ((BCECPublicKey)k).engineGetQ(), 121 new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); 122 } 123 else 124 { 125 return new ECPublicKeyParameters( 126 k.getQ(), 127 new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); 128 } 129 } 130 else if (key instanceof java.security.interfaces.ECPublicKey) 131 { 132 java.security.interfaces.ECPublicKey pubKey = (java.security.interfaces.ECPublicKey)key; 133 ECParameterSpec s = EC5Util.convertSpec(pubKey.getParams(), false); 134 return new ECPublicKeyParameters( 135 EC5Util.convertPoint(pubKey.getParams(), pubKey.getW(), false), 136 new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); 137 } 138 else 139 { 140 // see if we can build a key from key.getEncoded() 141 try 142 { 143 byte[] bytes = key.getEncoded(); 144 145 if (bytes == null) 146 { 147 throw new InvalidKeyException("no encoding for EC public key"); 148 } 149 150 PublicKey publicKey = BouncyCastleProvider.getPublicKey(SubjectPublicKeyInfo.getInstance(bytes)); 151 152 if (publicKey instanceof java.security.interfaces.ECPublicKey) 153 { 154 return ECUtil.generatePublicKeyParameter(publicKey); 155 } 156 } 157 catch (Exception e) 158 { 159 throw new InvalidKeyException("cannot identify EC public key: " + e.toString()); 160 } 161 } 162 163 throw new InvalidKeyException("cannot identify EC public key."); 164 } 165 166 public static AsymmetricKeyParameter generatePrivateKeyParameter( 167 PrivateKey key) 168 throws InvalidKeyException 169 { 170 if (key instanceof ECPrivateKey) 171 { 172 ECPrivateKey k = (ECPrivateKey)key; 173 ECParameterSpec s = k.getParameters(); 174 175 if (s == null) 176 { 177 s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 178 } 179 180 return new ECPrivateKeyParameters( 181 k.getD(), 182 new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); 183 } 184 else if (key instanceof java.security.interfaces.ECPrivateKey) 185 { 186 java.security.interfaces.ECPrivateKey privKey = (java.security.interfaces.ECPrivateKey)key; 187 ECParameterSpec s = EC5Util.convertSpec(privKey.getParams(), false); 188 return new ECPrivateKeyParameters( 189 privKey.getS(), 190 new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed())); 191 } 192 else 193 { 194 // see if we can build a key from key.getEncoded() 195 try 196 { 197 byte[] bytes = key.getEncoded(); 198 199 if (bytes == null) 200 { 201 throw new InvalidKeyException("no encoding for EC private key"); 202 } 203 204 PrivateKey privateKey = BouncyCastleProvider.getPrivateKey(PrivateKeyInfo.getInstance(bytes)); 205 206 if (privateKey instanceof java.security.interfaces.ECPrivateKey) 207 { 208 return ECUtil.generatePrivateKeyParameter(privateKey); 209 } 210 } 211 catch (Exception e) 212 { 213 throw new InvalidKeyException("cannot identify EC private key: " + e.toString()); 214 } 215 } 216 217 throw new InvalidKeyException("can't identify EC private key."); 218 } 219 220 public static ASN1ObjectIdentifier getNamedCurveOid( 221 String name) 222 { 223 ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name); 224 225 if (oid == null) 226 { 227 oid = SECNamedCurves.getOID(name); 228 if (oid == null) 229 { 230 oid = NISTNamedCurves.getOID(name); 231 } 232 // BEGIN android-removed 233 // if (oid == null) 234 // { 235 // oid = TeleTrusTNamedCurves.getOID(name); 236 // } 237 // if (oid == null) 238 // { 239 // oid = ECGOST3410NamedCurves.getOID(name); 240 // } 241 // END android-removed 242 } 243 244 return oid; 245 } 246 247 public static X9ECParameters getNamedCurveByOid( 248 ASN1ObjectIdentifier oid) 249 { 250 X9ECParameters params = X962NamedCurves.getByOID(oid); 251 252 if (params == null) 253 { 254 params = SECNamedCurves.getByOID(oid); 255 if (params == null) 256 { 257 params = NISTNamedCurves.getByOID(oid); 258 } 259 // BEGIN android-removed 260 // if (params == null) 261 // { 262 // params = TeleTrusTNamedCurves.getByOID(oid); 263 // } 264 // END android-removed 265 } 266 267 return params; 268 } 269 270 public static String getCurveName( 271 ASN1ObjectIdentifier oid) 272 { 273 String name = X962NamedCurves.getName(oid); 274 275 if (name == null) 276 { 277 name = SECNamedCurves.getName(oid); 278 if (name == null) 279 { 280 name = NISTNamedCurves.getName(oid); 281 } 282 // BEGIN android-removed 283 // if (name == null) 284 // { 285 // name = TeleTrusTNamedCurves.getName(oid); 286 // } 287 // if (name == null) 288 // { 289 // name = ECGOST3410NamedCurves.getName(oid); 290 // } 291 // END android-removed 292 } 293 294 return name; 295 } 296} 297