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