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 17package org.apache.harmony.xnet.provider.jsse; 18 19import java.math.BigInteger; 20import java.security.InvalidKeyException; 21import java.security.interfaces.DSAParams; 22import java.security.interfaces.DSAPublicKey; 23import java.security.spec.DSAPublicKeySpec; 24import java.security.spec.InvalidKeySpecException; 25 26public class OpenSSLDSAPublicKey implements DSAPublicKey { 27 private static final long serialVersionUID = 5238609500353792232L; 28 29 private final OpenSSLKey key; 30 31 private OpenSSLDSAParams params; 32 33 OpenSSLDSAPublicKey(OpenSSLKey key) { 34 this.key = key; 35 } 36 37 OpenSSLKey getOpenSSLKey() { 38 return key; 39 } 40 41 OpenSSLDSAPublicKey(DSAPublicKeySpec dsaKeySpec) throws InvalidKeySpecException { 42 try { 43 key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 44 dsaKeySpec.getP().toByteArray(), 45 dsaKeySpec.getQ().toByteArray(), 46 dsaKeySpec.getG().toByteArray(), 47 dsaKeySpec.getY().toByteArray(), 48 null)); 49 } catch (Exception e) { 50 throw new InvalidKeySpecException(e); 51 } 52 } 53 54 private void ensureReadParams() { 55 if (params == null) { 56 params = new OpenSSLDSAParams(key); 57 } 58 } 59 60 static OpenSSLKey getInstance(DSAPublicKey dsaPublicKey) throws InvalidKeyException { 61 try { 62 final DSAParams dsaParams = dsaPublicKey.getParams(); 63 return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 64 dsaParams.getP().toByteArray(), 65 dsaParams.getQ().toByteArray(), 66 dsaParams.getG().toByteArray(), 67 dsaPublicKey.getY().toByteArray(), 68 null)); 69 } catch (Exception e) { 70 throw new InvalidKeyException(e); 71 } 72 } 73 74 @Override 75 public DSAParams getParams() { 76 ensureReadParams(); 77 return params; 78 } 79 80 @Override 81 public String getAlgorithm() { 82 return "DSA"; 83 } 84 85 @Override 86 public String getFormat() { 87 return "X.509"; 88 } 89 90 @Override 91 public byte[] getEncoded() { 92 return NativeCrypto.i2d_PUBKEY(key.getPkeyContext()); 93 } 94 95 @Override 96 public BigInteger getY() { 97 ensureReadParams(); 98 return params.getY(); 99 } 100 101 @Override 102 public boolean equals(Object o) { 103 if (o == this) { 104 return true; 105 } 106 107 if (o instanceof OpenSSLDSAPublicKey) { 108 OpenSSLDSAPublicKey other = (OpenSSLDSAPublicKey) o; 109 110 /* 111 * We can shortcut the true case, but it still may be equivalent but 112 * different copies. 113 */ 114 if (key.equals(other.getOpenSSLKey())) { 115 return true; 116 } 117 } 118 119 if (!(o instanceof DSAPublicKey)) { 120 return false; 121 } 122 123 ensureReadParams(); 124 125 DSAPublicKey other = (DSAPublicKey) o; 126 return params.getY().equals(other.getY()) && params.equals(other.getParams()); 127 } 128 129 @Override 130 public int hashCode() { 131 ensureReadParams(); 132 133 return params.getY().hashCode() ^ params.hashCode(); 134 } 135 136 @Override 137 public String toString() { 138 ensureReadParams(); 139 140 final StringBuilder sb = new StringBuilder("OpenSSLDSAPublicKey{"); 141 sb.append("Y="); 142 sb.append(params.getY().toString(16)); 143 sb.append(','); 144 sb.append("params="); 145 sb.append(params.toString()); 146 sb.append('}'); 147 148 return sb.toString(); 149 } 150} 151