OpenSSLDSAPrivateKey.java revision 908975092f7ac7b7562f242c5fd99fbf228acf0f
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.DSAPrivateKey; 23import java.security.spec.DSAPrivateKeySpec; 24import java.security.spec.InvalidKeySpecException; 25 26public class OpenSSLDSAPrivateKey implements DSAPrivateKey { 27 private static final long serialVersionUID = 6524734576187424628L; 28 29 private final OpenSSLKey key; 30 31 private OpenSSLDSAParams params; 32 33 OpenSSLDSAPrivateKey(OpenSSLKey key) { 34 this.key = key; 35 } 36 37 OpenSSLKey getOpenSSLKey() { 38 return key; 39 } 40 41 OpenSSLDSAPrivateKey(DSAPrivateKeySpec 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 null, 48 dsaKeySpec.getX().toByteArray())); 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(DSAPrivateKey dsaPrivateKey) throws InvalidKeyException { 61 try { 62 DSAParams dsaParams = dsaPrivateKey.getParams(); 63 return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 64 dsaParams.getP().toByteArray(), 65 dsaParams.getQ().toByteArray(), 66 dsaParams.getG().toByteArray(), 67 null, 68 dsaPrivateKey.getX().toByteArray())); 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 /* 88 * If we're using an OpenSSL ENGINE, there's no guarantee we can export 89 * the key. Returning {@code null} tells the caller that there's no 90 * encoded format. 91 */ 92 if (key.isEngineBased()) { 93 return null; 94 } 95 96 return "PKCS#8"; 97 } 98 99 @Override 100 public byte[] getEncoded() { 101 /* 102 * If we're using an OpenSSL ENGINE, there's no guarantee we can export 103 * the key. Returning {@code null} tells the caller that there's no 104 * encoded format. 105 */ 106 if (key.isEngineBased()) { 107 return null; 108 } 109 110 return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext()); 111 } 112 113 @Override 114 public BigInteger getX() { 115 ensureReadParams(); 116 return params.getX(); 117 } 118 119 public int getPkeyContext() { 120 return key.getPkeyContext(); 121 } 122 123 @Override 124 public boolean equals(Object o) { 125 if (o == this) { 126 return true; 127 } 128 129 if (o instanceof OpenSSLDSAPrivateKey) { 130 OpenSSLDSAPrivateKey other = (OpenSSLDSAPrivateKey) o; 131 132 /* 133 * We can shortcut the true case, but it still may be equivalent but 134 * different copies. 135 */ 136 if (key.equals(other.getOpenSSLKey())) { 137 return true; 138 } 139 } 140 141 if (!(o instanceof DSAPrivateKey)) { 142 return false; 143 } 144 145 ensureReadParams(); 146 147 final BigInteger x = params.getX(); 148 if (x == null) { 149 /* 150 * If our X is null, we can't tell if these two private keys are 151 * equivalent. This usually happens if this key is ENGINE-based. If 152 * the other key was ENGINE-based, we should have caught it in the 153 * OpenSSLDSAPrivateKey case. 154 */ 155 return false; 156 } 157 158 final DSAPrivateKey other = (DSAPrivateKey) o; 159 return x.equals(other.getX()) && params.equals(other.getParams()); 160 } 161 162 @Override 163 public int hashCode() { 164 ensureReadParams(); 165 166 int hash = 1; 167 168 final BigInteger x = getX(); 169 if (x != null) { 170 hash = hash * 3 + x.hashCode(); 171 } 172 173 hash = hash * 7 + params.hashCode(); 174 175 return hash; 176 } 177 178 @Override 179 public String toString() { 180 final StringBuilder sb = new StringBuilder("OpenSSLDSAPrivateKey{"); 181 182 if (key.isEngineBased()) { 183 sb.append("key="); 184 sb.append(key); 185 sb.append('}'); 186 return sb.toString(); 187 } 188 189 ensureReadParams(); 190 sb.append("X="); 191 sb.append(params.getX().toString(16)); 192 sb.append(','); 193 sb.append("params="); 194 sb.append(params.toString()); 195 sb.append('}'); 196 197 return sb.toString(); 198 } 199} 200