1aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root/* 2aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * Copyright (C) 2012 The Android Open Source Project 3aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * 4aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * you may not use this file except in compliance with the License. 6aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * You may obtain a copy of the License at 7aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * 8aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * http://www.apache.org/licenses/LICENSE-2.0 9aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * 10aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * Unless required by applicable law or agreed to in writing, software 11aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * See the License for the specific language governing permissions and 14aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root * limitations under the License. 15aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root */ 16aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 17860d2707ce126ef8f66e3eac7ceeab6d24218cd8Kenny Rootpackage org.conscrypt; 18aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 19aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Rootimport java.io.IOException; 20aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Rootimport java.io.NotSerializableException; 21aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Rootimport java.io.ObjectInputStream; 22aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Rootimport java.io.ObjectOutputStream; 23aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.math.BigInteger; 24aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.security.InvalidKeyException; 25aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.security.interfaces.DSAParams; 26aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.security.interfaces.DSAPrivateKey; 27aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.security.spec.DSAPrivateKeySpec; 28aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Rootimport java.security.spec.InvalidKeySpecException; 29aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 3047cc520bd63c1eabfdef23cbab10457701f2a395Kenny Rootpublic class OpenSSLDSAPrivateKey implements DSAPrivateKey, OpenSSLKeyHolder { 31c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root private static final long serialVersionUID = 6524734576187424628L; 32c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 33aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root private transient OpenSSLKey key; 34aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 35aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root private transient OpenSSLDSAParams params; 36aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 37aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root OpenSSLDSAPrivateKey(OpenSSLKey key) { 38aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root this.key = key; 39aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 40aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 4147cc520bd63c1eabfdef23cbab10457701f2a395Kenny Root @Override 4247cc520bd63c1eabfdef23cbab10457701f2a395Kenny Root public OpenSSLKey getOpenSSLKey() { 439df6cea08a4eb527ba5b6fc9275e8b0571c12892Kenny Root return key; 449df6cea08a4eb527ba5b6fc9275e8b0571c12892Kenny Root } 459df6cea08a4eb527ba5b6fc9275e8b0571c12892Kenny Root 46aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root OpenSSLDSAPrivateKey(DSAPrivateKeySpec dsaKeySpec) throws InvalidKeySpecException { 47aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root try { 48aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 49aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaKeySpec.getP().toByteArray(), 50aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaKeySpec.getQ().toByteArray(), 51aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaKeySpec.getG().toByteArray(), 52aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root null, 53aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaKeySpec.getX().toByteArray())); 54aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } catch (Exception e) { 55aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root throw new InvalidKeySpecException(e); 56aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 57aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 58aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 59aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root private void ensureReadParams() { 60aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root if (params == null) { 61aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root params = new OpenSSLDSAParams(key); 62aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 63aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 64aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 65aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root static OpenSSLKey getInstance(DSAPrivateKey dsaPrivateKey) throws InvalidKeyException { 66f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root /** 67f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root * If the key is not encodable (PKCS11-like key), then wrap it and use 68f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root * JNI upcalls to satisfy requests. 69f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root */ 70f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root if (dsaPrivateKey.getFormat() == null) { 71f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root return wrapPlatformKey(dsaPrivateKey); 72f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root } 73f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root 74aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root try { 75aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root DSAParams dsaParams = dsaPrivateKey.getParams(); 76aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 77aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaParams.getP().toByteArray(), 78aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaParams.getQ().toByteArray(), 79aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaParams.getG().toByteArray(), 80aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root null, 81aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root dsaPrivateKey.getX().toByteArray())); 82aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } catch (Exception e) { 83aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root throw new InvalidKeyException(e); 84aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 85aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 86aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 87f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root public static OpenSSLKey wrapPlatformKey(DSAPrivateKey dsaPrivateKey) { 88dac92c69d3a147ea57bc7bd28c96b6365c1988e2Kenny Root return new OpenSSLKey(NativeCrypto.getDSAPrivateKeyWrapper(dsaPrivateKey), true); 89f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root } 90f24ba0620d88b7d71ddb089b97d29fb1b073718dKenny Root 91aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root @Override 92aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root public DSAParams getParams() { 93aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root ensureReadParams(); 94aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return params; 95aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 96aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 97aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root @Override 98aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root public String getAlgorithm() { 99aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return "DSA"; 100aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 101aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 102aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root @Override 103aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root public String getFormat() { 104a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root /* 105a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * If we're using an OpenSSL ENGINE, there's no guarantee we can export 106a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * the key. Returning {@code null} tells the caller that there's no 107a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * encoded format. 108a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root */ 109b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root if (key.isEngineBased()) { 110a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root return null; 111a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root } 112a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root 113aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return "PKCS#8"; 114aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 115aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 116aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root @Override 117aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root public byte[] getEncoded() { 118a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root /* 119a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * If we're using an OpenSSL ENGINE, there's no guarantee we can export 120a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * the key. Returning {@code null} tells the caller that there's no 121a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root * encoded format. 122a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root */ 123b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root if (key.isEngineBased()) { 124a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root return null; 125a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root } 126a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root 127aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return NativeCrypto.i2d_PKCS8_PRIV_KEY_INFO(key.getPkeyContext()); 128aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 129aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root 130aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root @Override 131aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root public BigInteger getX() { 132f42ec17cfa43a002814e901d63ae8a93d77f7fc3Kenny Root if (key.isEngineBased()) { 133f42ec17cfa43a002814e901d63ae8a93d77f7fc3Kenny Root throw new UnsupportedOperationException("private key value X cannot be extracted"); 134f42ec17cfa43a002814e901d63ae8a93d77f7fc3Kenny Root } 135f42ec17cfa43a002814e901d63ae8a93d77f7fc3Kenny Root 136aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root ensureReadParams(); 137aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root return params.getX(); 138aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root } 139c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 140c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root @Override 141c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root public boolean equals(Object o) { 142c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root if (o == this) { 143c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root return true; 144c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 145c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 146c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root if (o instanceof OpenSSLDSAPrivateKey) { 147c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root OpenSSLDSAPrivateKey other = (OpenSSLDSAPrivateKey) o; 148c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 149c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root /* 150c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root * We can shortcut the true case, but it still may be equivalent but 151c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root * different copies. 152c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root */ 153c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root if (key.equals(other.getOpenSSLKey())) { 154c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root return true; 155c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 156c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 157c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 158c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root if (!(o instanceof DSAPrivateKey)) { 159c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root return false; 160c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 161c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 162c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root ensureReadParams(); 163c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 164b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root final BigInteger x = params.getX(); 165b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root if (x == null) { 166b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root /* 167b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root * If our X is null, we can't tell if these two private keys are 168b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root * equivalent. This usually happens if this key is ENGINE-based. If 169b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root * the other key was ENGINE-based, we should have caught it in the 170b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root * OpenSSLDSAPrivateKey case. 171b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root */ 172b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root return false; 173b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root } 174b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root 175b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root final DSAPrivateKey other = (DSAPrivateKey) o; 176b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root return x.equals(other.getX()) && params.equals(other.getParams()); 177c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 178c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 179c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root @Override 180c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root public int hashCode() { 181c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root ensureReadParams(); 182c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 183b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root int hash = 1; 184b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root 185b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root final BigInteger x = getX(); 186b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root if (x != null) { 187b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root hash = hash * 3 + x.hashCode(); 188b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root } 189b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root 190b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root hash = hash * 7 + params.hashCode(); 191b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root 192b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root return hash; 193c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 194c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 195c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root @Override 196c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root public String toString() { 197c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root final StringBuilder sb = new StringBuilder("OpenSSLDSAPrivateKey{"); 198a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root 199b4fa75e1c6216696157135b6103eedb75f772f14Kenny Root if (key.isEngineBased()) { 200a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root sb.append("key="); 201a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root sb.append(key); 202a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root sb.append('}'); 203a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root return sb.toString(); 204a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root } 205a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root 206a590ec8553482f097f10c5cb6dfaa4d44bdda1a0Kenny Root ensureReadParams(); 207c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append("X="); 208c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append(params.getX().toString(16)); 209c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append(','); 210c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append("params="); 211c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append(params.toString()); 212c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root sb.append('}'); 213c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root 214c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root return sb.toString(); 215c43ab99bd48be940dde4c8ee74155e0482cd1599Kenny Root } 216aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root 217aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 218aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.defaultReadObject(); 219aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root 220aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root final BigInteger g = (BigInteger) stream.readObject(); 221aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root final BigInteger p = (BigInteger) stream.readObject(); 222aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root final BigInteger q = (BigInteger) stream.readObject(); 223aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root final BigInteger x = (BigInteger) stream.readObject(); 224aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root 225aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root key = new OpenSSLKey(NativeCrypto.EVP_PKEY_new_DSA( 226aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root p.toByteArray(), 227aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root q.toByteArray(), 228aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root g.toByteArray(), 229aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root null, 230aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root x.toByteArray())); 231aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root } 232aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root 233aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root private void writeObject(ObjectOutputStream stream) throws IOException { 234aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root if (getOpenSSLKey().isEngineBased()) { 235aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root throw new NotSerializableException("engine-based keys can not be serialized"); 236aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root } 237f42ec17cfa43a002814e901d63ae8a93d77f7fc3Kenny Root 238aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.defaultWriteObject(); 239aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root 240aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root ensureReadParams(); 241aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.writeObject(params.getG()); 242aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.writeObject(params.getP()); 243aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.writeObject(params.getQ()); 244aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root stream.writeObject(params.getX()); 245aceaabe71de0da877be36f5bfb88c7111f81fc3eKenny Root } 246aa48fdb4d42bc5de668f11055f88fb430fdf4d61Kenny Root} 247