19d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root/* 29d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * Copyright (C) 2012 The Android Open Source Project 39d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * 49d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 59d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * you may not use this file except in compliance with the License. 69d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * You may obtain a copy of the License at 79d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * 89d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 99d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * 109d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * Unless required by applicable law or agreed to in writing, software 119d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 129d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * See the License for the specific language governing permissions and 149d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * limitations under the License. 159d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root */ 169d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 1738375a4d0b3d34e2babbd2f6a013976c7c439696Kenny Rootpackage org.conscrypt; 189d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 199d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.InvalidAlgorithmParameterException; 209d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.InvalidParameterException; 219d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.KeyPair; 229d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.KeyPairGenerator; 239d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.SecureRandom; 249d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.spec.AlgorithmParameterSpec; 259d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.spec.ECGenParameterSpec; 269d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.security.spec.ECParameterSpec; 279d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.util.HashMap; 289d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootimport java.util.Map; 299d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 309d2fb535e5d43ad34af09195d490da18a7694a48Kenny Rootpublic final class OpenSSLECKeyPairGenerator extends KeyPairGenerator { 319d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root private static final String ALGORITHM = "EC"; 329d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 339d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root private static final int DEFAULT_KEY_SIZE = 192; 349d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 359d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root private static final Map<Integer, String> SIZE_TO_CURVE_NAME = new HashMap<Integer, String>(); 369d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 379d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root static { 389d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root /* NIST curves */ 399d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root SIZE_TO_CURVE_NAME.put(192, "prime192v1"); 403fefbd8abaf356e842705f8ebd24b414dcea8aacKenny Root SIZE_TO_CURVE_NAME.put(224, "secp224r1"); 419d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root SIZE_TO_CURVE_NAME.put(256, "prime256v1"); 423fefbd8abaf356e842705f8ebd24b414dcea8aacKenny Root SIZE_TO_CURVE_NAME.put(384, "secp384r1"); 433fefbd8abaf356e842705f8ebd24b414dcea8aacKenny Root SIZE_TO_CURVE_NAME.put(521, "secp521r1"); 449d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 459d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 469d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root private OpenSSLECGroupContext group; 479d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 489d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root public OpenSSLECKeyPairGenerator() { 499d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root super(ALGORITHM); 509d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 519d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 529d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root @Override 539d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root public KeyPair generateKeyPair() { 549d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root if (group == null) { 559d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final String curveName = SIZE_TO_CURVE_NAME.get(DEFAULT_KEY_SIZE); 569d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root group = OpenSSLECGroupContext.getCurveByName(curveName); 579d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 589d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 599d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final OpenSSLKey key = new OpenSSLKey(NativeCrypto.EC_KEY_generate_key(group.getContext())); 609d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root return new KeyPair(new OpenSSLECPublicKey(group, key), new OpenSSLECPrivateKey(group, key)); 619d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 629d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 639d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root @Override 649d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root public void initialize(int keysize, SecureRandom random) { 659d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final String name = SIZE_TO_CURVE_NAME.get(keysize); 669d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root if (name == null) { 679d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root throw new InvalidParameterException("unknown key size " + keysize); 689d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 699d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 709d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root /* 719d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * Store the group in a temporary variable until we know this is a valid 729d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * group. 739d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root */ 749d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext.getCurveByName(name); 759d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root if (possibleGroup == null) { 769d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root throw new InvalidParameterException("unknown curve " + name); 779d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 789d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 799d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root group = possibleGroup; 809d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 819d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 829d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root @Override 839d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root public void initialize(AlgorithmParameterSpec param, SecureRandom random) 849d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root throws InvalidAlgorithmParameterException { 859d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root if (param instanceof ECParameterSpec) { 869d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root ECParameterSpec ecParam = (ECParameterSpec) param; 879d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 889d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root group = OpenSSLECGroupContext.getInstance(ecParam); 899d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } else if (param instanceof ECGenParameterSpec) { 909d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root ECGenParameterSpec ecParam = (ECGenParameterSpec) param; 919d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 929d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final String curveName = ecParam.getName(); 939d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 949d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root /* 959d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * Store the group in a temporary variable until we know this is a 969d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root * valid group. 979d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root */ 989d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root final OpenSSLECGroupContext possibleGroup = OpenSSLECGroupContext 999d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root .getCurveByName(curveName); 1009d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root if (possibleGroup == null) { 1019d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root throw new InvalidAlgorithmParameterException("unknown curve name: " + curveName); 1029d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 1039d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root 1049d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root group = possibleGroup; 1059d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } else { 1069d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root throw new InvalidAlgorithmParameterException( 1079d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root "parameter must be ECParameterSpec or ECGenParameterSpec"); 1089d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 1099d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root } 1109d2fb535e5d43ad34af09195d490da18a7694a48Kenny Root} 111