0N/A/*
2362N/A * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.x509;
0N/A
0N/Aimport java.io.IOException;
0N/Aimport java.math.BigInteger;
0N/Aimport java.security.*;
0N/Aimport java.security.interfaces.DSAParams;
0N/A
0N/Aimport sun.security.util.*;
0N/A
0N/A
0N/A/**
0N/A * This class identifies DSS/DSA Algorithm variants, which are distinguished
0N/A * by using different algorithm parameters <em>P, Q, G</em>. It uses the
0N/A * NIST/IETF standard DER encoding. These are used to implement the Digital
0N/A * Signature Standard (DSS), FIPS 186.
0N/A *
0N/A * <P><em><b>NOTE:</b> DSS/DSA Algorithm IDs may be created without these
0N/A * parameters. Use of DSS/DSA in modes where parameters are
0N/A * either implicit (e.g. a default applicable to a site or a larger scope),
0N/A * or are derived from some Certificate Authority's DSS certificate, is
0N/A * not supported directly. The application is responsible for creating a key
0N/A * containing the required parameters prior to using the key in cryptographic
0N/A * operations. The follwoing is an example of how this may be done assuming
0N/A * that we have a certificate called <code>currentCert</code> which doesn't
0N/A * contain DSS/DSA parameters and we need to derive DSS/DSA parameters
0N/A * from a CA's certificate called <code>caCert</code>.
0N/A * <p>
0N/A * <code><pre>
0N/A * // key containing parameters to use
0N/A * DSAPublicKey cAKey = (DSAPublicKey)(caCert.getPublicKey());
0N/A * // key without parameters
0N/A * DSAPublicKey nullParamsKey = (DSAPublicKey)(currentCert.getPublicKey());
0N/A *
0N/A * DSAParams cAKeyParams = cAKey.getParams();
0N/A * KeyFactory kf = KeyFactory.getInstance("DSA");
0N/A * DSAPublicKeySpec ks = new DSAPublicKeySpec(nullParamsKey.getY(),
0N/A * cAKeyParams.getP(),
0N/A * cAKeyParams.getQ(),
0N/A * cAKeyParams.getG());
0N/A * DSAPublicKey usableKey = kf.generatePublic(ks);
0N/A * </pre></code>
0N/A *
0N/A * @see java.security.interfaces.DSAParams
0N/A * @see java.security.interfaces.DSAPublicKey
0N/A * @see java.security.KeyFactory
0N/A * @see java.security.spec.DSAPublicKeySpec
0N/A *
0N/A * @author David Brownell
0N/A */
0N/Apublic final
0N/Aclass AlgIdDSA extends AlgorithmId implements DSAParams
0N/A{
0N/A
0N/A private static final long serialVersionUID = 3437177836797504046L;
0N/A
0N/A /*
0N/A * The three unsigned integer parameters.
0N/A */
0N/A private BigInteger p , q, g;
0N/A
0N/A /** Returns the DSS/DSA parameter "P" */
0N/A public BigInteger getP () { return p; }
0N/A
0N/A /** Returns the DSS/DSA parameter "Q" */
0N/A public BigInteger getQ () { return q; }
0N/A
0N/A /** Returns the DSS/DSA parameter "G" */
0N/A public BigInteger getG () { return g; }
0N/A
0N/A /**
0N/A * Default constructor. The OID and parameters must be
0N/A * deserialized before this algorithm ID is used.
0N/A */
0N/A // XXX deprecated for general use
0N/A public AlgIdDSA () {}
0N/A
0N/A AlgIdDSA (DerValue val) throws IOException
0N/A { super(val.getOID()); }
0N/A
0N/A /**
0N/A * Construct an AlgIdDSA from an X.509 encoded byte array.
0N/A */
0N/A public AlgIdDSA (byte[] encodedAlg) throws IOException
0N/A { super (new DerValue(encodedAlg).getOID()); }
0N/A
0N/A /**
0N/A * Constructs a DSS/DSA Algorithm ID from unsigned integers that
0N/A * define the algorithm parameters. Those integers are encoded
0N/A * as big-endian byte arrays.
0N/A *
0N/A * @param p the DSS/DSA paramter "P"
0N/A * @param q the DSS/DSA paramter "Q"
0N/A * @param g the DSS/DSA paramter "G"
0N/A */
0N/A public AlgIdDSA (byte p [], byte q [], byte g [])
0N/A throws IOException
0N/A {
0N/A this (new BigInteger (1, p),
0N/A new BigInteger (1, q),
0N/A new BigInteger (1, g));
0N/A }
0N/A
0N/A /**
0N/A * Constructs a DSS/DSA Algorithm ID from numeric parameters.
0N/A * If all three are null, then the parameters portion of the algorithm id
0N/A * is set to null. See note in header regarding use.
0N/A *
0N/A * @param p the DSS/DSA paramter "P"
0N/A * @param q the DSS/DSA paramter "Q"
0N/A * @param g the DSS/DSA paramter "G"
0N/A */
0N/A public AlgIdDSA (BigInteger p, BigInteger q, BigInteger g)
0N/A {
0N/A super (DSA_oid);
0N/A
0N/A if (p != null || q != null || g != null) {
0N/A if (p == null || q == null || g == null)
0N/A throw new ProviderException("Invalid parameters for DSS/DSA" +
0N/A " Algorithm ID");
0N/A try {
0N/A this.p = p;
0N/A this.q = q;
0N/A this.g = g;
0N/A initializeParams ();
0N/A
0N/A } catch (IOException e) {
0N/A /* this should not happen */
0N/A throw new ProviderException ("Construct DSS/DSA Algorithm ID");
0N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns "DSA", indicating the Digital Signature Algorithm (DSA) as
0N/A * defined by the Digital Signature Standard (DSS), FIPS 186.
0N/A */
0N/A public String getName ()
0N/A { return "DSA"; }
0N/A
0N/A
0N/A /*
0N/A * For algorithm IDs which haven't been created from a DER encoded
0N/A * value, "params" must be created.
0N/A */
0N/A private void initializeParams ()
0N/A throws IOException
0N/A {
0N/A DerOutputStream out = new DerOutputStream ();
0N/A
0N/A out.putInteger(p);
0N/A out.putInteger(q);
0N/A out.putInteger(g);
0N/A params = new DerValue (DerValue.tag_Sequence,out.toByteArray ());
0N/A }
0N/A
0N/A /**
0N/A * Parses algorithm parameters P, Q, and G. They're found
0N/A * in the "params" member, which never needs to be changed.
0N/A */
0N/A protected void decodeParams ()
0N/A throws IOException
0N/A {
0N/A if (params == null)
0N/A throw new IOException("DSA alg params are null");
0N/A if (params.tag != DerValue.tag_Sequence)
0N/A throw new IOException("DSA alg parsing error");
0N/A
0N/A params.data.reset ();
0N/A
0N/A this.p = params.data.getBigInteger();
0N/A this.q = params.data.getBigInteger();
0N/A this.g = params.data.getBigInteger();
0N/A
0N/A if (params.data.available () != 0)
0N/A throw new IOException ("AlgIdDSA params, extra="+
0N/A params.data.available ());
0N/A }
0N/A
0N/A
0N/A /*
0N/A * Returns a formatted string describing the parameters.
0N/A */
0N/A public String toString ()
0N/A { return paramsToString (); }
0N/A
0N/A /*
0N/A * Returns a string describing the parameters.
0N/A */
0N/A protected String paramsToString ()
0N/A {
0N/A if (params == null)
0N/A return " null\n";
0N/A else
0N/A return
0N/A "\n p:\n" + Debug.toHexString(p) +
0N/A "\n q:\n" + Debug.toHexString(q) +
0N/A "\n g:\n" + Debug.toHexString(g) +
0N/A "\n";
0N/A }
0N/A}