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 if (keySpec instanceof ECPublicKeySpec) 145 { 146 return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration); 147 } 148 else if (keySpec instanceof java.security.spec.ECPublicKeySpec) 149 { 150 return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration); 151 } 152 153 return super.engineGeneratePublic(keySpec); 154 } 155 generatePrivate(PrivateKeyInfo keyInfo)156 public PrivateKey generatePrivate(PrivateKeyInfo keyInfo) 157 throws IOException 158 { 159 ASN1ObjectIdentifier algOid = keyInfo.getPrivateKeyAlgorithm().getAlgorithm(); 160 161 if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 162 { 163 return new BCECPrivateKey(algorithm, keyInfo, configuration); 164 } 165 else 166 { 167 throw new IOException("algorithm identifier " + algOid + " in key not recognised"); 168 } 169 } 170 generatePublic(SubjectPublicKeyInfo keyInfo)171 public PublicKey generatePublic(SubjectPublicKeyInfo keyInfo) 172 throws IOException 173 { 174 ASN1ObjectIdentifier algOid = keyInfo.getAlgorithm().getAlgorithm(); 175 176 if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey)) 177 { 178 return new BCECPublicKey(algorithm, keyInfo, configuration); 179 } 180 else 181 { 182 throw new IOException("algorithm identifier " + algOid + " in key not recognised"); 183 } 184 } 185 186 public static class EC 187 extends KeyFactorySpi 188 { EC()189 public EC() 190 { 191 super("EC", BouncyCastleProvider.CONFIGURATION); 192 } 193 } 194 195 public static class ECDSA 196 extends KeyFactorySpi 197 { ECDSA()198 public ECDSA() 199 { 200 super("ECDSA", BouncyCastleProvider.CONFIGURATION); 201 } 202 } 203 204 // BEGIN android-removed 205 // public static class ECGOST3410 206 // extends KeyFactorySpi 207 // { 208 // public ECGOST3410() 209 // { 210 // super("ECGOST3410", BouncyCastleProvider.CONFIGURATION); 211 // } 212 // } 213 // END android-removed 214 215 public static class ECDH 216 extends KeyFactorySpi 217 { ECDH()218 public ECDH() 219 { 220 super("ECDH", BouncyCastleProvider.CONFIGURATION); 221 } 222 } 223 224 public static class ECDHC 225 extends KeyFactorySpi 226 { ECDHC()227 public ECDHC() 228 { 229 super("ECDHC", BouncyCastleProvider.CONFIGURATION); 230 } 231 } 232 233 public static class ECMQV 234 extends KeyFactorySpi 235 { ECMQV()236 public ECMQV() 237 { 238 super("ECMQV", BouncyCastleProvider.CONFIGURATION); 239 } 240 } 241 }