1package org.bouncycastle.jcajce.provider.asymmetric.ec; 2 3import java.io.IOException; 4import java.security.InvalidKeyException; 5import java.security.Key; 6import java.security.PrivateKey; 7import java.security.PublicKey; 8import java.security.interfaces.ECPrivateKey; 9import java.security.interfaces.ECPublicKey; 10import java.security.spec.InvalidKeySpecException; 11import java.security.spec.KeySpec; 12 13import org.bouncycastle.asn1.ASN1ObjectIdentifier; 14import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 15import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 16import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 17import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; 18import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; 19import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; 20import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; 21import org.bouncycastle.jce.provider.BouncyCastleProvider; 22import org.bouncycastle.jce.spec.ECParameterSpec; 23import org.bouncycastle.jce.spec.ECPrivateKeySpec; 24import org.bouncycastle.jce.spec.ECPublicKeySpec; 25 26public class KeyFactorySpi 27 extends BaseKeyFactorySpi 28 implements AsymmetricKeyInfoConverter 29{ 30 String algorithm; 31 ProviderConfiguration configuration; 32 33 KeyFactorySpi( 34 String algorithm, 35 ProviderConfiguration configuration) 36 { 37 this.algorithm = algorithm; 38 this.configuration = configuration; 39 } 40 41 protected Key engineTranslateKey( 42 Key key) 43 throws InvalidKeyException 44 { 45 if (key instanceof ECPublicKey) 46 { 47 return new BCECPublicKey((ECPublicKey)key, configuration); 48 } 49 else if (key instanceof ECPrivateKey) 50 { 51 return new BCECPrivateKey((ECPrivateKey)key, configuration); 52 } 53 54 throw new InvalidKeyException("key type unknown"); 55 } 56 57 protected KeySpec engineGetKeySpec( 58 Key key, 59 Class spec) 60 throws InvalidKeySpecException 61 { 62 if (spec.isAssignableFrom(java.security.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) 63 { 64 ECPublicKey k = (ECPublicKey)key; 65 if (k.getParams() != null) 66 { 67 return new java.security.spec.ECPublicKeySpec(k.getW(), k.getParams()); 68 } 69 else 70 { 71 ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 72 73 return new java.security.spec.ECPublicKeySpec(k.getW(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); 74 } 75 } 76 else if (spec.isAssignableFrom(java.security.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) 77 { 78 ECPrivateKey k = (ECPrivateKey)key; 79 80 if (k.getParams() != null) 81 { 82 return new java.security.spec.ECPrivateKeySpec(k.getS(), k.getParams()); 83 } 84 else 85 { 86 ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 87 88 return new java.security.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(EC5Util.convertCurve(implicitSpec.getCurve(), implicitSpec.getSeed()), implicitSpec)); 89 } 90 } 91 else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPublicKeySpec.class) && key instanceof ECPublicKey) 92 { 93 ECPublicKey k = (ECPublicKey)key; 94 if (k.getParams() != null) 95 { 96 return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false)); 97 } 98 else 99 { 100 ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 101 102 return new org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), implicitSpec); 103 } 104 } 105 else if (spec.isAssignableFrom(org.bouncycastle.jce.spec.ECPrivateKeySpec.class) && key instanceof ECPrivateKey) 106 { 107 ECPrivateKey k = (ECPrivateKey)key; 108 109 if (k.getParams() != null) 110 { 111 return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false)); 112 } 113 else 114 { 115 ECParameterSpec implicitSpec = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa(); 116 117 return new org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), implicitSpec); 118 } 119 } 120 121 return super.engineGetKeySpec(key, spec); 122 } 123 124 protected PrivateKey engineGeneratePrivate( 125 KeySpec keySpec) 126 throws InvalidKeySpecException 127 { 128 if (keySpec instanceof ECPrivateKeySpec) 129 { 130 return new BCECPrivateKey(algorithm, (ECPrivateKeySpec)keySpec, configuration); 131 } 132 else if (keySpec instanceof java.security.spec.ECPrivateKeySpec) 133 { 134 return new BCECPrivateKey(algorithm, (java.security.spec.ECPrivateKeySpec)keySpec, configuration); 135 } 136 137 return super.engineGeneratePrivate(keySpec); 138 } 139 140 protected PublicKey engineGeneratePublic( 141 KeySpec keySpec) 142 throws InvalidKeySpecException 143 { 144 try 145 { 146 if (keySpec instanceof ECPublicKeySpec) 147 { 148 return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration); 149 } 150 else if (keySpec instanceof java.security.spec.ECPublicKeySpec) 151 { 152 return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration); 153 } 154 } 155 catch (Exception e) 156 { 157 throw new InvalidKeySpecException("invalid KeySpec: " + e.getMessage(), e); 158 } 159 160 return super.engineGeneratePublic(keySpec); 161 } 162 163 public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) 164 throws IOException 165 { 166 ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); 167 168 if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 169 { 170 return new BCECPrivateKey(algorithm, keyInfo, configuration); 171 } 172 else 173 { 174 throw new IOException("algorithm identifier " + algOid + " in key not recognised"); 175 } 176 } 177 178 public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) 179 throws IOException 180 { 181 ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); 182 183 if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 184 { 185 return new BCECPublicKey(algorithm, keyInfo, configuration); 186 } 187 else 188 { 189 throw new IOException("algorithm identifier " + algOid + " in key not recognised"); 190 } 191 } 192 193 public static class EC 194 extends KeyFactorySpi 195 { 196 public EC() 197 { 198 super("EC", BouncyCastleProvider.CONFIGURATION); 199 } 200 } 201 202 public static class ECDSA 203 extends KeyFactorySpi 204 { 205 public ECDSA() 206 { 207 super("ECDSA", BouncyCastleProvider.CONFIGURATION); 208 } 209 } 210 211 // BEGIN android-removed 212 // public static class ECGOST3410 213 // extends KeyFactorySpi 214 // { 215 // public ECGOST3410() 216 // { 217 // super("ECGOST3410", BouncyCastleProvider.CONFIGURATION); 218 // } 219 // } 220 // END android-removed 221 222 public static class ECDH 223 extends KeyFactorySpi 224 { 225 public ECDH() 226 { 227 super("ECDH", BouncyCastleProvider.CONFIGURATION); 228 } 229 } 230 231 public static class ECDHC 232 extends KeyFactorySpi 233 { 234 public ECDHC() 235 { 236 super("ECDHC", BouncyCastleProvider.CONFIGURATION); 237 } 238 } 239 240 public static class ECMQV 241 extends KeyFactorySpi 242 { 243 public ECMQV() 244 { 245 super("ECMQV", BouncyCastleProvider.CONFIGURATION); 246 } 247 } 248}