116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.jcajce.provider.asymmetric.dh; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.IOException; 416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.ObjectInputStream; 516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.ObjectOutputStream; 616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.math.BigInteger; 716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.interfaces.DHPublicKey; 916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.DHParameterSpec; 1016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.DHPublicKeySpec; 1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.ASN1Integer; 1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.ASN1Sequence; 1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.pkcs.DHParameter; 1616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 1716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.x509.AlgorithmIdentifier; 1816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 19bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giroimport org.bouncycastle.asn1.x9.DomainParameters; 204caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport org.bouncycastle.asn1.x9.ValidationParams; 2116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.asn1.x9.X9ObjectIdentifiers; 224caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport org.bouncycastle.crypto.params.DHParameters; 2316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DHPublicKeyParameters; 244caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giroimport org.bouncycastle.crypto.params.DHValidationParameters; 2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; 2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic class BCDHPublicKey 2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro implements DHPublicKey 2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 3016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final long serialVersionUID = -216691575254424324L; 3116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private BigInteger y; 3316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 344caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro private transient DHPublicKeyParameters dhPublicKey; 3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private transient DHParameterSpec dhSpec; 3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private transient SubjectPublicKeyInfo info; 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCDHPublicKey( 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPublicKeySpec spec) 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.y = spec.getY(); 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG()); 434caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG())); 4416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 4516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 4616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCDHPublicKey( 4716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPublicKey key) 4816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 4916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.y = key.getY(); 5016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = key.getParams(); 514caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG())); 5216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 5316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 5416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCDHPublicKey( 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPublicKeyParameters params) 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.y = params.getY(); 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL()); 594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = params; 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCDHPublicKey( 6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BigInteger y, 6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHParameterSpec dhSpec) 6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 6616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.y = y; 6716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = dhSpec; 684caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG())); 6916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public BCDHPublicKey( 7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro SubjectPublicKeyInfo info) 7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.info = info; 7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ASN1Integer derY; 7716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro try 7816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro derY = (ASN1Integer)info.parsePublicKey(); 8016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro catch (IOException e) 8216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 8316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalArgumentException("invalid info structure in DH public key"); 8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 8516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 8616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.y = derY.getValue(); 8716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ASN1Sequence seq = ASN1Sequence.getInstance(info.getAlgorithm().getParameters()); 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ASN1ObjectIdentifier id = info.getAlgorithm().getAlgorithm(); 9016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // we need the PKCS check to handle older keys marked with the X9 oid. 9216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (id.equals(PKCSObjectIdentifiers.dhKeyAgreement) || isPKCSParam(seq)) 9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHParameter params = DHParameter.getInstance(seq); 9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (params.getL() != null) 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = new DHParameterSpec(params.getP(), params.getG(), params.getL().intValue()); 9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 1044caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG())); 10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 10616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (id.equals(X9ObjectIdentifiers.dhpublicnumber)) 10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 108bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro DomainParameters params = DomainParameters.getInstance(seq); 10916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 110bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro this.dhSpec = new DHParameterSpec(params.getP(), params.getG()); 1114caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro ValidationParams validationParams = params.getValidationParams(); 1124caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro if (validationParams != null) 1134caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 1144caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), 1154caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro new DHValidationParameters(validationParams.getSeed(), validationParams.getPgenCounter().intValue()))); 1164caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 1174caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro else 1184caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 1194caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), null)); 1204caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 12116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 12216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 12316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 12416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalArgumentException("unknown algorithm type: " + id); 12516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 12616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 12716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 12816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public String getAlgorithm() 12916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return "DH"; 13116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 13216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 13316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public String getFormat() 13416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 13516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return "X.509"; 13616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 13716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 13816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public byte[] getEncoded() 13916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 14016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (info != null) 14116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 14216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return KeyUtil.getEncodedSubjectPublicKeyInfo(info); 14316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 14516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(dhSpec.getP(), dhSpec.getG(), dhSpec.getL()).toASN1Primitive()), new ASN1Integer(y)); 14616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 14816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public DHParameterSpec getParams() 14916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 15016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return dhSpec; 15116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 15216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 15316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public BigInteger getY() 15416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 15516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return y; 15616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 15716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1584caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro public DHPublicKeyParameters engineGetKeyParameters() 1594caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro { 1604caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro return dhPublicKey; 1614caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro } 1624caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro 16316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private boolean isPKCSParam(ASN1Sequence seq) 16416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 16516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (seq.size() == 2) 16616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 16716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return true; 16816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 16916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 17016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (seq.size() > 3) 17116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 17216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return false; 17316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 17416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 17516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ASN1Integer l = ASN1Integer.getInstance(seq.getObjectAt(2)); 17616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(0)); 17716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 17816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (l.getValue().compareTo(BigInteger.valueOf(p.getValue().bitLength())) > 0) 17916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 18016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return false; 18116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 18216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 18316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return true; 18416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 18516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 18616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public int hashCode() 18716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 18816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return this.getY().hashCode() ^ this.getParams().getG().hashCode() 18916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ^ this.getParams().getP().hashCode() ^ this.getParams().getL(); 19016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 19116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public boolean equals( 19316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro Object o) 19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 19516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (!(o instanceof DHPublicKey)) 19616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 19716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return false; 19816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 19916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DHPublicKey other = (DHPublicKey)o; 20116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return this.getY().equals(other.getY()) 20316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro && this.getParams().getG().equals(other.getParams().getG()) 20416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro && this.getParams().getP().equals(other.getParams().getP()) 20516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro && this.getParams().getL() == other.getParams().getL(); 20616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 20716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private void readObject( 20916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ObjectInputStream in) 21016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException, ClassNotFoundException 21116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 21216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro in.defaultReadObject(); 21316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 21416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.dhSpec = new DHParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), in.readInt()); 21516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro this.info = null; 21616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 21716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 21816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private void writeObject( 21916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro ObjectOutputStream out) 22016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throws IOException 22116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 22216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro out.defaultWriteObject(); 22316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 22416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro out.writeObject(dhSpec.getP()); 22516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro out.writeObject(dhSpec.getG()); 22616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro out.writeInt(dhSpec.getL()); 22716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 22816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 229