1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.harmony.xnet.provider.jsse; 18 19 import java.security.InvalidAlgorithmParameterException; 20 import java.security.InvalidParameterException; 21 import java.security.KeyPair; 22 import java.security.KeyPairGenerator; 23 import java.security.SecureRandom; 24 import java.security.spec.AlgorithmParameterSpec; 25 import java.security.spec.ECGenParameterSpec; 26 import java.security.spec.ECParameterSpec; 27 import java.util.HashMap; 28 import java.util.Map; 29 30 public final class OpenSSLECKeyPairGenerator extends KeyPairGenerator { 31 private static final String ALGORITHM = "EC"; 32 33 private static final int DEFAULT_KEY_SIZE = 192; 34 35 private static final Map<Integer, String> SIZE_TO_CURVE_NAME = new HashMap<Integer, String>(); 36 37 static { 38 /* NIST curves */ 39 SIZE_TO_CURVE_NAME.put(192, "prime192v1"); 40 SIZE_TO_CURVE_NAME.put(224, "secp224r1"); 41 SIZE_TO_CURVE_NAME.put(256, "prime256v1"); 42 SIZE_TO_CURVE_NAME.put(384, "secp384r1"); 43 SIZE_TO_CURVE_NAME.put(521, "secp521r1"); 44 } 45 46 private OpenSSLECGroupContext group; 47 48 public OpenSSLECKeyPairGenerator() { 49 super(ALGORITHM); 50 } 51 52 @Override 53 public KeyPair generateKeyPair() { 54 if (group == null) { 55 final String curveName = SIZE_TO_CURVE_NAME.get(DEFAULT_KEY_SIZE); 56 group = OpenSSLECGroupContext.getCurveByName(curveName); 57 } 58 59 final OpenSSLKey key = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group.getContext())); 60 return new KeyPair(new OpenSSLECPublicKey(group, key), new OpenSSLECPrivateKey(group, key)); 61 } 62 63 @Override 64 public void initialize(int keysize, SecureRandom random) { 65 final String name = SIZE_TO_CURVE_NAME.get(keysize); 66 if (name == null) { 67 throw new InvalidParameterException("unknown key size " + keysize); 68 } 69 70 /* 71 * Store the group in a temporary variable until we know this is a valid 72 * group. 73 */ 74 final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext.getCurveByName(name); 75 if (possibleGroup == null) { 76 throw new InvalidParameterException("unknown curve " + name); 77 } 78 79 group = possibleGroup; 80 } 81 82 @Override 83 public void initialize(AlgorithmParameterSpec param, SecureRandom random) 84 throws InvalidAlgorithmParameterException { 85 if (param instanceof ECParameterSpec) { 86 ECParameterSpec ecParam = (ECParameterSpec) param; 87 88 group = OpenSSLECGroupContext.getInstance(ecParam); 89 } else if (param instanceof ECGenParameterSpec) { 90 ECGenParameterSpec ecParam = (ECGenParameterSpec) param; 91 92 final String curveName = ecParam.getName(); 93 94 /* 95 * Store the group in a temporary variable until we know this is a 96 * valid group. 97 */ 98 final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext 99 .getCurveByName(curveName); 100 if (possibleGroup == null) { 101 throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); 102 } 103 104 group = possibleGroup; 105 } else { 106 throw new InvalidAlgorithmParameterException( 107 "parameter must be ECParameterSpec or ECGenParameterSpec"); 108 } 109 } 110 } 111