Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java
38922 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.crypto.provider;2627import java.io.*;28import java.util.Objects;29import java.math.BigInteger;30import java.security.KeyRep;31import java.security.PrivateKey;32import java.security.InvalidKeyException;33import java.security.ProviderException;34import javax.crypto.spec.DHParameterSpec;35import sun.security.util.*;3637/**38* A private key in PKCS#8 format for the Diffie-Hellman key agreement39* algorithm.40*41* @author Jan Luehe42*43*44* @see DHPublicKey45* @see java.security.KeyAgreement46*/47final class DHPrivateKey implements PrivateKey,48javax.crypto.interfaces.DHPrivateKey, Serializable {4950static final long serialVersionUID = 7565477590005668886L;5152// only supported version of PKCS#8 PrivateKeyInfo53private static final BigInteger PKCS8_VERSION = BigInteger.ZERO;5455// the private key56private BigInteger x;5758// the key bytes, without the algorithm information59private byte[] key;6061// the encoded key62private byte[] encodedKey;6364// the prime modulus65private BigInteger p;6667// the base generator68private BigInteger g;6970// the private-value length (optional)71private int l;7273private int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 };7475/**76* Make a DH private key out of a private value <code>x</code>, a prime77* modulus <code>p</code>, and a base generator <code>g</code>.78*79* @param x the private value80* @param p the prime modulus81* @param g the base generator82*83* @exception ProviderException if the key cannot be encoded84*/85DHPrivateKey(BigInteger x, BigInteger p, BigInteger g)86throws InvalidKeyException {87this(x, p, g, 0);88}8990/**91* Make a DH private key out of a private value <code>x</code>, a prime92* modulus <code>p</code>, a base generator <code>g</code>, and a93* private-value length <code>l</code>.94*95* @param x the private value96* @param p the prime modulus97* @param g the base generator98* @param l the private-value length99*100* @exception InvalidKeyException if the key cannot be encoded101*/102DHPrivateKey(BigInteger x, BigInteger p, BigInteger g, int l) {103this.x = x;104this.p = p;105this.g = g;106this.l = l;107try {108this.key = new DerValue(DerValue.tag_Integer,109this.x.toByteArray()).toByteArray();110this.encodedKey = getEncoded();111} catch (IOException e) {112throw new ProviderException("Cannot produce ASN.1 encoding", e);113}114}115116/**117* Make a DH private key from its DER encoding (PKCS #8).118*119* @param encodedKey the encoded key120*121* @exception InvalidKeyException if the encoded key does not represent122* a Diffie-Hellman private key123*/124DHPrivateKey(byte[] encodedKey) throws InvalidKeyException {125InputStream inStream = new ByteArrayInputStream(encodedKey);126try {127DerValue val = new DerValue(inStream);128if (val.tag != DerValue.tag_Sequence) {129throw new InvalidKeyException ("Key not a SEQUENCE");130}131132//133// version134//135BigInteger parsedVersion = val.data.getBigInteger();136if (!parsedVersion.equals(PKCS8_VERSION)) {137throw new IOException("version mismatch: (supported: " +138PKCS8_VERSION + ", parsed: " +139parsedVersion);140}141142//143// privateKeyAlgorithm144//145DerValue algid = val.data.getDerValue();146if (algid.tag != DerValue.tag_Sequence) {147throw new InvalidKeyException("AlgId is not a SEQUENCE");148}149DerInputStream derInStream = algid.toDerInputStream();150ObjectIdentifier oid = derInStream.getOID();151if (oid == null) {152throw new InvalidKeyException("Null OID");153}154if (derInStream.available() == 0) {155throw new InvalidKeyException("Parameters missing");156}157// parse the parameters158DerValue params = derInStream.getDerValue();159if (params.tag == DerValue.tag_Null) {160throw new InvalidKeyException("Null parameters");161}162if (params.tag != DerValue.tag_Sequence) {163throw new InvalidKeyException("Parameters not a SEQUENCE");164}165params.data.reset();166this.p = params.data.getBigInteger();167this.g = params.data.getBigInteger();168// Private-value length is OPTIONAL169if (params.data.available() != 0) {170this.l = params.data.getInteger();171}172if (params.data.available() != 0) {173throw new InvalidKeyException("Extra parameter data");174}175176//177// privateKey178//179this.key = val.data.getOctetString();180parseKeyBits();181182this.encodedKey = encodedKey.clone();183} catch (IOException | NumberFormatException e) {184throw new InvalidKeyException("Error parsing key encoding", e);185}186}187188/**189* Returns the encoding format of this key: "PKCS#8"190*/191public String getFormat() {192return "PKCS#8";193}194195/**196* Returns the name of the algorithm associated with this key: "DH"197*/198public String getAlgorithm() {199return "DH";200}201202/**203* Get the encoding of the key.204*/205public synchronized byte[] getEncoded() {206if (this.encodedKey == null) {207try {208DerOutputStream tmp = new DerOutputStream();209210//211// version212//213tmp.putInteger(PKCS8_VERSION);214215//216// privateKeyAlgorithm217//218DerOutputStream algid = new DerOutputStream();219220// store OID221algid.putOID(new ObjectIdentifier(DH_data));222// encode parameters223DerOutputStream params = new DerOutputStream();224params.putInteger(this.p);225params.putInteger(this.g);226if (this.l != 0) {227params.putInteger(this.l);228}229// wrap parameters into SEQUENCE230DerValue paramSequence = new DerValue(DerValue.tag_Sequence,231params.toByteArray());232// store parameter SEQUENCE in algid233algid.putDerValue(paramSequence);234// wrap algid into SEQUENCE235tmp.write(DerValue.tag_Sequence, algid);236237// privateKey238tmp.putOctetString(this.key);239240// make it a SEQUENCE241DerOutputStream derKey = new DerOutputStream();242derKey.write(DerValue.tag_Sequence, tmp);243this.encodedKey = derKey.toByteArray();244} catch (IOException e) {245return null;246}247}248return this.encodedKey.clone();249}250251/**252* Returns the private value, <code>x</code>.253*254* @return the private value, <code>x</code>255*/256public BigInteger getX() {257return this.x;258}259260/**261* Returns the key parameters.262*263* @return the key parameters264*/265public DHParameterSpec getParams() {266if (this.l != 0) {267return new DHParameterSpec(this.p, this.g, this.l);268} else {269return new DHParameterSpec(this.p, this.g);270}271}272273private void parseKeyBits() throws InvalidKeyException {274try {275DerInputStream in = new DerInputStream(this.key);276this.x = in.getBigInteger();277} catch (IOException e) {278InvalidKeyException ike = new InvalidKeyException(279"Error parsing key encoding: " + e.getMessage());280ike.initCause(e);281throw ike;282}283}284285/**286* Calculates a hash code value for the object.287* Objects that are equal will also have the same hashcode.288*/289public int hashCode() {290return Objects.hash(x, p, g);291}292293public boolean equals(Object obj) {294if (this == obj) return true;295296if (!(obj instanceof javax.crypto.interfaces.DHPrivateKey)) {297return false;298}299javax.crypto.interfaces.DHPrivateKey other =300(javax.crypto.interfaces.DHPrivateKey) obj;301DHParameterSpec otherParams = other.getParams();302return ((this.x.compareTo(other.getX()) == 0) &&303(this.p.compareTo(otherParams.getP()) == 0) &&304(this.g.compareTo(otherParams.getG()) == 0));305}306307/**308* Replace the DH private key to be serialized.309*310* @return the standard KeyRep object to be serialized311*312* @throws java.io.ObjectStreamException if a new object representing313* this DH private key could not be created314*/315private Object writeReplace() throws java.io.ObjectStreamException {316return new KeyRep(KeyRep.Type.PRIVATE,317getAlgorithm(),318getFormat(),319getEncoded());320}321}322323324