OpenSSLECKeyFactory.java revision cb4e73b4fffb5c5608f320f0af1004ebcfad71c0
111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root/* 211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * Copyright (C) 2013 The Android Open Source Project 311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * 411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * you may not use this file except in compliance with the License. 611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * You may obtain a copy of the License at 711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * 811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * http://www.apache.org/licenses/LICENSE-2.0 911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * 1011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * Unless required by applicable law or agreed to in writing, software 1111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 1211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * See the License for the specific language governing permissions and 1411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root * limitations under the License. 1511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root */ 1611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 1711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootpackage org.apache.harmony.xnet.provider.jsse; 1811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 1911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.math.BigInteger; 2011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.InvalidKeyException; 2111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.Key; 2211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.KeyFactorySpi; 2311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.PrivateKey; 2411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.PublicKey; 2511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.interfaces.ECPrivateKey; 2611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.interfaces.ECPublicKey; 2711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.ECParameterSpec; 2811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.ECPoint; 2911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.ECPrivateKeySpec; 3011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.ECPublicKeySpec; 3111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.InvalidKeySpecException; 3211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.KeySpec; 3311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.PKCS8EncodedKeySpec; 3411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootimport java.security.spec.X509EncodedKeySpec; 3511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 3611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Rootpublic class OpenSSLECKeyFactory extends KeyFactorySpi { 3711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 3811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root @Override 3911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { 4011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (keySpec instanceof ECPublicKeySpec) { 4111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPublicKeySpec ecKeySpec = (ECPublicKeySpec) keySpec; 4211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 4311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return new OpenSSLECPublicKey(ecKeySpec); 4411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else if (keySpec instanceof X509EncodedKeySpec) { 4511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root X509EncodedKeySpec x509KeySpec = (X509EncodedKeySpec) keySpec; 4611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 4711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root try { 4811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root final OpenSSLKey key = new OpenSSLKey( 4911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root NativeCrypto.d2i_PUBKEY(x509KeySpec.getEncoded())); 5011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return new OpenSSLECPublicKey(key); 5111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } catch (Exception e) { 5211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeySpecException(e); 5311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 5411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 5511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeySpecException("Must use ECPublicKeySpec or X509EncodedKeySpec; was " 5611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root + keySpec.getClass().getName()); 5711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 5811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 5911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root @Override 6011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root protected PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { 6111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (keySpec instanceof ECPrivateKeySpec) { 6211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPrivateKeySpec ecKeySpec = (ECPrivateKeySpec) keySpec; 6311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 6411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return new OpenSSLECPrivateKey(ecKeySpec); 6511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else if (keySpec instanceof PKCS8EncodedKeySpec) { 6611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root PKCS8EncodedKeySpec pkcs8KeySpec = (PKCS8EncodedKeySpec) keySpec; 6711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 6811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root try { 6911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root final OpenSSLKey key = new OpenSSLKey( 7011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(pkcs8KeySpec.getEncoded())); 7111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return new OpenSSLECPrivateKey(key); 7211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } catch (Exception e) { 7311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeySpecException(e); 7411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 7511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 769414cebabcf332fcca1f40fa629cc471cfbbc21cKenny Root throw new InvalidKeySpecException("Must use ECPrivateKeySpec or PKCS8EncodedKeySpec; was " 7711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root + keySpec.getClass().getName()); 7811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 7911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 8011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root @Override 8111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) 8211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throws InvalidKeySpecException { 8311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (key == null) { 8411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeySpecException("key == null"); 8511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 8611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 8711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (keySpec == null) { 8811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeySpecException("keySpec == null"); 8911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 9011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 9111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (key instanceof ECPublicKey) { 9211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPublicKey ecKey = (ECPublicKey) key; 9311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 9411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (ECPublicKeySpec.class.equals(keySpec)) { 9511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECParameterSpec params = ecKey.getParams(); 9611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 9711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPoint w = ecKey.getW(); 9811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 9911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return (T) new ECPublicKeySpec(w, params); 100cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root } else if (X509EncodedKeySpec.class.equals(keySpec)) { 101cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root return (T) new X509EncodedKeySpec(key.getEncoded()); 10211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else { 103cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root throw new InvalidKeySpecException( 104cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root "Must be ECPublicKeySpec or X509EncodedKeySpec; was " + keySpec.getName()); 10511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 10611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else if (key instanceof ECPrivateKey) { 10711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPrivateKey ecKey = (ECPrivateKey) key; 10811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 10911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (ECPrivateKeySpec.class.equals(keySpec)) { 11011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECParameterSpec params = ecKey.getParams(); 11111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 11211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root BigInteger s = ecKey.getS(); 11311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 11411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return (T) new ECPrivateKeySpec(s, params); 115cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root } else if (PKCS8EncodedKeySpec.class.equals(keySpec)) { 116cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root return (T) new PKCS8EncodedKeySpec(ecKey.getEncoded()); 11711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else { 118cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root throw new InvalidKeySpecException( 119cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root "Must be ECPrivateKeySpec or PKCS8EncodedKeySpec; was " + keySpec.getName()); 12011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 12111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else { 122cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root throw new InvalidKeySpecException("Must be ECPublicKey or ECPrivateKey; was " 123cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root + key.getClass().getName()); 12411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 12511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 12611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 12711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root @Override 12811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root protected Key engineTranslateKey(Key key) throws InvalidKeyException { 12911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (key == null) { 13011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeyException("key == null"); 13111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 13211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 13311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root if (key instanceof ECPublicKey) { 13411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPublicKey ecKey = (ECPublicKey) key; 13511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 13611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPoint w = ecKey.getW(); 13711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 13811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECParameterSpec params = ecKey.getParams(); 13911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 14011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root try { 14111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root return engineGeneratePublic(new ECPublicKeySpec(w, params)); 14211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } catch (InvalidKeySpecException e) { 14311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeyException(e); 14411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 14511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else if (key instanceof ECPrivateKey) { 14611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECPrivateKey ecKey = (ECPrivateKey) key; 14711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 14811b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root BigInteger s = ecKey.getS(); 14911b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 15011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root ECParameterSpec params = ecKey.getParams(); 15111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 15211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root try { 1539414cebabcf332fcca1f40fa629cc471cfbbc21cKenny Root return engineGeneratePrivate(new ECPrivateKeySpec(s, params)); 15411b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } catch (InvalidKeySpecException e) { 15511b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root throw new InvalidKeyException(e); 15611b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 15711b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } else { 158cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root throw new InvalidKeyException("Key must be ECPublicKey or ECPrivateKey; was " 159cb4e73b4fffb5c5608f320f0af1004ebcfad71c0Kenny Root + key.getClass().getName()); 16011b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 16111b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root } 16211b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root 16311b3e7025853f061e2f0e0ce1e248e730eca721eKenny Root} 164