1 package org.bouncycastle.jcajce.provider.asymmetric.ec; 2 3 import java.io.IOException; 4 import java.security.InvalidKeyException; 5 import java.security.Key; 6 import java.security.PrivateKey; 7 import java.security.PublicKey; 8 import java.security.interfaces.ECPrivateKey; 9 import java.security.interfaces.ECPublicKey; 10 import java.security.spec.InvalidKeySpecException; 11 import java.security.spec.KeySpec; 12 13 import org.bouncycastle.asn1.ASN1ObjectIdentifier; 14 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 15 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 16 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 17 import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi; 18 import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util; 19 import org.bouncycastle.jcajce.provider.config.ProviderConfiguration; 20 import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter; 21 import org.bouncycastle.jce.provider.BouncyCastleProvider; 22 import org.bouncycastle.jce.spec.ECParameterSpec; 23 import org.bouncycastle.jce.spec.ECPrivateKeySpec; 24 import org.bouncycastle.jce.spec.ECPublicKeySpec; 25 26 public class KeyFactorySpi 27 extends BaseKeyFactorySpi 28 implements AsymmetricKeyInfoConverter 29 { 30 String algorithm; 31 ProviderConfiguration configuration; 32 KeyFactorySpi( String algorithm, ProviderConfiguration configuration)33 KeyFactorySpi( 34 String algorithm, 35 ProviderConfiguration configuration) 36 { 37 this.algorithm = algorithm; 38 this.configuration = configuration; 39 } 40 engineTranslateKey( Key key)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 engineGetKeySpec( Key key, Class spec)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 engineGeneratePrivate( KeySpec keySpec)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 engineGeneratePublic( KeySpec keySpec)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 generatePrivate(PrivateKeyInfo keyInfo)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 generatePublic(SubjectPublicKeyInfo keyInfo)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 { EC()196 public EC() 197 { 198 super("EC", BouncyCastleProvider.CONFIGURATION); 199 } 200 } 201 202 public static class ECDSA 203 extends KeyFactorySpi 204 { ECDSA()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 { ECDH()225 public ECDH() 226 { 227 super("ECDH", BouncyCastleProvider.CONFIGURATION); 228 } 229 } 230 231 public static class ECDHC 232 extends KeyFactorySpi 233 { ECDHC()234 public ECDHC() 235 { 236 super("ECDHC", BouncyCastleProvider.CONFIGURATION); 237 } 238 } 239 240 public static class ECMQV 241 extends KeyFactorySpi 242 { ECMQV()243 public ECMQV() 244 { 245 super("ECMQV", BouncyCastleProvider.CONFIGURATION); 246 } 247 } 248 }