1746a236e2be5dee62c482e27f4c682496d071d8bKenny Root/* 2746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * Copyright (C) 2012 The Android Open Source Project 3746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * 4746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * you may not use this file except in compliance with the License. 6746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * You may obtain a copy of the License at 7746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * 8746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * 10746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * Unless required by applicable law or agreed to in writing, software 11746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * See the License for the specific language governing permissions and 14746a236e2be5dee62c482e27f4c682496d071d8bKenny Root * limitations under the License. 15746a236e2be5dee62c482e27f4c682496d071d8bKenny Root */ 16746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 17746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootpackage org.apache.harmony.xnet.provider.jsse; 18746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 19746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.math.BigInteger; 20746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.security.InvalidKeyException; 21746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.security.interfaces.DSAParams; 22746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.security.interfaces.DSAPublicKey; 23746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.security.spec.DSAPublicKeySpec; 24746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootimport java.security.spec.InvalidKeySpecException; 25746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 26746a236e2be5dee62c482e27f4c682496d071d8bKenny Rootpublic class OpenSSLDSAPublicKey implements DSAPublicKey { 27d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root private static final long serialVersionUID = 5238609500353792232L; 28d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 29746a236e2be5dee62c482e27f4c682496d071d8bKenny Root private final OpenSSLKey key; 30746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 31746a236e2be5dee62c482e27f4c682496d071d8bKenny Root private OpenSSLDSAParams params; 32746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 33746a236e2be5dee62c482e27f4c682496d071d8bKenny Root OpenSSLDSAPublicKey(OpenSSLKey key) { 34746a236e2be5dee62c482e27f4c682496d071d8bKenny Root this.key = key; 35746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 36746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 3791bb5fbe55b854df891ff7720e30d42081dbcd58Kenny Root OpenSSLKey getOpenSSLKey() { 3891bb5fbe55b854df891ff7720e30d42081dbcd58Kenny Root return key; 3991bb5fbe55b854df891ff7720e30d42081dbcd58Kenny Root } 4091bb5fbe55b854df891ff7720e30d42081dbcd58Kenny Root 41746a236e2be5dee62c482e27f4c682496d071d8bKenny Root OpenSSLDSAPublicKey(DSAPublicKeySpec dsaKeySpec) throws InvalidKeySpecException { 42746a236e2be5dee62c482e27f4c682496d071d8bKenny Root try { 43746a236e2be5dee62c482e27f4c682496d071d8bKenny Root key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 44746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaKeySpec.getP().toByteArray(), 45746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaKeySpec.getQ().toByteArray(), 46746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaKeySpec.getG().toByteArray(), 47746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaKeySpec.getY().toByteArray(), 48746a236e2be5dee62c482e27f4c682496d071d8bKenny Root null)); 49746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } catch (Exception e) { 50746a236e2be5dee62c482e27f4c682496d071d8bKenny Root throw new InvalidKeySpecException(e); 51746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 52746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 53746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 54746a236e2be5dee62c482e27f4c682496d071d8bKenny Root private void ensureReadParams() { 55746a236e2be5dee62c482e27f4c682496d071d8bKenny Root if (params == null) { 56746a236e2be5dee62c482e27f4c682496d071d8bKenny Root params = new OpenSSLDSAParams(key); 57746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 58746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 59746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 60746a236e2be5dee62c482e27f4c682496d071d8bKenny Root static OpenSSLKey getInstance(DSAPublicKey dsaPublicKey) throws InvalidKeyException { 61746a236e2be5dee62c482e27f4c682496d071d8bKenny Root try { 62746a236e2be5dee62c482e27f4c682496d071d8bKenny Root final DSAParams dsaParams = dsaPublicKey.getParams(); 63746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 64746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaParams.getP().toByteArray(), 65746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaParams.getQ().toByteArray(), 66746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaParams.getG().toByteArray(), 67746a236e2be5dee62c482e27f4c682496d071d8bKenny Root dsaPublicKey.getY().toByteArray(), 68746a236e2be5dee62c482e27f4c682496d071d8bKenny Root null)); 69746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } catch (Exception e) { 70746a236e2be5dee62c482e27f4c682496d071d8bKenny Root throw new InvalidKeyException(e); 71746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 72746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 73746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 74746a236e2be5dee62c482e27f4c682496d071d8bKenny Root @Override 75746a236e2be5dee62c482e27f4c682496d071d8bKenny Root public DSAParams getParams() { 76746a236e2be5dee62c482e27f4c682496d071d8bKenny Root ensureReadParams(); 77746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return params; 78746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 79746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 80746a236e2be5dee62c482e27f4c682496d071d8bKenny Root @Override 81746a236e2be5dee62c482e27f4c682496d071d8bKenny Root public String getAlgorithm() { 82746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return "DSA"; 83746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 84746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 85746a236e2be5dee62c482e27f4c682496d071d8bKenny Root @Override 86746a236e2be5dee62c482e27f4c682496d071d8bKenny Root public String getFormat() { 87746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return "X.509"; 88746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 89746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 90746a236e2be5dee62c482e27f4c682496d071d8bKenny Root @Override 91746a236e2be5dee62c482e27f4c682496d071d8bKenny Root public byte[] getEncoded() { 92746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return NativeCrypto.i2d_PUBKEY(key.getPkeyContext()); 93746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 94746a236e2be5dee62c482e27f4c682496d071d8bKenny Root 95746a236e2be5dee62c482e27f4c682496d071d8bKenny Root @Override 96746a236e2be5dee62c482e27f4c682496d071d8bKenny Root public BigInteger getY() { 97746a236e2be5dee62c482e27f4c682496d071d8bKenny Root ensureReadParams(); 98746a236e2be5dee62c482e27f4c682496d071d8bKenny Root return params.getY(); 99746a236e2be5dee62c482e27f4c682496d071d8bKenny Root } 100d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 101d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root @Override 102d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root public boolean equals(Object o) { 103d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root if (o == this) { 104d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return true; 105d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 106d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 107d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root if (o instanceof OpenSSLDSAPublicKey) { 108d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root OpenSSLDSAPublicKey other = (OpenSSLDSAPublicKey) o; 109d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 110d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root /* 111d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root * We can shortcut the true case, but it still may be equivalent but 112d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root * different copies. 113d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root */ 114d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root if (key.equals(other.getOpenSSLKey())) { 115d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return true; 116d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 117d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 118d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 119d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root if (!(o instanceof DSAPublicKey)) { 120d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return false; 121d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 122d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 123d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root ensureReadParams(); 124d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 125d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root DSAPublicKey other = (DSAPublicKey) o; 126d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return params.getY().equals(other.getY()) && params.equals(other.getParams()); 127d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 128d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 129d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root @Override 130d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root public int hashCode() { 131d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root ensureReadParams(); 132d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 133d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return params.getY().hashCode() ^ params.hashCode(); 134d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 135d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 136d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root @Override 137d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root public String toString() { 138d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root ensureReadParams(); 139d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 140d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root final StringBuilder sb = new StringBuilder("OpenSSLDSAPublicKey{"); 141d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append("Y="); 142d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append(params.getY().toString(16)); 143d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append(','); 144d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append("params="); 145d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append(params.toString()); 146d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root sb.append('}'); 147d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root 148d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root return sb.toString(); 149d036721c2ecd146acef9f36408c7a397dd0a0785Kenny Root } 150746a236e2be5dee62c482e27f4c682496d071d8bKenny Root} 151