feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
1356
jdkSrc/jdk8/sun/security/x509/AVA.java
Normal file
1356
jdkSrc/jdk8/sun/security/x509/AVA.java
Normal file
File diff suppressed because it is too large
Load Diff
118
jdkSrc/jdk8/sun/security/x509/AccessDescription.java
Normal file
118
jdkSrc/jdk8/sun/security/x509/AccessDescription.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* @author Ram Marti
|
||||
*/
|
||||
|
||||
public final class AccessDescription {
|
||||
|
||||
private int myhash = -1;
|
||||
|
||||
private ObjectIdentifier accessMethod;
|
||||
|
||||
private GeneralName accessLocation;
|
||||
|
||||
public static final ObjectIdentifier Ad_OCSP_Id =
|
||||
ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 1});
|
||||
|
||||
public static final ObjectIdentifier Ad_CAISSUERS_Id =
|
||||
ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 2});
|
||||
|
||||
public static final ObjectIdentifier Ad_TIMESTAMPING_Id =
|
||||
ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 3});
|
||||
|
||||
public static final ObjectIdentifier Ad_CAREPOSITORY_Id =
|
||||
ObjectIdentifier.newInternal(new int[] {1, 3, 6, 1, 5, 5, 7, 48, 5});
|
||||
|
||||
public AccessDescription(ObjectIdentifier accessMethod, GeneralName accessLocation) {
|
||||
this.accessMethod = accessMethod;
|
||||
this.accessLocation = accessLocation;
|
||||
}
|
||||
|
||||
public AccessDescription(DerValue derValue) throws IOException {
|
||||
DerInputStream derIn = derValue.getData();
|
||||
accessMethod = derIn.getOID();
|
||||
accessLocation = new GeneralName(derIn.getDerValue());
|
||||
}
|
||||
|
||||
public ObjectIdentifier getAccessMethod() {
|
||||
return accessMethod;
|
||||
}
|
||||
|
||||
public GeneralName getAccessLocation() {
|
||||
return accessLocation;
|
||||
}
|
||||
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putOID(accessMethod);
|
||||
accessLocation.encode(tmp);
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (myhash == -1) {
|
||||
myhash = accessMethod.hashCode() + accessLocation.hashCode();
|
||||
}
|
||||
return myhash;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || (!(obj instanceof AccessDescription))) {
|
||||
return false;
|
||||
}
|
||||
AccessDescription that = (AccessDescription)obj;
|
||||
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
return (accessMethod.equals((Object)that.getAccessMethod()) &&
|
||||
accessLocation.equals(that.getAccessLocation()));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String method = null;
|
||||
if (accessMethod.equals((Object)Ad_CAISSUERS_Id)) {
|
||||
method = "caIssuers";
|
||||
} else if (accessMethod.equals((Object)Ad_CAREPOSITORY_Id)) {
|
||||
method = "caRepository";
|
||||
} else if (accessMethod.equals((Object)Ad_TIMESTAMPING_Id)) {
|
||||
method = "timeStamping";
|
||||
} else if (accessMethod.equals((Object)Ad_OCSP_Id)) {
|
||||
method = "ocsp";
|
||||
} else {
|
||||
method = accessMethod.toString();
|
||||
}
|
||||
return ("\n accessMethod: " + method +
|
||||
"\n accessLocation: " + accessLocation.toString() + "\n");
|
||||
}
|
||||
}
|
||||
225
jdkSrc/jdk8/sun/security/x509/AlgIdDSA.java
Normal file
225
jdkSrc/jdk8/sun/security/x509/AlgIdDSA.java
Normal file
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.DSAParams;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class identifies DSS/DSA Algorithm variants, which are distinguished
|
||||
* by using different algorithm parameters <em>P, Q, G</em>. It uses the
|
||||
* NIST/IETF standard DER encoding. These are used to implement the Digital
|
||||
* Signature Standard (DSS), FIPS 186.
|
||||
*
|
||||
* <P><em><b>NOTE:</b> DSS/DSA Algorithm IDs may be created without these
|
||||
* parameters. Use of DSS/DSA in modes where parameters are
|
||||
* either implicit (e.g. a default applicable to a site or a larger scope),
|
||||
* or are derived from some Certificate Authority's DSS certificate, is
|
||||
* not supported directly. The application is responsible for creating a key
|
||||
* containing the required parameters prior to using the key in cryptographic
|
||||
* operations. The follwoing is an example of how this may be done assuming
|
||||
* that we have a certificate called <code>currentCert</code> which doesn't
|
||||
* contain DSS/DSA parameters and we need to derive DSS/DSA parameters
|
||||
* from a CA's certificate called <code>caCert</code>.
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* // key containing parameters to use
|
||||
* DSAPublicKey cAKey = (DSAPublicKey)(caCert.getPublicKey());
|
||||
* // key without parameters
|
||||
* DSAPublicKey nullParamsKey = (DSAPublicKey)(currentCert.getPublicKey());
|
||||
*
|
||||
* DSAParams cAKeyParams = cAKey.getParams();
|
||||
* KeyFactory kf = KeyFactory.getInstance("DSA");
|
||||
* DSAPublicKeySpec ks = new DSAPublicKeySpec(nullParamsKey.getY(),
|
||||
* cAKeyParams.getP(),
|
||||
* cAKeyParams.getQ(),
|
||||
* cAKeyParams.getG());
|
||||
* DSAPublicKey usableKey = kf.generatePublic(ks);
|
||||
* </pre></code>
|
||||
*
|
||||
* @see java.security.interfaces.DSAParams
|
||||
* @see java.security.interfaces.DSAPublicKey
|
||||
* @see java.security.KeyFactory
|
||||
* @see java.security.spec.DSAPublicKeySpec
|
||||
*
|
||||
* @author David Brownell
|
||||
*/
|
||||
public final
|
||||
class AlgIdDSA extends AlgorithmId implements DSAParams
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 3437177836797504046L;
|
||||
|
||||
/*
|
||||
* The three unsigned integer parameters.
|
||||
*/
|
||||
private BigInteger p , q, g;
|
||||
|
||||
/** Returns the DSS/DSA parameter "P" */
|
||||
public BigInteger getP () { return p; }
|
||||
|
||||
/** Returns the DSS/DSA parameter "Q" */
|
||||
public BigInteger getQ () { return q; }
|
||||
|
||||
/** Returns the DSS/DSA parameter "G" */
|
||||
public BigInteger getG () { return g; }
|
||||
|
||||
/**
|
||||
* Default constructor. The OID and parameters must be
|
||||
* deserialized before this algorithm ID is used.
|
||||
*/
|
||||
@Deprecated
|
||||
public AlgIdDSA () {}
|
||||
|
||||
AlgIdDSA (DerValue val) throws IOException
|
||||
{ super(val.getOID()); }
|
||||
|
||||
/**
|
||||
* Construct an AlgIdDSA from an X.509 encoded byte array.
|
||||
*/
|
||||
public AlgIdDSA (byte[] encodedAlg) throws IOException
|
||||
{ super (new DerValue(encodedAlg).getOID()); }
|
||||
|
||||
/**
|
||||
* Constructs a DSS/DSA Algorithm ID from unsigned integers that
|
||||
* define the algorithm parameters. Those integers are encoded
|
||||
* as big-endian byte arrays.
|
||||
*
|
||||
* @param p the DSS/DSA parameter "P"
|
||||
* @param q the DSS/DSA parameter "Q"
|
||||
* @param g the DSS/DSA parameter "G"
|
||||
*/
|
||||
public AlgIdDSA (byte p [], byte q [], byte g [])
|
||||
throws IOException
|
||||
{
|
||||
this (new BigInteger (1, p),
|
||||
new BigInteger (1, q),
|
||||
new BigInteger (1, g));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DSS/DSA Algorithm ID from numeric parameters.
|
||||
* If all three are null, then the parameters portion of the algorithm id
|
||||
* is set to null. See note in header regarding use.
|
||||
*
|
||||
* @param p the DSS/DSA parameter "P"
|
||||
* @param q the DSS/DSA parameter "Q"
|
||||
* @param g the DSS/DSA parameter "G"
|
||||
*/
|
||||
public AlgIdDSA (BigInteger p, BigInteger q, BigInteger g)
|
||||
{
|
||||
super (DSA_oid);
|
||||
|
||||
if (p != null || q != null || g != null) {
|
||||
if (p == null || q == null || g == null)
|
||||
throw new ProviderException("Invalid parameters for DSS/DSA" +
|
||||
" Algorithm ID");
|
||||
try {
|
||||
this.p = p;
|
||||
this.q = q;
|
||||
this.g = g;
|
||||
initializeParams ();
|
||||
|
||||
} catch (IOException e) {
|
||||
/* this should not happen */
|
||||
throw new ProviderException ("Construct DSS/DSA Algorithm ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "DSA", indicating the Digital Signature Algorithm (DSA) as
|
||||
* defined by the Digital Signature Standard (DSS), FIPS 186.
|
||||
*/
|
||||
public String getName ()
|
||||
{ return "DSA"; }
|
||||
|
||||
|
||||
/*
|
||||
* For algorithm IDs which haven't been created from a DER encoded
|
||||
* value, "params" must be created.
|
||||
*/
|
||||
private void initializeParams ()
|
||||
throws IOException
|
||||
{
|
||||
DerOutputStream out = new DerOutputStream ();
|
||||
|
||||
out.putInteger(p);
|
||||
out.putInteger(q);
|
||||
out.putInteger(g);
|
||||
params = new DerValue (DerValue.tag_Sequence,out.toByteArray ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses algorithm parameters P, Q, and G. They're found
|
||||
* in the "params" member, which never needs to be changed.
|
||||
*/
|
||||
protected void decodeParams ()
|
||||
throws IOException
|
||||
{
|
||||
if (params == null)
|
||||
throw new IOException("DSA alg params are null");
|
||||
if (params.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("DSA alg parsing error");
|
||||
|
||||
params.data.reset ();
|
||||
|
||||
this.p = params.data.getBigInteger();
|
||||
this.q = params.data.getBigInteger();
|
||||
this.g = params.data.getBigInteger();
|
||||
|
||||
if (params.data.available () != 0)
|
||||
throw new IOException ("AlgIdDSA params, extra="+
|
||||
params.data.available ());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a formatted string describing the parameters.
|
||||
*/
|
||||
public String toString ()
|
||||
{ return paramsToString (); }
|
||||
|
||||
/*
|
||||
* Returns a string describing the parameters.
|
||||
*/
|
||||
protected String paramsToString ()
|
||||
{
|
||||
if (params == null)
|
||||
return " null\n";
|
||||
else
|
||||
return
|
||||
"\n p:\n" + Debug.toHexString(p) +
|
||||
"\n q:\n" + Debug.toHexString(q) +
|
||||
"\n g:\n" + Debug.toHexString(g) +
|
||||
"\n";
|
||||
}
|
||||
}
|
||||
1158
jdkSrc/jdk8/sun/security/x509/AlgorithmId.java
Normal file
1158
jdkSrc/jdk8/sun/security/x509/AlgorithmId.java
Normal file
File diff suppressed because it is too large
Load Diff
49
jdkSrc/jdk8/sun/security/x509/AttributeNameEnumeration.java
Normal file
49
jdkSrc/jdk8/sun/security/x509/AttributeNameEnumeration.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* <p>This class provides the Enumeration implementation used
|
||||
* by all the X509 certificate attributes to return the attribute
|
||||
* names contained within them.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class AttributeNameEnumeration extends Vector<String> {
|
||||
|
||||
private static final long serialVersionUID = -6067440240757099134L;
|
||||
|
||||
/**
|
||||
* The default constructor for this class.
|
||||
*/
|
||||
public AttributeNameEnumeration() {
|
||||
super(4,2);
|
||||
}
|
||||
}
|
||||
241
jdkSrc/jdk8/sun/security/x509/AuthorityInfoAccessExtension.java
Normal file
241
jdkSrc/jdk8/sun/security/x509/AuthorityInfoAccessExtension.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* The Authority Information Access Extension (OID = 1.3.6.1.5.5.7.1.1).
|
||||
* <p>
|
||||
* The AIA extension identifies how to access CA information and services
|
||||
* for the certificate in which it appears. It enables CAs to issue their
|
||||
* certificates pre-configured with the URLs appropriate for contacting
|
||||
* services relevant to those certificates. For example, a CA may issue a
|
||||
* certificate that identifies the specific OCSP Responder to use when
|
||||
* performing on-line validation of that certificate.
|
||||
* <p>
|
||||
* This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
|
||||
* Internet X.509 PKI Certificate and Certificate Revocation List
|
||||
* (CRL) Profile</a>. The profile permits
|
||||
* the extension to be included in end-entity or CA certificates,
|
||||
* and it must be marked as non-critical. Its ASN.1 definition is as follows:
|
||||
* <pre>
|
||||
* id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
|
||||
*
|
||||
* AuthorityInfoAccessSyntax ::=
|
||||
* SEQUENCE SIZE (1..MAX) OF AccessDescription
|
||||
*
|
||||
* AccessDescription ::= SEQUENCE {
|
||||
* accessMethod OBJECT IDENTIFIER,
|
||||
* accessLocation GeneralName }
|
||||
* </pre>
|
||||
* <p>
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
|
||||
public class AuthorityInfoAccessExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.AuthorityInfoAccess";
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "AuthorityInfoAccess";
|
||||
public static final String DESCRIPTIONS = "descriptions";
|
||||
|
||||
/**
|
||||
* The List of AccessDescription objects.
|
||||
*/
|
||||
private List<AccessDescription> accessDescriptions;
|
||||
|
||||
/**
|
||||
* Create an AuthorityInfoAccessExtension from a List of
|
||||
* AccessDescription; the criticality is set to false.
|
||||
*
|
||||
* @param accessDescriptions the List of AccessDescription
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public AuthorityInfoAccessExtension(
|
||||
List<AccessDescription> accessDescriptions) throws IOException {
|
||||
this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
|
||||
this.critical = false;
|
||||
this.accessDescriptions = accessDescriptions;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value Array of DER encoded bytes of the actual value.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public AuthorityInfoAccessExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
if (!(value instanceof byte[])) {
|
||||
throw new IOException("Illegal argument type");
|
||||
}
|
||||
|
||||
extensionValue = (byte[])value;
|
||||
DerValue val = new DerValue(extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"AuthorityInfoAccessExtension.");
|
||||
}
|
||||
accessDescriptions = new ArrayList<AccessDescription>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
AccessDescription accessDescription = new AccessDescription(seq);
|
||||
accessDescriptions.add(accessDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of AccessDescription objects.
|
||||
*/
|
||||
public List<AccessDescription> getAccessDescriptions() {
|
||||
return accessDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.AuthInfoAccess_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with an instanceof check
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
if (!(obj instanceof List)) {
|
||||
throw new IOException("Attribute value should be of type List.");
|
||||
}
|
||||
accessDescriptions = (List<AccessDescription>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:AuthorityInfoAccessExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public List<AccessDescription> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
return accessDescriptions;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:AuthorityInfoAccessExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
accessDescriptions = new ArrayList<AccessDescription>();
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:AuthorityInfoAccessExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DESCRIPTIONS);
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (accessDescriptions.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
} else {
|
||||
DerOutputStream ads = new DerOutputStream();
|
||||
for (AccessDescription accessDescription : accessDescriptions) {
|
||||
accessDescription.encode(ads);
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, ads);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + "AuthorityInfoAccess [\n "
|
||||
+ accessDescriptions + "\n]\n";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class represents the Authority Key Identifier Extension.
|
||||
*
|
||||
* <p>The authority key identifier extension provides a means of
|
||||
* identifying the particular public key used to sign a certificate.
|
||||
* This extension would be used where an issuer has multiple signing
|
||||
* keys (either due to multiple concurrent key pairs or due to
|
||||
* changeover).
|
||||
* <p>
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
* keyIdentifier [0] KeyIdentifier OPTIONAL,
|
||||
* authorityCertIssuer [1] GeneralNames OPTIONAL,
|
||||
* authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
|
||||
* }
|
||||
* KeyIdentifier ::= OCTET STRING
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class AuthorityKeyIdentifierExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.AuthorityKeyIdentifier";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "AuthorityKeyIdentifier";
|
||||
public static final String KEY_ID = "key_id";
|
||||
public static final String AUTH_NAME = "auth_name";
|
||||
public static final String SERIAL_NUMBER = "serial_number";
|
||||
|
||||
// Private data members
|
||||
private static final byte TAG_ID = 0;
|
||||
private static final byte TAG_NAMES = 1;
|
||||
private static final byte TAG_SERIAL_NUM = 2;
|
||||
|
||||
private KeyIdentifier id = null;
|
||||
private GeneralNames names = null;
|
||||
private SerialNumber serialNum = null;
|
||||
|
||||
// Encode only the extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (id == null && names == null && serialNum == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (id != null) {
|
||||
DerOutputStream tmp1 = new DerOutputStream();
|
||||
id.encode(tmp1);
|
||||
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_ID), tmp1);
|
||||
}
|
||||
try {
|
||||
if (names != null) {
|
||||
DerOutputStream tmp1 = new DerOutputStream();
|
||||
names.encode(tmp1);
|
||||
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, TAG_NAMES), tmp1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e.toString());
|
||||
}
|
||||
if (serialNum != null) {
|
||||
DerOutputStream tmp1 = new DerOutputStream();
|
||||
serialNum.encode(tmp1);
|
||||
tmp.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_SERIAL_NUM), tmp1);
|
||||
}
|
||||
seq.write(DerValue.tag_Sequence, tmp);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this extension. Null parameters make
|
||||
* the element optional (not present).
|
||||
*
|
||||
* @param id the KeyIdentifier associated with this extension.
|
||||
* @param names the GeneralNames associated with this extension
|
||||
* @param serialNum the CertificateSerialNumber associated with
|
||||
* this extension.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public AuthorityKeyIdentifierExtension(KeyIdentifier kid, GeneralNames name,
|
||||
SerialNumber sn)
|
||||
throws IOException {
|
||||
this.id = kid;
|
||||
this.names = name;
|
||||
this.serialNum = sn;
|
||||
|
||||
this.extensionId = PKIXExtensions.AuthorityKey_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public AuthorityKeyIdentifierExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.AuthorityKey_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"AuthorityKeyIdentifierExtension.");
|
||||
}
|
||||
|
||||
// Note that all the fields in AuthorityKeyIdentifier are defined as
|
||||
// being OPTIONAL, i.e., there could be an empty SEQUENCE, resulting
|
||||
// in val.data being null.
|
||||
while ((val.data != null) && (val.data.available() != 0)) {
|
||||
DerValue opt = val.data.getDerValue();
|
||||
|
||||
// NB. this is always encoded with the IMPLICIT tag
|
||||
// The checks only make sense if we assume implicit tagging,
|
||||
// with explicit tagging the form is always constructed.
|
||||
if (opt.isContextSpecific(TAG_ID) && !opt.isConstructed()) {
|
||||
if (id != null)
|
||||
throw new IOException("Duplicate KeyIdentifier in " +
|
||||
"AuthorityKeyIdentifier.");
|
||||
opt.resetTag(DerValue.tag_OctetString);
|
||||
id = new KeyIdentifier(opt);
|
||||
|
||||
} else if (opt.isContextSpecific(TAG_NAMES) &&
|
||||
opt.isConstructed()) {
|
||||
if (names != null)
|
||||
throw new IOException("Duplicate GeneralNames in " +
|
||||
"AuthorityKeyIdentifier.");
|
||||
opt.resetTag(DerValue.tag_Sequence);
|
||||
names = new GeneralNames(opt);
|
||||
|
||||
} else if (opt.isContextSpecific(TAG_SERIAL_NUM) &&
|
||||
!opt.isConstructed()) {
|
||||
if (serialNum != null)
|
||||
throw new IOException("Duplicate SerialNumber in " +
|
||||
"AuthorityKeyIdentifier.");
|
||||
opt.resetTag(DerValue.tag_Integer);
|
||||
serialNum = new SerialNumber(opt);
|
||||
} else
|
||||
throw new IOException("Invalid encoding of " +
|
||||
"AuthorityKeyIdentifierExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object as a string.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = super.toString() + "AuthorityKeyIdentifier [\n";
|
||||
if (id != null) {
|
||||
s += id.toString(); // id already has a newline
|
||||
}
|
||||
if (names != null) {
|
||||
s += names.toString() + "\n";
|
||||
}
|
||||
if (serialNum != null) {
|
||||
s += serialNum.toString() + "\n";
|
||||
}
|
||||
return (s + "]\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
extensionId = PKIXExtensions.AuthorityKey_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
if (!(obj instanceof KeyIdentifier)) {
|
||||
throw new IOException("Attribute value should be of " +
|
||||
"type KeyIdentifier.");
|
||||
}
|
||||
id = (KeyIdentifier)obj;
|
||||
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
|
||||
if (!(obj instanceof GeneralNames)) {
|
||||
throw new IOException("Attribute value should be of " +
|
||||
"type GeneralNames.");
|
||||
}
|
||||
names = (GeneralNames)obj;
|
||||
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
|
||||
if (!(obj instanceof SerialNumber)) {
|
||||
throw new IOException("Attribute value should be of " +
|
||||
"type SerialNumber.");
|
||||
}
|
||||
serialNum = (SerialNumber)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:AuthorityKeyIdentifier.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
return (id);
|
||||
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
|
||||
return (names);
|
||||
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
|
||||
return (serialNum);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:AuthorityKeyIdentifier.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
id = null;
|
||||
} else if (name.equalsIgnoreCase(AUTH_NAME)) {
|
||||
names = null;
|
||||
} else if (name.equalsIgnoreCase(SERIAL_NUMBER)) {
|
||||
serialNum = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:AuthorityKeyIdentifier.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(KEY_ID);
|
||||
elements.addElement(AUTH_NAME);
|
||||
elements.addElement(SERIAL_NUMBER);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the encoded key identifier, or null if not specified.
|
||||
*/
|
||||
public byte[] getEncodedKeyIdentifier() throws IOException {
|
||||
if (id != null) {
|
||||
DerOutputStream derOut = new DerOutputStream();
|
||||
id.encode(derOut);
|
||||
return derOut.toByteArray();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
274
jdkSrc/jdk8/sun/security/x509/BasicConstraintsExtension.java
Normal file
274
jdkSrc/jdk8/sun/security/x509/BasicConstraintsExtension.java
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class represents the Basic Constraints Extension.
|
||||
*
|
||||
* <p>The basic constraints extension identifies whether the subject of the
|
||||
* certificate is a CA and how deep a certification path may exist
|
||||
* through that CA.
|
||||
*
|
||||
* <pre>
|
||||
* The ASN.1 syntax for this extension is:
|
||||
* BasicConstraints ::= SEQUENCE {
|
||||
* cA BOOLEAN DEFAULT FALSE,
|
||||
* pathLenConstraint INTEGER (0..MAX) OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
* @see Extension
|
||||
*/
|
||||
public class BasicConstraintsExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.BasicConstraints";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "BasicConstraints";
|
||||
public static final String IS_CA = "is_ca";
|
||||
public static final String PATH_LEN = "path_len";
|
||||
|
||||
// Private data members
|
||||
private boolean ca = false;
|
||||
private int pathLen = -1;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (ca) {
|
||||
tmp.putBoolean(ca);
|
||||
// Only encode pathLen when ca == true
|
||||
if (pathLen >= 0) {
|
||||
tmp.putInteger(pathLen);
|
||||
}
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
this.extensionValue = out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for this object. The extension is marked
|
||||
* critical if the ca flag is true, false otherwise.
|
||||
*
|
||||
* @param ca true, if the subject of the Certificate is a CA.
|
||||
* @param len specifies the depth of the certification path.
|
||||
*/
|
||||
public BasicConstraintsExtension(boolean ca, int len) throws IOException {
|
||||
this(Boolean.valueOf(ca), ca, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for this object with specified criticality.
|
||||
*
|
||||
* @param critical true, if the extension should be marked critical
|
||||
* @param ca true, if the subject of the Certificate is a CA.
|
||||
* @param len specifies the depth of the certification path.
|
||||
*/
|
||||
public BasicConstraintsExtension(Boolean critical, boolean ca, int len)
|
||||
throws IOException {
|
||||
this.ca = ca;
|
||||
this.pathLen = len;
|
||||
this.extensionId = PKIXExtensions.BasicConstraints_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical flag indicating if extension is critical or not
|
||||
* @param value an array containing the DER encoded bytes of the extension.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public BasicConstraintsExtension(Boolean critical, Object value)
|
||||
throws IOException
|
||||
{
|
||||
this.extensionId = PKIXExtensions.BasicConstraints_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding of BasicConstraints");
|
||||
}
|
||||
|
||||
if (val.data == null || val.data.available() == 0) {
|
||||
// non-CA cert ("cA" field is FALSE by default), return -1
|
||||
return;
|
||||
}
|
||||
DerValue opt = val.data.getDerValue();
|
||||
if (opt.tag != DerValue.tag_Boolean) {
|
||||
// non-CA cert ("cA" field is FALSE by default), return -1
|
||||
return;
|
||||
}
|
||||
|
||||
this.ca = opt.getBoolean();
|
||||
if (val.data.available() == 0) {
|
||||
// From PKIX profile:
|
||||
// Where pathLenConstraint does not appear, there is no
|
||||
// limit to the allowed length of the certification path.
|
||||
this.pathLen = Integer.MAX_VALUE;
|
||||
return;
|
||||
}
|
||||
|
||||
opt = val.data.getDerValue();
|
||||
if (opt.tag != DerValue.tag_Integer) {
|
||||
throw new IOException("Invalid encoding of BasicConstraints");
|
||||
}
|
||||
this.pathLen = opt.getInteger();
|
||||
/*
|
||||
* Activate this check once again after PKIX profiling
|
||||
* is a standard and this check no longer imposes an
|
||||
* interoperability barrier.
|
||||
* if (ca) {
|
||||
* if (!this.critical) {
|
||||
* throw new IOException("Criticality cannot be false for CA.");
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user readable form of extension.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = super.toString() + "BasicConstraints:[\n";
|
||||
|
||||
s += ((ca) ? (" CA:true") : (" CA:false")) + "\n";
|
||||
if (pathLen >= 0) {
|
||||
s += " PathLen:" + pathLen + "\n";
|
||||
} else {
|
||||
s += " PathLen: undefined\n";
|
||||
}
|
||||
return (s + "]\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode this extension value to the output stream.
|
||||
*
|
||||
* @param out the DerOutputStream to encode the extension to.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.BasicConstraints_Id;
|
||||
if (ca) {
|
||||
critical = true;
|
||||
} else {
|
||||
critical = false;
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(IS_CA)) {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException("Attribute value should be of type Boolean.");
|
||||
}
|
||||
ca = ((Boolean)obj).booleanValue();
|
||||
} else if (name.equalsIgnoreCase(PATH_LEN)) {
|
||||
if (!(obj instanceof Integer)) {
|
||||
throw new IOException("Attribute value should be of type Integer.");
|
||||
}
|
||||
pathLen = ((Integer)obj).intValue();
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:BasicConstraints.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(IS_CA)) {
|
||||
return (Boolean.valueOf(ca));
|
||||
} else if (name.equalsIgnoreCase(PATH_LEN)) {
|
||||
return (Integer.valueOf(pathLen));
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:BasicConstraints.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(IS_CA)) {
|
||||
ca = false;
|
||||
} else if (name.equalsIgnoreCase(PATH_LEN)) {
|
||||
pathLen = -1;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:BasicConstraints.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(IS_CA);
|
||||
elements.addElement(PATH_LEN);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
|
||||
/**
|
||||
* Represent the CRL Distribution Points Extension (OID = 2.5.29.31).
|
||||
* <p>
|
||||
* The CRL distribution points extension identifies how CRL information
|
||||
* is obtained. The extension SHOULD be non-critical, but the PKIX profile
|
||||
* recommends support for this extension by CAs and applications.
|
||||
* <p>
|
||||
* For PKIX, if the cRLDistributionPoints extension contains a
|
||||
* DistributionPointName of type URI, the following semantics MUST be
|
||||
* assumed: the URI is a pointer to the current CRL for the associated
|
||||
* reasons and will be issued by the associated cRLIssuer. The
|
||||
* expected values for the URI conform to the following rules. The
|
||||
* name MUST be a non-relative URL, and MUST follow the URL syntax and
|
||||
* encoding rules specified in [RFC 1738]. The name must include both
|
||||
* a scheme (e.g., "http" or "ftp") and a scheme-specific-part. The
|
||||
* scheme- specific-part must include a fully qualified domain name or
|
||||
* IP address as the host. As specified in [RFC 1738], the scheme
|
||||
* name is not case-sensitive (e.g., "http" is equivalent to "HTTP").
|
||||
* The host part is also not case-sensitive, but other components of
|
||||
* the scheme-specific-part may be case-sensitive. When comparing
|
||||
* URIs, conforming implementations MUST compare the scheme and host
|
||||
* without regard to case, but assume the remainder of the
|
||||
* scheme-specific-part is case sensitive. Processing rules for other
|
||||
* values are not defined by this specification. If the
|
||||
* distributionPoint omits reasons, the CRL MUST include revocations
|
||||
* for all reasons. If the distributionPoint omits cRLIssuer, the CRL
|
||||
* MUST be issued by the CA that issued the certificate.
|
||||
* <p>
|
||||
* The ASN.1 definition for this is:
|
||||
* <pre>
|
||||
* id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 }
|
||||
*
|
||||
* cRLDistributionPoints ::= {
|
||||
* CRLDistPointsSyntax }
|
||||
*
|
||||
* CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||||
* </pre>
|
||||
* <p>
|
||||
* @author Anne Anderson
|
||||
* @author Andreas Sterbenz
|
||||
* @since 1.4.2
|
||||
* @see DistributionPoint
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CRLDistributionPointsExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.CRLDistributionPoints";
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "CRLDistributionPoints";
|
||||
public static final String POINTS = "points";
|
||||
|
||||
/**
|
||||
* The List of DistributionPoint objects.
|
||||
*/
|
||||
private List<DistributionPoint> distributionPoints;
|
||||
|
||||
private String extensionName;
|
||||
|
||||
/**
|
||||
* Create a CRLDistributionPointsExtension from a List of
|
||||
* DistributionPoint; the criticality is set to false.
|
||||
*
|
||||
* @param distributionPoints the list of distribution points
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public CRLDistributionPointsExtension(
|
||||
List<DistributionPoint> distributionPoints) throws IOException {
|
||||
|
||||
this(false, distributionPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CRLDistributionPointsExtension from a List of
|
||||
* DistributionPoint.
|
||||
*
|
||||
* @param isCritical the criticality setting.
|
||||
* @param distributionPoints the list of distribution points
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public CRLDistributionPointsExtension(boolean isCritical,
|
||||
List<DistributionPoint> distributionPoints) throws IOException {
|
||||
|
||||
this(PKIXExtensions.CRLDistributionPoints_Id, isCritical,
|
||||
distributionPoints, NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension (also called by the subclass).
|
||||
*/
|
||||
protected CRLDistributionPointsExtension(ObjectIdentifier extensionId,
|
||||
boolean isCritical, List<DistributionPoint> distributionPoints,
|
||||
String extensionName) throws IOException {
|
||||
|
||||
this.extensionId = extensionId;
|
||||
this.critical = isCritical;
|
||||
this.distributionPoints = distributionPoints;
|
||||
encodeThis();
|
||||
this.extensionName = extensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value Array of DER encoded bytes of the actual value.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public CRLDistributionPointsExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this(PKIXExtensions.CRLDistributionPoints_Id, critical, value, NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension (also called by the subclass).
|
||||
*/
|
||||
protected CRLDistributionPointsExtension(ObjectIdentifier extensionId,
|
||||
Boolean critical, Object value, String extensionName)
|
||||
throws IOException {
|
||||
|
||||
this.extensionId = extensionId;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
if (!(value instanceof byte[])) {
|
||||
throw new IOException("Illegal argument type");
|
||||
}
|
||||
|
||||
extensionValue = (byte[])value;
|
||||
DerValue val = new DerValue(extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " + extensionName +
|
||||
" extension.");
|
||||
}
|
||||
distributionPoints = new ArrayList<DistributionPoint>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
DistributionPoint point = new DistributionPoint(seq);
|
||||
distributionPoints.add(point);
|
||||
}
|
||||
this.extensionName = extensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return extensionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
encode(out, PKIXExtensions.CRLDistributionPoints_Id, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
* (Also called by the subclass)
|
||||
*/
|
||||
protected void encode(OutputStream out, ObjectIdentifier extensionId,
|
||||
boolean isCritical) throws IOException {
|
||||
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = extensionId;
|
||||
this.critical = isCritical;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with instanceof
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINTS)) {
|
||||
if (!(obj instanceof List)) {
|
||||
throw new IOException("Attribute value should be of type List.");
|
||||
}
|
||||
distributionPoints = (List<DistributionPoint>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:" + extensionName + ".");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public List<DistributionPoint> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINTS)) {
|
||||
return distributionPoints;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:" + extensionName + ".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINTS)) {
|
||||
distributionPoints =
|
||||
Collections.<DistributionPoint>emptyList();
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:" + extensionName + '.');
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(POINTS);
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (distributionPoints.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
} else {
|
||||
DerOutputStream pnts = new DerOutputStream();
|
||||
for (DistributionPoint point : distributionPoints) {
|
||||
point.encode(pnts);
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, pnts);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + extensionName + " [\n "
|
||||
+ distributionPoints + "]\n";
|
||||
}
|
||||
|
||||
}
|
||||
299
jdkSrc/jdk8/sun/security/x509/CRLExtensions.java
Normal file
299
jdkSrc/jdk8/sun/security/x509/CRLExtensions.java
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the CRL Extensions.
|
||||
* It is used for both CRL Extensions and CRL Entry Extensions,
|
||||
* which are defined are follows:
|
||||
* <pre>
|
||||
* TBSCertList ::= SEQUENCE {
|
||||
* version Version OPTIONAL, -- if present, must be v2
|
||||
* signature AlgorithmIdentifier,
|
||||
* issuer Name,
|
||||
* thisUpdate Time,
|
||||
* nextUpdate Time OPTIONAL,
|
||||
* revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
* userCertificate CertificateSerialNumber,
|
||||
* revocationDate Time,
|
||||
* crlEntryExtensions Extensions OPTIONAL -- if present, must be v2
|
||||
* } OPTIONAL,
|
||||
* crlExtensions [0] EXPLICIT Extensions OPTIONAL -- if present, must be v2
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class CRLExtensions {
|
||||
|
||||
private Map<String,Extension> map = Collections.synchronizedMap(
|
||||
new TreeMap<String,Extension>());
|
||||
private boolean unsupportedCritExt = false;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public CRLExtensions() { }
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the Extension from, i.e. the
|
||||
* sequence of extensions.
|
||||
* @exception CRLException on decoding errors.
|
||||
*/
|
||||
public CRLExtensions(DerInputStream in) throws CRLException {
|
||||
init(in);
|
||||
}
|
||||
|
||||
// helper routine
|
||||
private void init(DerInputStream derStrm) throws CRLException {
|
||||
try {
|
||||
DerInputStream str = derStrm;
|
||||
|
||||
byte nextByte = (byte)derStrm.peekByte();
|
||||
// check for context specific byte 0; skip it
|
||||
if (((nextByte & 0x0c0) == 0x080) &&
|
||||
((nextByte & 0x01f) == 0x000)) {
|
||||
DerValue val = str.getDerValue();
|
||||
str = val.data;
|
||||
}
|
||||
|
||||
DerValue[] exts = str.getSequence(5);
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
Extension ext = new Extension(exts[i]);
|
||||
parseExtension(ext);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CRLException("Parsing error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Class[] PARAMS = {Boolean.class, Object.class};
|
||||
|
||||
// Parse the encoded extension
|
||||
private void parseExtension(Extension ext) throws CRLException {
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
|
||||
if (extClass == null) { // Unsupported extension
|
||||
if (ext.isCritical())
|
||||
unsupportedCritExt = true;
|
||||
if (map.put(ext.getExtensionId().toString(), ext) != null)
|
||||
throw new CRLException("Duplicate extensions not allowed");
|
||||
return;
|
||||
}
|
||||
Constructor<?> cons = extClass.getConstructor(PARAMS);
|
||||
Object[] passed = new Object[] {Boolean.valueOf(ext.isCritical()),
|
||||
ext.getExtensionValue()};
|
||||
CertAttrSet<?> crlExt = (CertAttrSet<?>)cons.newInstance(passed);
|
||||
if (map.put(crlExt.getName(), (Extension)crlExt) != null) {
|
||||
throw new CRLException("Duplicate extensions not allowed");
|
||||
}
|
||||
} catch (InvocationTargetException invk) {
|
||||
throw new CRLException(invk.getTargetException().getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new CRLException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the extensions in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @param isExplicit the tag indicating whether this is an entry
|
||||
* extension (false) or a CRL extension (true).
|
||||
* @exception CRLException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out, boolean isExplicit)
|
||||
throws CRLException {
|
||||
try {
|
||||
DerOutputStream extOut = new DerOutputStream();
|
||||
Collection<Extension> allExts = map.values();
|
||||
Object[] objs = allExts.toArray();
|
||||
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
if (objs[i] instanceof CertAttrSet)
|
||||
((CertAttrSet)objs[i]).encode(extOut);
|
||||
else if (objs[i] instanceof Extension)
|
||||
((Extension)objs[i]).encode(extOut);
|
||||
else
|
||||
throw new CRLException("Illegal extension object");
|
||||
}
|
||||
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, extOut);
|
||||
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (isExplicit)
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)0), seq);
|
||||
else
|
||||
tmp = seq;
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new CRLException("Encoding error: " + e.toString());
|
||||
} catch (CertificateException e) {
|
||||
throw new CRLException("Encoding error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension with this alias.
|
||||
*
|
||||
* @param alias the identifier string for the extension to retrieve.
|
||||
*/
|
||||
public Extension get(String alias) {
|
||||
X509AttributeName attr = new X509AttributeName(alias);
|
||||
String name;
|
||||
String id = attr.getPrefix();
|
||||
if (id.equalsIgnoreCase(X509CertImpl.NAME)) { // fully qualified
|
||||
int index = alias.lastIndexOf(".");
|
||||
name = alias.substring(index + 1);
|
||||
} else
|
||||
name = alias;
|
||||
return map.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extension value with this alias.
|
||||
*
|
||||
* @param alias the identifier string for the extension to set.
|
||||
* @param obj the Object to set the extension identified by the
|
||||
* alias.
|
||||
*/
|
||||
public void set(String alias, Object obj) {
|
||||
map.put(alias, (Extension)obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the extension value with this alias.
|
||||
*
|
||||
* @param alias the identifier string for the extension to delete.
|
||||
*/
|
||||
public void delete(String alias) {
|
||||
map.remove(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of the extensions.
|
||||
* @return an enumeration of the extensions in this CRL.
|
||||
*/
|
||||
public Enumeration<Extension> getElements() {
|
||||
return Collections.enumeration(map.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection view of the extensions.
|
||||
* @return a collection view of the extensions in this CRL.
|
||||
*/
|
||||
public Collection<Extension> getAllExtensions() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a critical extension is found that is
|
||||
* not supported, otherwise return false.
|
||||
*/
|
||||
public boolean hasUnsupportedCriticalExtension() {
|
||||
return unsupportedCritExt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this CRLExtensions for equality with the specified
|
||||
* object. If the {@code other} object is an
|
||||
* {@code instanceof} {@code CRLExtensions}, then
|
||||
* all the entries are compared with the entries from this.
|
||||
*
|
||||
* @param other the object to test for equality with this CRLExtensions.
|
||||
* @return true iff all the entries match that of the Other,
|
||||
* false otherwise.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
if (!(other instanceof CRLExtensions))
|
||||
return false;
|
||||
Collection<Extension> otherC =
|
||||
((CRLExtensions)other).getAllExtensions();
|
||||
Object[] objs = otherC.toArray();
|
||||
|
||||
int len = objs.length;
|
||||
if (len != map.size())
|
||||
return false;
|
||||
|
||||
Extension otherExt, thisExt;
|
||||
String key = null;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (objs[i] instanceof CertAttrSet)
|
||||
key = ((CertAttrSet)objs[i]).getName();
|
||||
otherExt = (Extension)objs[i];
|
||||
if (key == null)
|
||||
key = otherExt.getExtensionId().toString();
|
||||
thisExt = map.get(key);
|
||||
if (thisExt == null)
|
||||
return false;
|
||||
if (! thisExt.equals(otherExt))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode value for this CRLExtensions.
|
||||
*
|
||||
* @return the hashcode value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return map.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this {@code CRLExtensions} object
|
||||
* in the form of a set of entries, enclosed in braces and separated
|
||||
* by the ASCII characters "{@code , }" (comma and space).
|
||||
* <p>Overrides to {@code toString} method of {@code Object}.
|
||||
*
|
||||
* @return a string representation of this CRLExtensions.
|
||||
*/
|
||||
public String toString() {
|
||||
return map.toString();
|
||||
}
|
||||
}
|
||||
235
jdkSrc/jdk8/sun/security/x509/CRLNumberExtension.java
Normal file
235
jdkSrc/jdk8/sun/security/x509/CRLNumberExtension.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the CRL Number Extension.
|
||||
*
|
||||
* <p>This extension, if present, conveys a monotonically increasing
|
||||
* sequence number for each CRL issued by a given CA through a specific
|
||||
* CA X.500 Directory entry or CRL distribution point. This extension
|
||||
* allows users to easily determine when a particular CRL supersedes
|
||||
* another CRL.
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CRLNumberExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "CRLNumber";
|
||||
public static final String NUMBER = "value";
|
||||
|
||||
private static final String LABEL = "CRL Number";
|
||||
|
||||
private BigInteger crlNumber = null;
|
||||
private String extensionName;
|
||||
private String extensionLabel;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (crlNumber == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
os.putInteger(this.crlNumber);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CRLNumberExtension with the integer value .
|
||||
* The criticality is set to false.
|
||||
*
|
||||
* @param crlNum the value to be set for the extension.
|
||||
*/
|
||||
public CRLNumberExtension(int crlNum) throws IOException {
|
||||
this(PKIXExtensions.CRLNumber_Id, false, BigInteger.valueOf(crlNum),
|
||||
NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CRLNumberExtension with the BigInteger value .
|
||||
* The criticality is set to false.
|
||||
*
|
||||
* @param crlNum the value to be set for the extension.
|
||||
*/
|
||||
public CRLNumberExtension(BigInteger crlNum) throws IOException {
|
||||
this(PKIXExtensions.CRLNumber_Id, false, crlNum, NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension (also called by the subclass).
|
||||
*/
|
||||
protected CRLNumberExtension(ObjectIdentifier extensionId,
|
||||
boolean isCritical, BigInteger crlNum, String extensionName,
|
||||
String extensionLabel) throws IOException {
|
||||
|
||||
this.extensionId = extensionId;
|
||||
this.critical = isCritical;
|
||||
this.crlNumber = crlNum;
|
||||
this.extensionName = extensionName;
|
||||
this.extensionLabel = extensionLabel;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public CRLNumberExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this(PKIXExtensions.CRLNumber_Id, critical, value, NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension (also called by the subclass).
|
||||
*/
|
||||
protected CRLNumberExtension(ObjectIdentifier extensionId,
|
||||
Boolean critical, Object value, String extensionName,
|
||||
String extensionLabel) throws IOException {
|
||||
|
||||
this.extensionId = extensionId;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.crlNumber = val.getBigInteger();
|
||||
this.extensionName = extensionName;
|
||||
this.extensionLabel = extensionLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
if (!(obj instanceof BigInteger)) {
|
||||
throw new IOException("Attribute must be of type BigInteger.");
|
||||
}
|
||||
crlNumber = (BigInteger)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:" + extensionName + ".");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public BigInteger get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
return crlNumber;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by" +
|
||||
" CertAttrSet:" + extensionName + '.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
crlNumber = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:" + extensionName + ".");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the CRLNumberExtension.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = super.toString() + extensionLabel + ": " +
|
||||
((crlNumber == null) ? "" : Debug.toHexString(crlNumber))
|
||||
+ "\n";
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
encode(out, PKIXExtensions.CRLNumber_Id, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
* (Also called by the subclass)
|
||||
*/
|
||||
protected void encode(OutputStream out, ObjectIdentifier extensionId,
|
||||
boolean isCritical) throws IOException {
|
||||
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = extensionId;
|
||||
this.critical = isCritical;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(NUMBER);
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (extensionName);
|
||||
}
|
||||
}
|
||||
202
jdkSrc/jdk8/sun/security/x509/CRLReasonCodeExtension.java
Normal file
202
jdkSrc/jdk8/sun/security/x509/CRLReasonCodeExtension.java
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.CRLReason;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* The reasonCode is a non-critical CRL entry extension that identifies
|
||||
* the reason for the certificate revocation.
|
||||
* @author Hemma Prafullchandra
|
||||
* @see java.security.cert.CRLReason
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CRLReasonCodeExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Attribute name
|
||||
*/
|
||||
public static final String NAME = "CRLReasonCode";
|
||||
public static final String REASON = "reason";
|
||||
|
||||
private static CRLReason[] values = CRLReason.values();
|
||||
|
||||
private int reasonCode = 0;
|
||||
|
||||
private void encodeThis() throws IOException {
|
||||
if (reasonCode == 0) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream dos = new DerOutputStream();
|
||||
dos.putEnumerated(reasonCode);
|
||||
this.extensionValue = dos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CRLReasonCodeExtension with the passed in reason.
|
||||
* Criticality automatically set to false.
|
||||
*
|
||||
* @param reason the enumerated value for the reason code.
|
||||
*/
|
||||
public CRLReasonCodeExtension(int reason) throws IOException {
|
||||
this(false, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CRLReasonCodeExtension with the passed in reason.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param reason the enumerated value for the reason code.
|
||||
*/
|
||||
public CRLReasonCodeExtension(boolean critical, int reason)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.ReasonCode_Id;
|
||||
this.critical = critical;
|
||||
this.reasonCode = reason;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public CRLReasonCodeExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.ReasonCode_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.reasonCode = val.getEnumerated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Integer)) {
|
||||
throw new IOException("Attribute must be of type Integer.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(REASON)) {
|
||||
reasonCode = ((Integer)obj).intValue();
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by CRLReasonCodeExtension");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Integer get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(REASON)) {
|
||||
return new Integer(reasonCode);
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by CRLReasonCodeExtension");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(REASON)) {
|
||||
reasonCode = 0;
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by CRLReasonCodeExtension");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the Reason code.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + " Reason Code: " + getReasonCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.ReasonCode_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(REASON);
|
||||
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reason as a CRLReason enum.
|
||||
*/
|
||||
public CRLReason getReasonCode() {
|
||||
// if out-of-range, return UNSPECIFIED
|
||||
if (reasonCode > 0 && reasonCode < values.length) {
|
||||
return values[reasonCode];
|
||||
} else {
|
||||
return CRLReason.UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
117
jdkSrc/jdk8/sun/security/x509/CertAttrSet.java
Normal file
117
jdkSrc/jdk8/sun/security/x509/CertAttrSet.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This interface defines the methods required of a certificate attribute.
|
||||
* Examples of X.509 certificate attributes are Validity, Issuer_Name, and
|
||||
* Subject Name. A CertAttrSet may comprise one attribute or many
|
||||
* attributes.
|
||||
* <p>
|
||||
* A CertAttrSet itself can also be comprised of other sub-sets.
|
||||
* In the case of X.509 V3 certificates, for example, the "extensions"
|
||||
* attribute has subattributes, such as those for KeyUsage and
|
||||
* AuthorityKeyIdentifier.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertificateException
|
||||
*/
|
||||
public interface CertAttrSet<T> {
|
||||
/**
|
||||
* Returns a short string describing this certificate attribute.
|
||||
*
|
||||
* @return value of this certificate attribute in
|
||||
* printable form.
|
||||
*/
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* Encodes the attribute to the output stream in a format
|
||||
* that can be parsed by the <code>decode</code> method.
|
||||
*
|
||||
* @param out the OutputStream to encode the attribute to.
|
||||
*
|
||||
* @exception CertificateException on encoding or validity errors.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
void encode(OutputStream out)
|
||||
throws CertificateException, IOException;
|
||||
|
||||
/**
|
||||
* Sets an attribute value within this CertAttrSet.
|
||||
*
|
||||
* @param name the name of the attribute (e.g. "x509.info.key")
|
||||
* @param obj the attribute object.
|
||||
*
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
void set(String name, Object obj)
|
||||
throws CertificateException, IOException;
|
||||
|
||||
/**
|
||||
* Gets an attribute value for this CertAttrSet.
|
||||
*
|
||||
* @param name the name of the attribute to return.
|
||||
*
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
Object get(String name)
|
||||
throws CertificateException, IOException;
|
||||
|
||||
/**
|
||||
* Deletes an attribute value from this CertAttrSet.
|
||||
*
|
||||
* @param name the name of the attribute to delete.
|
||||
*
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
void delete(String name)
|
||||
throws CertificateException, IOException;
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the names of the attributes existing within
|
||||
* this attribute.
|
||||
*
|
||||
* @return an enumeration of the attribute names.
|
||||
*/
|
||||
Enumeration<T> getElements();
|
||||
|
||||
/**
|
||||
* Returns the name (identifier) of this CertAttrSet.
|
||||
*
|
||||
* @return the name of this CertAttrSet.
|
||||
*/
|
||||
String getName();
|
||||
}
|
||||
173
jdkSrc/jdk8/sun/security/x509/CertException.java
Normal file
173
jdkSrc/jdk8/sun/security/x509/CertException.java
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
/**
|
||||
* CertException indicates one of a variety of certificate problems.
|
||||
*
|
||||
* @deprecated use one of Exceptions defined in the java.security.cert
|
||||
* package.
|
||||
*
|
||||
* @see java.security.Certificate
|
||||
*
|
||||
*
|
||||
* @author David Brownell
|
||||
*/
|
||||
@Deprecated
|
||||
public class CertException extends SecurityException {
|
||||
|
||||
private static final long serialVersionUID = 6930793039696446142L;
|
||||
|
||||
// Zero is reserved.
|
||||
|
||||
/** Indicates that the signature in the certificate is not valid. */
|
||||
public static final int verf_INVALID_SIG = 1;
|
||||
|
||||
/** Indicates that the certificate was revoked, and so is invalid. */
|
||||
public static final int verf_INVALID_REVOKED = 2;
|
||||
|
||||
/** Indicates that the certificate is not yet valid. */
|
||||
public static final int verf_INVALID_NOTBEFORE = 3;
|
||||
|
||||
/** Indicates that the certificate has expired and so is not valid. */
|
||||
public static final int verf_INVALID_EXPIRED = 4;
|
||||
|
||||
/** Indicates that a certificate authority in the certification
|
||||
* chain is not trusted. */
|
||||
public static final int verf_CA_UNTRUSTED = 5;
|
||||
|
||||
/** Indicates that the certification chain is too long. */
|
||||
public static final int verf_CHAIN_LENGTH = 6;
|
||||
|
||||
/** Indicates an error parsing the ASN.1/DER encoding of the certificate. */
|
||||
public static final int verf_PARSE_ERROR = 7;
|
||||
|
||||
/** Indicates an error constructing a certificate or certificate chain. */
|
||||
public static final int err_CONSTRUCTION = 8;
|
||||
|
||||
/** Indicates a problem with the public key */
|
||||
public static final int err_INVALID_PUBLIC_KEY = 9;
|
||||
|
||||
/** Indicates a problem with the certificate version */
|
||||
public static final int err_INVALID_VERSION = 10;
|
||||
|
||||
/** Indicates a problem with the certificate format */
|
||||
public static final int err_INVALID_FORMAT = 11;
|
||||
|
||||
/** Indicates a problem with the certificate encoding */
|
||||
public static final int err_ENCODING = 12;
|
||||
|
||||
// Private data members
|
||||
private int verfCode;
|
||||
private String moreData;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a certificate exception using an error code
|
||||
* (<code>verf_*</code>) and a string describing the context
|
||||
* of the error.
|
||||
*/
|
||||
public CertException(int code, String moredata)
|
||||
{
|
||||
verfCode = code;
|
||||
moreData = moredata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a certificate exception using just an error code,
|
||||
* without a string describing the context.
|
||||
*/
|
||||
public CertException(int code)
|
||||
{
|
||||
verfCode = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code with which the exception was created.
|
||||
*/
|
||||
public int getVerfCode() { return verfCode; }
|
||||
|
||||
/**
|
||||
* Returns a string describing the context in which the exception
|
||||
* was reported.
|
||||
*/
|
||||
public String getMoreData() { return moreData; }
|
||||
|
||||
/**
|
||||
* Return a string corresponding to the error code used to create
|
||||
* this exception.
|
||||
*/
|
||||
public String getVerfDescription()
|
||||
{
|
||||
switch (verfCode) {
|
||||
case verf_INVALID_SIG:
|
||||
return "The signature in the certificate is not valid.";
|
||||
case verf_INVALID_REVOKED:
|
||||
return "The certificate has been revoked.";
|
||||
case verf_INVALID_NOTBEFORE:
|
||||
return "The certificate is not yet valid.";
|
||||
case verf_INVALID_EXPIRED:
|
||||
return "The certificate has expired.";
|
||||
case verf_CA_UNTRUSTED:
|
||||
return "The Authority which issued the certificate is not trusted.";
|
||||
case verf_CHAIN_LENGTH:
|
||||
return "The certificate path to a trusted authority is too long.";
|
||||
case verf_PARSE_ERROR:
|
||||
return "The certificate could not be parsed.";
|
||||
case err_CONSTRUCTION:
|
||||
return "There was an error when constructing the certificate.";
|
||||
case err_INVALID_PUBLIC_KEY:
|
||||
return "The public key was not in the correct format.";
|
||||
case err_INVALID_VERSION:
|
||||
return "The certificate has an invalid version number.";
|
||||
case err_INVALID_FORMAT:
|
||||
return "The certificate has an invalid format.";
|
||||
case err_ENCODING:
|
||||
return "Problem encountered while encoding the data.";
|
||||
|
||||
default:
|
||||
return "Unknown code: " + verfCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the certificate exception.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "[Certificate Exception: " + getMessage() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the certificate exception.
|
||||
*/
|
||||
public String getMessage()
|
||||
{
|
||||
return getVerfDescription()
|
||||
+ ( (moreData != null)
|
||||
? ( "\n (" + moreData + ")" ) : "" );
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/sun/security/x509/CertParseError.java
Normal file
44
jdkSrc/jdk8/sun/security/x509/CertParseError.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
/**
|
||||
* CertException indicates one of a variety of certificate problems.
|
||||
* @deprecated use one of the Exceptions defined in the
|
||||
* java.security.cert package.
|
||||
*
|
||||
* @author David Brownell
|
||||
*/
|
||||
@Deprecated
|
||||
class CertParseError extends CertException
|
||||
{
|
||||
private static final long serialVersionUID = -4559645519017017804L;
|
||||
|
||||
CertParseError (String where)
|
||||
{
|
||||
super (CertException.verf_PARSE_ERROR, where);
|
||||
}
|
||||
}
|
||||
170
jdkSrc/jdk8/sun/security/x509/CertificateAlgorithmId.java
Normal file
170
jdkSrc/jdk8/sun/security/x509/CertificateAlgorithmId.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the AlgorithmId for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class CertificateAlgorithmId implements CertAttrSet<String> {
|
||||
private AlgorithmId algId;
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.algorithmID";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "algorithmID";
|
||||
|
||||
/**
|
||||
* Identifier to be used with get, set, and delete methods. When
|
||||
* using this identifier the associated object being passed in or
|
||||
* returned is an instance of AlgorithmId.
|
||||
* @see sun.security.x509.AlgorithmId
|
||||
*/
|
||||
public static final String ALGORITHM = "algorithm";
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param algId the Algorithm identifier
|
||||
*/
|
||||
public CertificateAlgorithmId(AlgorithmId algId) {
|
||||
this.algId = algId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the serial number from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateAlgorithmId(DerInputStream in) throws IOException {
|
||||
DerValue val = in.getDerValue();
|
||||
algId = AlgorithmId.parse(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the serial number from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateAlgorithmId(InputStream in) throws IOException {
|
||||
DerValue val = new DerValue(in);
|
||||
algId = AlgorithmId.parse(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the algorithm identifier as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (algId == null) return "";
|
||||
return (algId.toString() +
|
||||
", OID = " + (algId.getOID()).toString() + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the algorithm identifier in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
algId.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof AlgorithmId)) {
|
||||
throw new IOException("Attribute must be of type AlgorithmId.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(ALGORITHM)) {
|
||||
algId = (AlgorithmId)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateAlgorithmId.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public AlgorithmId get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ALGORITHM)) {
|
||||
return (algId);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateAlgorithmId.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ALGORITHM)) {
|
||||
algId = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateAlgorithmId.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(ALGORITHM);
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
382
jdkSrc/jdk8/sun/security/x509/CertificateExtensions.java
Normal file
382
jdkSrc/jdk8/sun/security/x509/CertificateExtensions.java
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.*;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the Extensions attribute for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateExtensions implements CertAttrSet<Extension> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions";
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
public static final String NAME = "extensions";
|
||||
|
||||
private static final Debug debug = Debug.getInstance("x509");
|
||||
|
||||
private Map<String,Extension> map = Collections.synchronizedMap(
|
||||
new TreeMap<String,Extension>());
|
||||
private boolean unsupportedCritExt = false;
|
||||
|
||||
private Map<String,Extension> unparseableExtensions;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public CertificateExtensions() { }
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the Extension from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateExtensions(DerInputStream in) throws IOException {
|
||||
init(in);
|
||||
}
|
||||
|
||||
// helper routine
|
||||
private void init(DerInputStream in) throws IOException {
|
||||
|
||||
DerValue[] exts = in.getSequence(5);
|
||||
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
Extension ext = new Extension(exts[i]);
|
||||
parseExtension(ext);
|
||||
}
|
||||
}
|
||||
|
||||
private static Class[] PARAMS = {Boolean.class, Object.class};
|
||||
|
||||
// Parse the encoded extension
|
||||
private void parseExtension(Extension ext) throws IOException {
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
|
||||
if (extClass == null) { // Unsupported extension
|
||||
if (ext.isCritical()) {
|
||||
unsupportedCritExt = true;
|
||||
}
|
||||
if (map.put(ext.getExtensionId().toString(), ext) == null) {
|
||||
return;
|
||||
} else {
|
||||
throw new IOException("Duplicate extensions not allowed");
|
||||
}
|
||||
}
|
||||
Constructor<?> cons = extClass.getConstructor(PARAMS);
|
||||
|
||||
Object[] passed = new Object[] {Boolean.valueOf(ext.isCritical()),
|
||||
ext.getExtensionValue()};
|
||||
CertAttrSet<?> certExt = (CertAttrSet<?>)
|
||||
cons.newInstance(passed);
|
||||
if (map.put(certExt.getName(), (Extension)certExt) != null) {
|
||||
throw new IOException("Duplicate extensions not allowed");
|
||||
}
|
||||
} catch (InvocationTargetException invk) {
|
||||
Throwable e = invk.getTargetException();
|
||||
if (ext.isCritical() == false) {
|
||||
// ignore errors parsing non-critical extensions
|
||||
if (unparseableExtensions == null) {
|
||||
unparseableExtensions = new TreeMap<String,Extension>();
|
||||
}
|
||||
unparseableExtensions.put(ext.getExtensionId().toString(),
|
||||
new UnparseableExtension(ext, e));
|
||||
if (debug != null) {
|
||||
debug.println("Debug info only." +
|
||||
" Error parsing extension: " + ext);
|
||||
e.printStackTrace();
|
||||
HexDumpEncoder h = new HexDumpEncoder();
|
||||
System.err.println(h.encodeBuffer(ext.getExtensionValue()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (e instanceof IOException) {
|
||||
throw (IOException)e;
|
||||
} else {
|
||||
throw new IOException(e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the extensions in DER form to the stream, setting
|
||||
* the context specific tag as needed in the X.509 v3 certificate.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception CertificateException on encoding errors.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out)
|
||||
throws CertificateException, IOException {
|
||||
encode(out, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the extensions in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @param isCertReq if true then no context specific tag is added.
|
||||
* @exception CertificateException on encoding errors.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out, boolean isCertReq)
|
||||
throws CertificateException, IOException {
|
||||
DerOutputStream extOut = new DerOutputStream();
|
||||
Collection<Extension> allExts = map.values();
|
||||
Object[] objs = allExts.toArray();
|
||||
|
||||
for (int i = 0; i < objs.length; i++) {
|
||||
if (objs[i] instanceof CertAttrSet)
|
||||
((CertAttrSet)objs[i]).encode(extOut);
|
||||
else if (objs[i] instanceof Extension)
|
||||
((Extension)objs[i]).encode(extOut);
|
||||
else
|
||||
throw new CertificateException("Illegal extension object");
|
||||
}
|
||||
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, extOut);
|
||||
|
||||
DerOutputStream tmp;
|
||||
if (!isCertReq) { // certificate
|
||||
tmp = new DerOutputStream();
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)3),
|
||||
seq);
|
||||
} else
|
||||
tmp = seq; // pkcs#10 certificateRequest
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
* @param name the extension name used in the cache.
|
||||
* @param obj the object to set.
|
||||
* @exception IOException if the object could not be cached.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (obj instanceof Extension) {
|
||||
map.put(name, (Extension)obj);
|
||||
} else {
|
||||
throw new IOException("Unknown extension type.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
* @param name the extension name used in the lookup.
|
||||
* @exception IOException if named extension is not found.
|
||||
*/
|
||||
public Extension get(String name) throws IOException {
|
||||
Extension obj = map.get(name);
|
||||
if (obj == null) {
|
||||
throw new IOException("No extension found with name " + name);
|
||||
}
|
||||
return (obj);
|
||||
}
|
||||
|
||||
// Similar to get(String), but throw no exception, might return null.
|
||||
// Used in X509CertImpl::getExtension(OID).
|
||||
Extension getExtension(String name) {
|
||||
return map.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
* @param name the extension name used in the lookup.
|
||||
* @exception IOException if named extension is not found.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
Object obj = map.get(name);
|
||||
if (obj == null) {
|
||||
throw new IOException("No extension found with name " + name);
|
||||
}
|
||||
map.remove(name);
|
||||
}
|
||||
|
||||
public String getNameByOid(ObjectIdentifier oid) throws IOException {
|
||||
for (String name: map.keySet()) {
|
||||
if (map.get(name).getExtensionId().equals((Object)oid)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<Extension> getElements() {
|
||||
return Collections.enumeration(map.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a collection view of the extensions.
|
||||
* @return a collection view of the extensions in this Certificate.
|
||||
*/
|
||||
public Collection<Extension> getAllExtensions() {
|
||||
return map.values();
|
||||
}
|
||||
|
||||
public Map<String,Extension> getUnparseableExtensions() {
|
||||
if (unparseableExtensions == null) {
|
||||
return Collections.emptyMap();
|
||||
} else {
|
||||
return unparseableExtensions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a critical extension is found that is
|
||||
* not supported, otherwise return false.
|
||||
*/
|
||||
public boolean hasUnsupportedCriticalExtension() {
|
||||
return unsupportedCritExt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this CertificateExtensions for equality with the specified
|
||||
* object. If the {@code other} object is an
|
||||
* {@code instanceof} {@code CertificateExtensions}, then
|
||||
* all the entries are compared with the entries from this.
|
||||
*
|
||||
* @param other the object to test for equality with this
|
||||
* CertificateExtensions.
|
||||
* @return true iff all the entries match that of the Other,
|
||||
* false otherwise.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
if (!(other instanceof CertificateExtensions))
|
||||
return false;
|
||||
Collection<Extension> otherC =
|
||||
((CertificateExtensions)other).getAllExtensions();
|
||||
Object[] objs = otherC.toArray();
|
||||
|
||||
int len = objs.length;
|
||||
if (len != map.size())
|
||||
return false;
|
||||
|
||||
Extension otherExt, thisExt;
|
||||
String key = null;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (objs[i] instanceof CertAttrSet)
|
||||
key = ((CertAttrSet)objs[i]).getName();
|
||||
otherExt = (Extension)objs[i];
|
||||
if (key == null)
|
||||
key = otherExt.getExtensionId().toString();
|
||||
thisExt = map.get(key);
|
||||
if (thisExt == null)
|
||||
return false;
|
||||
if (! thisExt.equals(otherExt))
|
||||
return false;
|
||||
}
|
||||
return this.getUnparseableExtensions().equals(
|
||||
((CertificateExtensions)other).getUnparseableExtensions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode value for this CertificateExtensions.
|
||||
*
|
||||
* @return the hashcode value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return map.hashCode() + getUnparseableExtensions().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this {@code CertificateExtensions}
|
||||
* object in the form of a set of entries, enclosed in braces and separated
|
||||
* by the ASCII characters "{@code , }" (comma and space).
|
||||
* <p>Overrides to {@code toString} method of {@code Object}.
|
||||
*
|
||||
* @return a string representation of this CertificateExtensions.
|
||||
*/
|
||||
public String toString() {
|
||||
return map.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class UnparseableExtension extends Extension {
|
||||
private String name;
|
||||
private Throwable why;
|
||||
|
||||
public UnparseableExtension(Extension ext, Throwable why) {
|
||||
super(ext);
|
||||
|
||||
name = "";
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(ext.getExtensionId());
|
||||
if (extClass != null) {
|
||||
Field field = extClass.getDeclaredField("NAME");
|
||||
name = (String)(field.get(null)) + " ";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// If we cannot find the name, just ignore it
|
||||
}
|
||||
|
||||
this.why = why;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return super.toString() +
|
||||
"Unparseable " + name + "extension due to\n" + why + "\n\n" +
|
||||
new sun.misc.HexDumpEncoder().encodeBuffer(getExtensionValue());
|
||||
}
|
||||
}
|
||||
209
jdkSrc/jdk8/sun/security/x509/CertificateIssuerExtension.java
Normal file
209
jdkSrc/jdk8/sun/security/x509/CertificateIssuerExtension.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.DerOutputStream;
|
||||
|
||||
/**
|
||||
* Represents the CRL Certificate Issuer Extension (OID = 2.5.29.29).
|
||||
* <p>
|
||||
* The CRL certificate issuer extension identifies the certificate issuer
|
||||
* associated with an entry in an indirect CRL, i.e. a CRL that has the
|
||||
* indirectCRL indicator set in its issuing distribution point extension. If
|
||||
* this extension is not present on the first entry in an indirect CRL, the
|
||||
* certificate issuer defaults to the CRL issuer. On subsequent entries
|
||||
* in an indirect CRL, if this extension is not present, the certificate
|
||||
* issuer for the entry is the same as that for the preceding entry.
|
||||
* <p>
|
||||
* If used by conforming CRL issuers, this extension is always
|
||||
* critical. If an implementation ignored this extension it could not
|
||||
* correctly attribute CRL entries to certificates. PKIX (RFC 5280)
|
||||
* RECOMMENDS that implementations recognize this extension.
|
||||
* <p>
|
||||
* The ASN.1 definition for this is:
|
||||
* <pre>
|
||||
* id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
|
||||
*
|
||||
* certificateIssuer ::= GeneralNames
|
||||
* </pre>
|
||||
*
|
||||
* @author Anne Anderson
|
||||
* @author Sean Mullan
|
||||
* @since 1.5
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateIssuerExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "CertificateIssuer";
|
||||
public static final String ISSUER = "issuer";
|
||||
|
||||
private GeneralNames names;
|
||||
|
||||
/**
|
||||
* Encode this extension
|
||||
*/
|
||||
private void encodeThis() throws IOException {
|
||||
if (names == null || names.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
names.encode(os);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CertificateIssuerExtension containing the specified issuer name.
|
||||
* Criticality is automatically set to true.
|
||||
*
|
||||
* @param issuer the certificate issuer
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public CertificateIssuerExtension(GeneralNames issuer) throws IOException {
|
||||
this.extensionId = PKIXExtensions.CertificateIssuer_Id;
|
||||
this.critical = true;
|
||||
this.names = issuer;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CertificateIssuerExtension from the specified DER encoded
|
||||
* value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value
|
||||
* @throws ClassCastException if value is not an array of bytes
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public CertificateIssuerExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.CertificateIssuer_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.names = new GeneralNames(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER)) {
|
||||
if (!(obj instanceof GeneralNames)) {
|
||||
throw new IOException("Attribute value must be of type " +
|
||||
"GeneralNames");
|
||||
}
|
||||
this.names = (GeneralNames)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuer");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attribute value.
|
||||
*
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public GeneralNames get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER)) {
|
||||
return names;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuer");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the attribute value.
|
||||
*
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER)) {
|
||||
names = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuer");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the certificate issuer.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + "Certificate Issuer [\n" +
|
||||
String.valueOf(names) + "]\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to
|
||||
* @exception IOException on encoding errors
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.CertificateIssuer_Id;
|
||||
critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(ISSUER);
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
180
jdkSrc/jdk8/sun/security/x509/CertificateIssuerName.java
Normal file
180
jdkSrc/jdk8/sun/security/x509/CertificateIssuerName.java
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the X500Name attribute for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateIssuerName implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.issuer";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "issuer";
|
||||
public static final String DN_NAME = "dname";
|
||||
|
||||
// accessor name for cached X500Principal only
|
||||
// do not allow a set() of this value, do not advertise with getElements()
|
||||
public static final String DN_PRINCIPAL = "x500principal";
|
||||
|
||||
// Private data member
|
||||
private X500Name dnName;
|
||||
|
||||
// cached X500Principal version of the name
|
||||
private X500Principal dnPrincipal;
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param name the X500Name
|
||||
*/
|
||||
public CertificateIssuerName(X500Name name) {
|
||||
this.dnName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the X500Name from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateIssuerName(DerInputStream in) throws IOException {
|
||||
dnName = new X500Name(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the X500Name from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateIssuerName(InputStream in) throws IOException {
|
||||
DerValue derVal = new DerValue(in);
|
||||
dnName = new X500Name(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (dnName == null) return "";
|
||||
return(dnName.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the name in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
dnName.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof X500Name)) {
|
||||
throw new IOException("Attribute must be of type X500Name.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
this.dnName = (X500Name)obj;
|
||||
this.dnPrincipal = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuerName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
return(dnName);
|
||||
} else if (name.equalsIgnoreCase(DN_PRINCIPAL)) {
|
||||
if ((dnPrincipal == null) && (dnName != null)) {
|
||||
dnPrincipal = dnName.asX500Principal();
|
||||
}
|
||||
return dnPrincipal;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuerName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
dnName = null;
|
||||
dnPrincipal = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateIssuerName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DN_NAME);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
}
|
||||
252
jdkSrc/jdk8/sun/security/x509/CertificatePoliciesExtension.java
Normal file
252
jdkSrc/jdk8/sun/security/x509/CertificatePoliciesExtension.java
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.DerOutputStream;
|
||||
|
||||
/**
|
||||
* This class defines the certificate policies extension which specifies the
|
||||
* policies under which the certificate has been issued
|
||||
* and the purposes for which the certificate may be used.
|
||||
* <p>
|
||||
* Applications with specific policy requirements are expected to have a
|
||||
* list of those policies which they will accept and to compare the
|
||||
* policy OIDs in the certificate to that list. If this extension is
|
||||
* critical, the path validation software MUST be able to interpret this
|
||||
* extension (including the optional qualifier), or MUST reject the
|
||||
* certificate.
|
||||
* <p>
|
||||
* Optional qualifiers are not supported in this implementation, as they are
|
||||
* not recommended by RFC2459.
|
||||
*
|
||||
* The ASN.1 syntax for this is (IMPLICIT tagging is defined in the
|
||||
* module definition):
|
||||
* <pre>
|
||||
* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||
*
|
||||
* certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
|
||||
*
|
||||
* PolicyInformation ::= SEQUENCE {
|
||||
* policyIdentifier CertPolicyId,
|
||||
* policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||||
* PolicyQualifierInfo OPTIONAL }
|
||||
*
|
||||
* CertPolicyId ::= OBJECT IDENTIFIER
|
||||
* </pre>
|
||||
* @author Anne Anderson
|
||||
* @since 1.4
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificatePoliciesExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.CertificatePolicies";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "CertificatePolicies";
|
||||
public static final String POLICIES = "policies";
|
||||
|
||||
/**
|
||||
* List of PolicyInformation for this object.
|
||||
*/
|
||||
private List<PolicyInformation> certPolicies;
|
||||
|
||||
// Encode this extension value.
|
||||
private void encodeThis() throws IOException {
|
||||
if (certPolicies == null || certPolicies.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
} else {
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
for (PolicyInformation info : certPolicies) {
|
||||
info.encode(tmp);
|
||||
}
|
||||
|
||||
os.write(DerValue.tag_Sequence, tmp);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CertificatePoliciesExtension object from
|
||||
* a List of PolicyInformation; the criticality is set to false.
|
||||
*
|
||||
* @param certPolicies the List of PolicyInformation.
|
||||
*/
|
||||
public CertificatePoliciesExtension(List<PolicyInformation> certPolicies)
|
||||
throws IOException {
|
||||
this(Boolean.FALSE, certPolicies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a CertificatePoliciesExtension object from
|
||||
* a List of PolicyInformation with specified criticality.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param certPolicies the List of PolicyInformation.
|
||||
*/
|
||||
public CertificatePoliciesExtension(Boolean critical,
|
||||
List<PolicyInformation> certPolicies) throws IOException {
|
||||
this.certPolicies = certPolicies;
|
||||
this.extensionId = PKIXExtensions.CertificatePolicies_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from its DER encoded value and criticality.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public CertificatePoliciesExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.CertificatePolicies_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"CertificatePoliciesExtension.");
|
||||
}
|
||||
certPolicies = new ArrayList<PolicyInformation>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
PolicyInformation policy = new PolicyInformation(seq);
|
||||
certPolicies.add(policy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (certPolicies == null) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(super.toString());
|
||||
sb.append("CertificatePolicies [\n");
|
||||
for (PolicyInformation info : certPolicies) {
|
||||
sb.append(info.toString());
|
||||
}
|
||||
sb.append("]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.CertificatePolicies_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with an instanceof check
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(POLICIES)) {
|
||||
if (!(obj instanceof List)) {
|
||||
throw new IOException("Attribute value should be of type List.");
|
||||
}
|
||||
certPolicies = (List<PolicyInformation>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:CertificatePoliciesExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public List<PolicyInformation> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POLICIES)) {
|
||||
//XXXX May want to consider cloning this
|
||||
return certPolicies;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:CertificatePoliciesExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POLICIES)) {
|
||||
certPolicies = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:CertificatePoliciesExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(POLICIES);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
110
jdkSrc/jdk8/sun/security/x509/CertificatePolicyId.java
Normal file
110
jdkSrc/jdk8/sun/security/x509/CertificatePolicyId.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.security.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* Represent the CertificatePolicyId ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class CertificatePolicyId {
|
||||
private ObjectIdentifier id;
|
||||
|
||||
/**
|
||||
* Create a CertificatePolicyId with the ObjectIdentifier.
|
||||
*
|
||||
* @param id the ObjectIdentifier for the policy id.
|
||||
*/
|
||||
public CertificatePolicyId(ObjectIdentifier id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from its Der encoded value.
|
||||
*
|
||||
* @param val the DER encoded value for the same.
|
||||
*/
|
||||
public CertificatePolicyId(DerValue val) throws IOException {
|
||||
this.id = val.getOID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the CertificatePolicyId as an ObjectIdentifier.
|
||||
*/
|
||||
public ObjectIdentifier getIdentifier() {
|
||||
return (id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the CertificatePolicyId.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "CertificatePolicyId: ["
|
||||
+ id.toString()
|
||||
+ "]\n";
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the CertificatePolicyId to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the object to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putOID(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this CertificatePolicyId with another, for
|
||||
* equality. Uses ObjectIdentifier.equals() as test for
|
||||
* equality.
|
||||
*
|
||||
* @return true iff the ids are identical.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof CertificatePolicyId)
|
||||
return id.equals((Object)
|
||||
((CertificatePolicyId) other).getIdentifier());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for this object.
|
||||
*
|
||||
* @return a hash code value
|
||||
*/
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
}
|
||||
106
jdkSrc/jdk8/sun/security/x509/CertificatePolicyMap.java
Normal file
106
jdkSrc/jdk8/sun/security/x509/CertificatePolicyMap.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the CertificatePolicyMap ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class CertificatePolicyMap {
|
||||
private CertificatePolicyId issuerDomain;
|
||||
private CertificatePolicyId subjectDomain;
|
||||
|
||||
/**
|
||||
* Create a CertificatePolicyMap with the passed CertificatePolicyId's.
|
||||
*
|
||||
* @param issuer the CertificatePolicyId for the issuer CA.
|
||||
* @param subject the CertificatePolicyId for the subject CA.
|
||||
*/
|
||||
public CertificatePolicyMap(CertificatePolicyId issuer,
|
||||
CertificatePolicyId subject) {
|
||||
this.issuerDomain = issuer;
|
||||
this.subjectDomain = subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the CertificatePolicyMap from the DER encoded value.
|
||||
*
|
||||
* @param val the DER encoded value of the same.
|
||||
*/
|
||||
public CertificatePolicyMap(DerValue val) throws IOException {
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for CertificatePolicyMap");
|
||||
}
|
||||
issuerDomain = new CertificatePolicyId(val.data.getDerValue());
|
||||
subjectDomain = new CertificatePolicyId(val.data.getDerValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the issuer CA part of the policy map.
|
||||
*/
|
||||
public CertificatePolicyId getIssuerIdentifier() {
|
||||
return (issuerDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the subject CA part of the policy map.
|
||||
*/
|
||||
public CertificatePolicyId getSubjectIdentifier() {
|
||||
return (subjectDomain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the CertificatePolicyId.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "CertificatePolicyMap: [\n"
|
||||
+ "IssuerDomain:" + issuerDomain.toString()
|
||||
+ "SubjectDomain:" + subjectDomain.toString()
|
||||
+ "]\n";
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the CertificatePolicyMap to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the object to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
issuerDomain.encode(tmp);
|
||||
subjectDomain.encode(tmp);
|
||||
out.write(DerValue.tag_Sequence,tmp);
|
||||
}
|
||||
}
|
||||
104
jdkSrc/jdk8/sun/security/x509/CertificatePolicySet.java
Normal file
104
jdkSrc/jdk8/sun/security/x509/CertificatePolicySet.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the certificate policy set ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class CertificatePolicySet {
|
||||
|
||||
private final Vector<CertificatePolicyId> ids;
|
||||
|
||||
/**
|
||||
* The default constructor for this class.
|
||||
*
|
||||
* @param ids the sequence of CertificatePolicyId's.
|
||||
*/
|
||||
public CertificatePolicySet(Vector<CertificatePolicyId> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from the DerValue.
|
||||
*
|
||||
* @param in the passed DerInputStream.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificatePolicySet(DerInputStream in) throws IOException {
|
||||
ids = new Vector<CertificatePolicyId>();
|
||||
DerValue[] seq = in.getSequence(5);
|
||||
|
||||
for (int i = 0; i < seq.length; i++) {
|
||||
CertificatePolicyId id = new CertificatePolicyId(seq[i]);
|
||||
ids.addElement(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return printable form of the object.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "CertificatePolicySet:[\n"
|
||||
+ ids.toString()
|
||||
+ "]\n";
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the policy set to the output stream.
|
||||
*
|
||||
* @param out the DerOutputStream to encode the data to.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
for (int i = 0; i < ids.size(); i++) {
|
||||
ids.elementAt(i).encode(tmp);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence,tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sequence of CertificatePolicyIds.
|
||||
*
|
||||
* @return A List containing the CertificatePolicyId objects.
|
||||
*
|
||||
*/
|
||||
public List<CertificatePolicyId> getCertPolicyIds() {
|
||||
return Collections.unmodifiableList(ids);
|
||||
}
|
||||
}
|
||||
182
jdkSrc/jdk8/sun/security/x509/CertificateSerialNumber.java
Normal file
182
jdkSrc/jdk8/sun/security/x509/CertificateSerialNumber.java
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the SerialNumber attribute for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateSerialNumber implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.serialNumber";
|
||||
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "serialNumber";
|
||||
public static final String NUMBER = "number";
|
||||
|
||||
private SerialNumber serial;
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param serial the serial number for the certificate.
|
||||
*/
|
||||
public CertificateSerialNumber(BigInteger num) {
|
||||
this.serial = new SerialNumber(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param serial the serial number for the certificate.
|
||||
*/
|
||||
public CertificateSerialNumber(int num) {
|
||||
this.serial = new SerialNumber(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the serial number from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateSerialNumber(DerInputStream in) throws IOException {
|
||||
serial = new SerialNumber(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the serial number from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateSerialNumber(InputStream in) throws IOException {
|
||||
serial = new SerialNumber(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DerValue.
|
||||
*
|
||||
* @param val the DER encoded value.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateSerialNumber(DerValue val) throws IOException {
|
||||
serial = new SerialNumber(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the serial number as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (serial == null) return "";
|
||||
return (serial.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the serial number in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
serial.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof SerialNumber)) {
|
||||
throw new IOException("Attribute must be of type SerialNumber.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
serial = (SerialNumber)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSerialNumber.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public SerialNumber get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
return (serial);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSerialNumber.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NUMBER)) {
|
||||
serial = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSerialNumber.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(NUMBER);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
180
jdkSrc/jdk8/sun/security/x509/CertificateSubjectName.java
Normal file
180
jdkSrc/jdk8/sun/security/x509/CertificateSubjectName.java
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the X500Name attribute for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateSubjectName implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.subject";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "subject";
|
||||
public static final String DN_NAME = "dname";
|
||||
|
||||
// accessor name for cached X500Principal only
|
||||
// do not allow a set() of this value, do not advertise with getElements()
|
||||
public static final String DN_PRINCIPAL = "x500principal";
|
||||
|
||||
// Private data member
|
||||
private X500Name dnName;
|
||||
|
||||
// cached X500Principal version of the name
|
||||
private X500Principal dnPrincipal;
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param name the X500Name
|
||||
*/
|
||||
public CertificateSubjectName(X500Name name) {
|
||||
this.dnName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the X500Name from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateSubjectName(DerInputStream in) throws IOException {
|
||||
dnName = new X500Name(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the X500Name from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateSubjectName(InputStream in) throws IOException {
|
||||
DerValue derVal = new DerValue(in);
|
||||
dnName = new X500Name(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (dnName == null) return "";
|
||||
return(dnName.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the name in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
dnName.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof X500Name)) {
|
||||
throw new IOException("Attribute must be of type X500Name.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
this.dnName = (X500Name)obj;
|
||||
this.dnPrincipal = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSubjectName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
return(dnName);
|
||||
} else if (name.equalsIgnoreCase(DN_PRINCIPAL)) {
|
||||
if ((dnPrincipal == null) && (dnName != null)) {
|
||||
dnPrincipal = dnName.asX500Principal();
|
||||
}
|
||||
return dnPrincipal;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSubjectName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DN_NAME)) {
|
||||
dnName = null;
|
||||
dnPrincipal = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:CertificateSubjectName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DN_NAME);
|
||||
|
||||
return(elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
}
|
||||
280
jdkSrc/jdk8/sun/security/x509/CertificateValidity.java
Normal file
280
jdkSrc/jdk8/sun/security/x509/CertificateValidity.java
Normal file
@@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.*;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the interval for which the certificate is valid.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateValidity implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.validity";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "validity";
|
||||
public static final String NOT_BEFORE = "notBefore";
|
||||
public static final String NOT_AFTER = "notAfter";
|
||||
/**
|
||||
* YR_2050 date and time set to Jan01 00:00 2050 GMT
|
||||
*/
|
||||
static final long YR_2050 = 2524608000000L;
|
||||
|
||||
// Private data members
|
||||
private Date notBefore;
|
||||
private Date notAfter;
|
||||
|
||||
// Returns the first time the certificate is valid.
|
||||
private Date getNotBefore() {
|
||||
return (new Date(notBefore.getTime()));
|
||||
}
|
||||
|
||||
// Returns the last time the certificate is valid.
|
||||
private Date getNotAfter() {
|
||||
return (new Date(notAfter.getTime()));
|
||||
}
|
||||
|
||||
// Construct the class from the DerValue
|
||||
private void construct(DerValue derVal) throws IOException {
|
||||
if (derVal.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoded CertificateValidity, " +
|
||||
"starting sequence tag missing.");
|
||||
}
|
||||
// check if UTCTime encoded or GeneralizedTime
|
||||
if (derVal.data.available() == 0)
|
||||
throw new IOException("No data encoded for CertificateValidity");
|
||||
|
||||
DerInputStream derIn = new DerInputStream(derVal.toByteArray());
|
||||
DerValue[] seq = derIn.getSequence(2);
|
||||
if (seq.length != 2)
|
||||
throw new IOException("Invalid encoding for CertificateValidity");
|
||||
|
||||
if (seq[0].tag == DerValue.tag_UtcTime) {
|
||||
notBefore = derVal.data.getUTCTime();
|
||||
} else if (seq[0].tag == DerValue.tag_GeneralizedTime) {
|
||||
notBefore = derVal.data.getGeneralizedTime();
|
||||
} else {
|
||||
throw new IOException("Invalid encoding for CertificateValidity");
|
||||
}
|
||||
|
||||
if (seq[1].tag == DerValue.tag_UtcTime) {
|
||||
notAfter = derVal.data.getUTCTime();
|
||||
} else if (seq[1].tag == DerValue.tag_GeneralizedTime) {
|
||||
notAfter = derVal.data.getGeneralizedTime();
|
||||
} else {
|
||||
throw new IOException("Invalid encoding for CertificateValidity");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for the class.
|
||||
*/
|
||||
public CertificateValidity() { }
|
||||
|
||||
/**
|
||||
* The default constructor for this class for the specified interval.
|
||||
*
|
||||
* @param notBefore the date and time before which the certificate
|
||||
* is not valid.
|
||||
* @param notAfter the date and time after which the certificate is
|
||||
* not valid.
|
||||
*/
|
||||
public CertificateValidity(Date notBefore, Date notAfter) {
|
||||
this.notBefore = notBefore;
|
||||
this.notAfter = notAfter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the CertificateValidity from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateValidity(DerInputStream in) throws IOException {
|
||||
DerValue derVal = in.getDerValue();
|
||||
construct(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the validity period as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (notBefore == null || notAfter == null)
|
||||
return "";
|
||||
return ("Validity: [From: " + notBefore.toString() +
|
||||
",\n To: " + notAfter.toString() + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the CertificateValidity period in DER form to the stream.
|
||||
*
|
||||
* @param out the OutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
|
||||
// in cases where default constructor is used check for
|
||||
// null values
|
||||
if (notBefore == null || notAfter == null) {
|
||||
throw new IOException("CertAttrSet:CertificateValidity:" +
|
||||
" null values to encode.\n");
|
||||
}
|
||||
DerOutputStream pair = new DerOutputStream();
|
||||
|
||||
if (notBefore.getTime() < YR_2050) {
|
||||
pair.putUTCTime(notBefore);
|
||||
} else
|
||||
pair.putGeneralizedTime(notBefore);
|
||||
|
||||
if (notAfter.getTime() < YR_2050) {
|
||||
pair.putUTCTime(notAfter);
|
||||
} else {
|
||||
pair.putGeneralizedTime(notAfter);
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, pair);
|
||||
|
||||
out.write(seq.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Date)) {
|
||||
throw new IOException("Attribute must be of type Date.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
notBefore = (Date)obj;
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
notAfter = (Date)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateValidity.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Date get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
return (getNotBefore());
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
return (getNotAfter());
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateValidity.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
notBefore = null;
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
notAfter = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateValidity.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(NOT_BEFORE);
|
||||
elements.addElement(NOT_AFTER);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the current time is within the validity period.
|
||||
*
|
||||
* @exception CertificateExpiredException if the certificate has expired.
|
||||
* @exception CertificateNotYetValidException if the certificate is not
|
||||
* yet valid.
|
||||
*/
|
||||
public void valid()
|
||||
throws CertificateNotYetValidException, CertificateExpiredException {
|
||||
Date now = new Date();
|
||||
valid(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the passed time is within the validity period.
|
||||
* @param now the Date against which to compare the validity
|
||||
* period.
|
||||
*
|
||||
* @exception CertificateExpiredException if the certificate has expired
|
||||
* with respect to the <code>Date</code> supplied.
|
||||
* @exception CertificateNotYetValidException if the certificate is not
|
||||
* yet valid with respect to the <code>Date</code> supplied.
|
||||
*
|
||||
*/
|
||||
public void valid(Date now)
|
||||
throws CertificateNotYetValidException, CertificateExpiredException {
|
||||
/*
|
||||
* we use the internal Dates rather than the passed in Date
|
||||
* because someone could override the Date methods after()
|
||||
* and before() to do something entirely different.
|
||||
*/
|
||||
if (notBefore.after(now)) {
|
||||
throw new CertificateNotYetValidException("NotBefore: " +
|
||||
notBefore.toString());
|
||||
}
|
||||
if (notAfter.before(now)) {
|
||||
throw new CertificateExpiredException("NotAfter: " +
|
||||
notAfter.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
239
jdkSrc/jdk8/sun/security/x509/CertificateVersion.java
Normal file
239
jdkSrc/jdk8/sun/security/x509/CertificateVersion.java
Normal file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the version of the X509 Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateVersion implements CertAttrSet<String> {
|
||||
/**
|
||||
* X509Certificate Version 1
|
||||
*/
|
||||
public static final int V1 = 0;
|
||||
/**
|
||||
* X509Certificate Version 2
|
||||
*/
|
||||
public static final int V2 = 1;
|
||||
/**
|
||||
* X509Certificate Version 3
|
||||
*/
|
||||
public static final int V3 = 2;
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.version";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "version";
|
||||
public static final String VERSION = "number";
|
||||
|
||||
// Private data members
|
||||
int version = V1;
|
||||
|
||||
// Returns the version number.
|
||||
private int getVersion() {
|
||||
return(version);
|
||||
}
|
||||
|
||||
// Construct the class from the passed DerValue
|
||||
private void construct(DerValue derVal) throws IOException {
|
||||
if (derVal.isConstructed() && derVal.isContextSpecific()) {
|
||||
derVal = derVal.data.getDerValue();
|
||||
version = derVal.getInteger();
|
||||
if (derVal.data.available() != 0) {
|
||||
throw new IOException("X.509 version, bad format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class,
|
||||
* sets the version to 0 (i.e. X.509 version 1).
|
||||
*/
|
||||
public CertificateVersion() {
|
||||
version = V1;
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor for this class for the required version.
|
||||
*
|
||||
* @param version the version for the certificate.
|
||||
* @exception IOException if the version is not valid.
|
||||
*/
|
||||
public CertificateVersion(int version) throws IOException {
|
||||
|
||||
// check that it is a valid version
|
||||
if (version == V1 || version == V2 || version == V3)
|
||||
this.version = version;
|
||||
else {
|
||||
throw new IOException("X.509 Certificate version " +
|
||||
version + " not supported.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the CertificateVersion from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateVersion(DerInputStream in) throws IOException {
|
||||
version = V1;
|
||||
DerValue derVal = in.getDerValue();
|
||||
|
||||
construct(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the CertificateVersion from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateVersion(InputStream in) throws IOException {
|
||||
version = V1;
|
||||
DerValue derVal = new DerValue(in);
|
||||
|
||||
construct(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DerValue.
|
||||
*
|
||||
* @param val the Der encoded value.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateVersion(DerValue val) throws IOException {
|
||||
version = V1;
|
||||
|
||||
construct(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the version number of the certificate.
|
||||
*/
|
||||
public String toString() {
|
||||
return("Version: V" + (version+1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the CertificateVersion period in DER form to the stream.
|
||||
*
|
||||
* @param out the OutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
// Nothing for default
|
||||
if (version == V1) {
|
||||
return;
|
||||
}
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putInteger(version);
|
||||
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0),
|
||||
tmp);
|
||||
|
||||
out.write(seq.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Integer)) {
|
||||
throw new IOException("Attribute must be of type Integer.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(VERSION)) {
|
||||
version = ((Integer)obj).intValue();
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateVersion.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Integer get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(VERSION)) {
|
||||
return(new Integer(getVersion()));
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateVersion.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(VERSION)) {
|
||||
version = V1;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateVersion.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(VERSION);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare versions.
|
||||
*/
|
||||
public int compare(int vers) {
|
||||
return(version - vers);
|
||||
}
|
||||
}
|
||||
163
jdkSrc/jdk8/sun/security/x509/CertificateX509Key.java
Normal file
163
jdkSrc/jdk8/sun/security/x509/CertificateX509Key.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the X509Key attribute for the Certificate.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class CertificateX509Key implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.key";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "key";
|
||||
public static final String KEY = "value";
|
||||
|
||||
// Private data member
|
||||
private PublicKey key;
|
||||
|
||||
/**
|
||||
* Default constructor for the certificate attribute.
|
||||
*
|
||||
* @param key the X509Key
|
||||
*/
|
||||
public CertificateX509Key(PublicKey key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the X509Key from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateX509Key(DerInputStream in) throws IOException {
|
||||
DerValue val = in.getDerValue();
|
||||
key = X509Key.parse(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the X509Key from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public CertificateX509Key(InputStream in) throws IOException {
|
||||
DerValue val = new DerValue(in);
|
||||
key = X509Key.parse(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key as printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (key == null) return "";
|
||||
return(key.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the key in DER form to the stream.
|
||||
*
|
||||
* @param out the OutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.write(key.getEncoded());
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY)) {
|
||||
this.key = (PublicKey)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateX509Key.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public PublicKey get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY)) {
|
||||
return(key);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateX509Key.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY)) {
|
||||
key = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet: CertificateX509Key.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(KEY);
|
||||
|
||||
return(elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
}
|
||||
278
jdkSrc/jdk8/sun/security/x509/DNSName.java
Normal file
278
jdkSrc/jdk8/sun/security/x509/DNSName.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the DNSName as required by the GeneralNames
|
||||
* ASN.1 object.
|
||||
* <p>
|
||||
* [RFC5280] When the subjectAltName extension contains a domain name system
|
||||
* label, the domain name MUST be stored in the dNSName (an IA5String).
|
||||
* The name MUST be in the "preferred name syntax", as specified by
|
||||
* Section 3.5 of [RFC1034] and as modified by Section 2.1 of
|
||||
* [RFC1123]. Note that while uppercase and lowercase letters are
|
||||
* allowed in domain names, no significance is attached to the case. In
|
||||
* addition, while the string " " is a legal domain name, subjectAltName
|
||||
* extensions with a dNSName of " " MUST NOT be used. Finally, the use
|
||||
* of the DNS representation for Internet mail addresses
|
||||
* (subscriber.example.com instead of subscriber@example.com) MUST NOT
|
||||
* be used; such identities are to be encoded as rfc822Name.
|
||||
* <p>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class DNSName implements GeneralNameInterface {
|
||||
private String name;
|
||||
|
||||
private static final String alphaDigits =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
/**
|
||||
* Create the DNSName object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER DNSName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public DNSName(DerValue derValue) throws IOException {
|
||||
name = derValue.getIA5String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the DNSName object with the specified name.
|
||||
*
|
||||
* @param name the DNSName.
|
||||
* @param allowWildcard the flag for wildcard checking.
|
||||
* @throws IOException if the name is not a valid DNSName
|
||||
*/
|
||||
public DNSName(String name, boolean allowWildcard) throws IOException {
|
||||
if (name == null || name.length() == 0)
|
||||
throw new IOException("DNSName must not be null or empty");
|
||||
if (name.contains(" "))
|
||||
throw new IOException("DNSName with blank components is not permitted");
|
||||
if (name.startsWith(".") || name.endsWith("."))
|
||||
throw new IOException("DNSName may not begin or end with a .");
|
||||
/*
|
||||
* Name will consist of label components separated by "."
|
||||
* startIndex is the index of the first character of a component
|
||||
* endIndex is the index of the last character of a component plus 1
|
||||
*/
|
||||
for (int endIndex,startIndex = 0; startIndex < name.length(); startIndex = endIndex+1) {
|
||||
endIndex = name.indexOf('.', startIndex);
|
||||
if (endIndex < 0) {
|
||||
endIndex = name.length();
|
||||
}
|
||||
if (endIndex - startIndex < 1)
|
||||
throw new IOException("DNSName with empty components are not permitted");
|
||||
|
||||
if (allowWildcard) {
|
||||
// RFC 1123: DNSName components must begin with a letter or digit
|
||||
// or RFC 4592: the first component of a DNSName can have only a wildcard
|
||||
// character * (asterisk), i.e. *.example.com. Asterisks at other components
|
||||
// will not be allowed as a wildcard.
|
||||
if (alphaDigits.indexOf(name.charAt(startIndex)) < 0) {
|
||||
// Checking to make sure the wildcard only appears in the first component,
|
||||
// and it has to be at least 3-char long with the form of *.[alphaDigit]
|
||||
if ((name.length() < 3) || (name.indexOf('*', 0) != 0) ||
|
||||
(name.charAt(startIndex+1) != '.') ||
|
||||
(alphaDigits.indexOf(name.charAt(startIndex+2)) < 0))
|
||||
throw new IOException("DNSName components must begin with a letter, digit, "
|
||||
+ "or the first component can have only a wildcard character *");
|
||||
}
|
||||
} else {
|
||||
// RFC 1123: DNSName components must begin with a letter or digit
|
||||
if (alphaDigits.indexOf(name.charAt(startIndex)) < 0)
|
||||
throw new IOException("DNSName components must begin with a letter or digit");
|
||||
}
|
||||
|
||||
//nonStartIndex: index for characters in the component beyond the first one
|
||||
for (int nonStartIndex=startIndex+1; nonStartIndex < endIndex; nonStartIndex++) {
|
||||
char x = name.charAt(nonStartIndex);
|
||||
if ((alphaDigits).indexOf(x) < 0 && x != '-')
|
||||
throw new IOException("DNSName components must consist of letters, digits, and hyphens");
|
||||
}
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the DNSName object with the specified name.
|
||||
*
|
||||
* @param name the DNSName.
|
||||
* @throws IOException if the name is not a valid DNSName
|
||||
*/
|
||||
public DNSName(String name) throws IOException {
|
||||
this(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return (GeneralNameInterface.NAME_DNS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the actual name value of the GeneralName.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the DNSName into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the DNSName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putIA5String(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the name into user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("DNSName: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are equivalent
|
||||
* according to RFC5280.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof DNSName))
|
||||
return false;
|
||||
|
||||
DNSName other = (DNSName)obj;
|
||||
|
||||
// RFC5280 mandates that these names are
|
||||
// not case-sensitive
|
||||
return name.equalsIgnoreCase(other.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.toUpperCase(Locale.ENGLISH).hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
* <p>
|
||||
* RFC5280: DNS name restrictions are expressed as host.example.com.
|
||||
* Any DNS name that can be constructed by simply adding zero or more
|
||||
* labels to the left-hand side of the name satisfies the name constraint.
|
||||
* For example, www.host.example.com would satisfy the constraint but
|
||||
* host1.example.com would not.
|
||||
* <p>
|
||||
* draft-ietf-pkix-new-part1-00.txt: DNSName restrictions are expressed as foo.bar.com.
|
||||
* Any DNSName that
|
||||
* can be constructed by simply adding to the left hand side of the name
|
||||
* satisfies the name constraint. For example, www.foo.bar.com would
|
||||
* satisfy the constraint but foo1.bar.com would not.
|
||||
* <p>
|
||||
* RFC1034: By convention, domain names can be stored with arbitrary case, but
|
||||
* domain name comparisons for all present domain functions are done in a
|
||||
* case-insensitive manner, assuming an ASCII character set, and a high
|
||||
* order zero bit.
|
||||
* <p>
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is not exact match, but narrowing and widening are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != NAME_DNS)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else {
|
||||
String inName =
|
||||
(((DNSName)inputName).getName()).toLowerCase(Locale.ENGLISH);
|
||||
String thisName = name.toLowerCase(Locale.ENGLISH);
|
||||
if (inName.equals(thisName))
|
||||
constraintType = NAME_MATCH;
|
||||
else if (thisName.endsWith(inName)) {
|
||||
int inNdx = thisName.lastIndexOf(inName);
|
||||
if (thisName.charAt(inNdx-1) == '.' )
|
||||
constraintType = NAME_WIDENS;
|
||||
else
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else if (inName.endsWith(thisName)) {
|
||||
int ndx = inName.lastIndexOf(thisName);
|
||||
if (inName.charAt(ndx-1) == '.' )
|
||||
constraintType = NAME_NARROWS;
|
||||
else
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
// subtree depth is always at least 1
|
||||
int sum = 1;
|
||||
|
||||
// count dots
|
||||
for (int i = name.indexOf('.'); i >= 0; i = name.indexOf('.', i + 1)) {
|
||||
++sum;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
}
|
||||
116
jdkSrc/jdk8/sun/security/x509/DeltaCRLIndicatorExtension.java
Normal file
116
jdkSrc/jdk8/sun/security/x509/DeltaCRLIndicatorExtension.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represents the Delta CRL Indicator Extension.
|
||||
*
|
||||
* <p>
|
||||
* The extension identifies a CRL as being a delta CRL.
|
||||
* Delta CRLs contain updates to revocation information previously distributed,
|
||||
* rather than all the information that would appear in a complete CRL.
|
||||
* The extension contains a CRL number that identifies the CRL, complete for a
|
||||
* given scope, that was used as the starting point in the generation of
|
||||
* this delta CRL.
|
||||
*
|
||||
* <p>
|
||||
* The extension is defined in Section 5.2.4 of
|
||||
* <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
|
||||
ate and Certificate Revocation List (CRL) Profile</a>.
|
||||
*
|
||||
* <p>
|
||||
* Its ASN.1 definition is as follows:
|
||||
* <pre>
|
||||
* id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
|
||||
*
|
||||
* BaseCRLNumber ::= CRLNumber
|
||||
* CRLNumber ::= INTEGER (0..MAX)
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class DeltaCRLIndicatorExtension extends CRLNumberExtension {
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "DeltaCRLIndicator";
|
||||
|
||||
private static final String LABEL = "Base CRL Number";
|
||||
|
||||
/**
|
||||
* Creates a delta CRL indicator extension with the integer value .
|
||||
* The criticality is set to true.
|
||||
*
|
||||
* @param crlNum the value to be set for the extension.
|
||||
*/
|
||||
public DeltaCRLIndicatorExtension(int crlNum) throws IOException {
|
||||
super(PKIXExtensions.DeltaCRLIndicator_Id, true,
|
||||
BigInteger.valueOf(crlNum), NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a delta CRL indictor extension with the BigInteger value .
|
||||
* The criticality is set to true.
|
||||
*
|
||||
* @param crlNum the value to be set for the extension.
|
||||
*/
|
||||
public DeltaCRLIndicatorExtension(BigInteger crlNum) throws IOException {
|
||||
super(PKIXExtensions.DeltaCRLIndicator_Id, true, crlNum, NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on decoding error.
|
||||
*/
|
||||
public DeltaCRLIndicatorExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
super(PKIXExtensions.DeltaCRLIndicator_Id, critical.booleanValue(),
|
||||
value, NAME, LABEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
super.encode(out, PKIXExtensions.DeltaCRLIndicator_Id, true);
|
||||
}
|
||||
}
|
||||
404
jdkSrc/jdk8/sun/security/x509/DistributionPoint.java
Normal file
404
jdkSrc/jdk8/sun/security/x509/DistributionPoint.java
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.BitArray;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* Represent the DistributionPoint sequence used in the CRL
|
||||
* Distribution Points Extension (OID = 2.5.29.31).
|
||||
* <p>
|
||||
* The ASN.1 definition for this is:
|
||||
* <pre>
|
||||
* DistributionPoint ::= SEQUENCE {
|
||||
* distributionPoint [0] DistributionPointName OPTIONAL,
|
||||
* reasons [1] ReasonFlags OPTIONAL,
|
||||
* cRLIssuer [2] GeneralNames OPTIONAL }
|
||||
*
|
||||
* DistributionPointName ::= CHOICE {
|
||||
* fullName [0] GeneralNames,
|
||||
* nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
|
||||
*
|
||||
* ReasonFlags ::= BIT STRING {
|
||||
* unused (0),
|
||||
* keyCompromise (1),
|
||||
* cACompromise (2),
|
||||
* affiliationChanged (3),
|
||||
* superseded (4),
|
||||
* cessationOfOperation (5),
|
||||
* certificateHold (6),
|
||||
* privilegeWithdrawn (7),
|
||||
* aACompromise (8) }
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] INSTANCE OF OTHER-NAME,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
* </pre>
|
||||
* <p>
|
||||
* Instances of this class are designed to be immutable. However, since this
|
||||
* is an internal API we do not use defensive cloning for values for
|
||||
* performance reasons. It is the responsibility of the consumer to ensure
|
||||
* that no mutable elements are modified.
|
||||
*
|
||||
* @author Anne Anderson
|
||||
* @author Andreas Sterbenz
|
||||
* @since 1.4.2
|
||||
* @see CRLDistributionPointsExtension
|
||||
*/
|
||||
public class DistributionPoint {
|
||||
|
||||
// reason flag bits
|
||||
// NOTE that these are NOT quite the same as the CRL reason code extension
|
||||
public final static int KEY_COMPROMISE = 1;
|
||||
public final static int CA_COMPROMISE = 2;
|
||||
public final static int AFFILIATION_CHANGED = 3;
|
||||
public final static int SUPERSEDED = 4;
|
||||
public final static int CESSATION_OF_OPERATION = 5;
|
||||
public final static int CERTIFICATE_HOLD = 6;
|
||||
public final static int PRIVILEGE_WITHDRAWN = 7;
|
||||
public final static int AA_COMPROMISE = 8;
|
||||
|
||||
private static final String[] REASON_STRINGS = {
|
||||
null,
|
||||
"key compromise",
|
||||
"CA compromise",
|
||||
"affiliation changed",
|
||||
"superseded",
|
||||
"cessation of operation",
|
||||
"certificate hold",
|
||||
"privilege withdrawn",
|
||||
"AA compromise",
|
||||
};
|
||||
|
||||
// context specific tag values
|
||||
private static final byte TAG_DIST_PT = 0;
|
||||
private static final byte TAG_REASONS = 1;
|
||||
private static final byte TAG_ISSUER = 2;
|
||||
|
||||
private static final byte TAG_FULL_NAME = 0;
|
||||
private static final byte TAG_REL_NAME = 1;
|
||||
|
||||
// only one of fullName and relativeName can be set
|
||||
private GeneralNames fullName;
|
||||
private RDN relativeName;
|
||||
|
||||
// reasonFlags or null
|
||||
private boolean[] reasonFlags;
|
||||
|
||||
// crlIssuer or null
|
||||
private GeneralNames crlIssuer;
|
||||
|
||||
// cached hashCode value
|
||||
private volatile int hashCode;
|
||||
|
||||
/**
|
||||
* Constructor for the class using GeneralNames for DistributionPointName
|
||||
*
|
||||
* @param fullName the GeneralNames of the distribution point; may be null
|
||||
* @param reasons the CRL reasons included in the CRL at this distribution
|
||||
* point; may be null
|
||||
* @param issuer the name(s) of the CRL issuer for the CRL at this
|
||||
* distribution point; may be null
|
||||
*/
|
||||
public DistributionPoint(GeneralNames fullName, boolean[] reasonFlags,
|
||||
GeneralNames crlIssuer) {
|
||||
if ((fullName == null) && (crlIssuer == null)) {
|
||||
throw new IllegalArgumentException
|
||||
("fullName and crlIssuer may not both be null");
|
||||
}
|
||||
this.fullName = fullName;
|
||||
this.reasonFlags = reasonFlags;
|
||||
this.crlIssuer = crlIssuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the class using RelativeDistinguishedName for
|
||||
* DistributionPointName
|
||||
*
|
||||
* @param relativeName the RelativeDistinguishedName of the distribution
|
||||
* point; may not be null
|
||||
* @param reasons the CRL reasons included in the CRL at this distribution
|
||||
* point; may be null
|
||||
* @param issuer the name(s) of the CRL issuer for the CRL at this
|
||||
* distribution point; may not be null or empty.
|
||||
*/
|
||||
public DistributionPoint(RDN relativeName, boolean[] reasonFlags,
|
||||
GeneralNames crlIssuer) {
|
||||
if ((relativeName == null) && (crlIssuer == null)) {
|
||||
throw new IllegalArgumentException
|
||||
("relativeName and crlIssuer may not both be null");
|
||||
}
|
||||
this.relativeName = relativeName;
|
||||
this.reasonFlags = reasonFlags;
|
||||
this.crlIssuer = crlIssuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from the passed DER encoded form.
|
||||
*
|
||||
* @param val the DER encoded form of the DistributionPoint
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public DistributionPoint(DerValue val) throws IOException {
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding of DistributionPoint.");
|
||||
}
|
||||
|
||||
// Note that all the fields in DistributionPoint are defined as
|
||||
// being OPTIONAL, i.e., there could be an empty SEQUENCE, resulting
|
||||
// in val.data being null.
|
||||
while ((val.data != null) && (val.data.available() != 0)) {
|
||||
DerValue opt = val.data.getDerValue();
|
||||
|
||||
if (opt.isContextSpecific(TAG_DIST_PT) && opt.isConstructed()) {
|
||||
if ((fullName != null) || (relativeName != null)) {
|
||||
throw new IOException("Duplicate DistributionPointName in "
|
||||
+ "DistributionPoint.");
|
||||
}
|
||||
DerValue distPnt = opt.data.getDerValue();
|
||||
if (distPnt.isContextSpecific(TAG_FULL_NAME)
|
||||
&& distPnt.isConstructed()) {
|
||||
distPnt.resetTag(DerValue.tag_Sequence);
|
||||
fullName = new GeneralNames(distPnt);
|
||||
} else if (distPnt.isContextSpecific(TAG_REL_NAME)
|
||||
&& distPnt.isConstructed()) {
|
||||
distPnt.resetTag(DerValue.tag_Set);
|
||||
relativeName = new RDN(distPnt);
|
||||
} else {
|
||||
throw new IOException("Invalid DistributionPointName in "
|
||||
+ "DistributionPoint");
|
||||
}
|
||||
} else if (opt.isContextSpecific(TAG_REASONS)
|
||||
&& !opt.isConstructed()) {
|
||||
if (reasonFlags != null) {
|
||||
throw new IOException("Duplicate Reasons in " +
|
||||
"DistributionPoint.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_BitString);
|
||||
reasonFlags = (opt.getUnalignedBitString()).toBooleanArray();
|
||||
} else if (opt.isContextSpecific(TAG_ISSUER)
|
||||
&& opt.isConstructed()) {
|
||||
if (crlIssuer != null) {
|
||||
throw new IOException("Duplicate CRLIssuer in " +
|
||||
"DistributionPoint.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_Sequence);
|
||||
crlIssuer = new GeneralNames(opt);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of " +
|
||||
"DistributionPoint.");
|
||||
}
|
||||
}
|
||||
if ((crlIssuer == null) && (fullName == null) && (relativeName == null)) {
|
||||
throw new IOException("One of fullName, relativeName, "
|
||||
+ " and crlIssuer has to be set");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full distribution point name or null if not set.
|
||||
*/
|
||||
public GeneralNames getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relative distribution point name or null if not set.
|
||||
*/
|
||||
public RDN getRelativeName() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reason flags or null if not set.
|
||||
*/
|
||||
public boolean[] getReasonFlags() {
|
||||
return reasonFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CRL issuer name or null if not set.
|
||||
*/
|
||||
public GeneralNames getCRLIssuer() {
|
||||
return crlIssuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the DistributionPoint value to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
|
||||
// NOTE: only one of pointNames and pointRDN can be set
|
||||
if ((fullName != null) || (relativeName != null)) {
|
||||
DerOutputStream distributionPoint = new DerOutputStream();
|
||||
if (fullName != null) {
|
||||
DerOutputStream derOut = new DerOutputStream();
|
||||
fullName.encode(derOut);
|
||||
distributionPoint.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_FULL_NAME),
|
||||
derOut);
|
||||
} else if (relativeName != null) {
|
||||
DerOutputStream derOut = new DerOutputStream();
|
||||
relativeName.encode(derOut);
|
||||
distributionPoint.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_REL_NAME),
|
||||
derOut);
|
||||
}
|
||||
tagged.write(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_DIST_PT),
|
||||
distributionPoint);
|
||||
}
|
||||
if (reasonFlags != null) {
|
||||
DerOutputStream reasons = new DerOutputStream();
|
||||
BitArray rf = new BitArray(reasonFlags);
|
||||
reasons.putTruncatedUnalignedBitString(rf);
|
||||
tagged.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, false, TAG_REASONS),
|
||||
reasons);
|
||||
}
|
||||
if (crlIssuer != null) {
|
||||
DerOutputStream issuer = new DerOutputStream();
|
||||
crlIssuer.encode(issuer);
|
||||
tagged.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_ISSUER),
|
||||
issuer);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, tagged);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare an object to this DistributionPoint for equality.
|
||||
*
|
||||
* @param obj Object to be compared to this
|
||||
* @return true if objects match; false otherwise
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof DistributionPoint == false) {
|
||||
return false;
|
||||
}
|
||||
DistributionPoint other = (DistributionPoint)obj;
|
||||
|
||||
boolean equal = Objects.equals(this.fullName, other.fullName)
|
||||
&& Objects.equals(this.relativeName, other.relativeName)
|
||||
&& Objects.equals(this.crlIssuer, other.crlIssuer)
|
||||
&& Arrays.equals(this.reasonFlags, other.reasonFlags);
|
||||
return equal;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hash = hashCode;
|
||||
if (hash == 0) {
|
||||
hash = 1;
|
||||
if (fullName != null) {
|
||||
hash += fullName.hashCode();
|
||||
}
|
||||
if (relativeName != null) {
|
||||
hash += relativeName.hashCode();
|
||||
}
|
||||
if (crlIssuer != null) {
|
||||
hash += crlIssuer.hashCode();
|
||||
}
|
||||
if (reasonFlags != null) {
|
||||
for (int i = 0; i < reasonFlags.length; i++) {
|
||||
if (reasonFlags[i]) {
|
||||
hash += i;
|
||||
}
|
||||
}
|
||||
}
|
||||
hashCode = hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation for reasonFlag bit 'reason'.
|
||||
*/
|
||||
private static String reasonToString(int reason) {
|
||||
if ((reason > 0) && (reason < REASON_STRINGS.length)) {
|
||||
return REASON_STRINGS[reason];
|
||||
}
|
||||
return "Unknown reason " + reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a printable string of the Distribution Point.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (fullName != null) {
|
||||
sb.append("DistributionPoint:\n " + fullName + "\n");
|
||||
}
|
||||
if (relativeName != null) {
|
||||
sb.append("DistributionPoint:\n " + relativeName + "\n");
|
||||
}
|
||||
|
||||
if (reasonFlags != null) {
|
||||
sb.append(" ReasonFlags:\n");
|
||||
for (int i = 0; i < reasonFlags.length; i++) {
|
||||
if (reasonFlags[i]) {
|
||||
sb.append(" " + reasonToString(i) + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (crlIssuer != null) {
|
||||
sb.append(" CRLIssuer:" + crlIssuer + "\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
242
jdkSrc/jdk8/sun/security/x509/DistributionPointName.java
Normal file
242
jdkSrc/jdk8/sun/security/x509/DistributionPointName.java
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.BitArray;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* Represents the DistributionPointName ASN.1 type.
|
||||
*
|
||||
* It is used in the CRL Distribution Points Extension (OID = 2.5.29.31)
|
||||
* and the Issuing Distribution Point Extension (OID = 2.5.29.28).
|
||||
* <p>
|
||||
* Its ASN.1 definition is:
|
||||
* <pre>
|
||||
*
|
||||
* DistributionPointName ::= CHOICE {
|
||||
* fullName [0] GeneralNames,
|
||||
* nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
|
||||
*
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
*
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] INSTANCE OF OTHER-NAME,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER }
|
||||
*
|
||||
* RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Instances of this class are designed to be immutable. However, since this
|
||||
* is an internal API we do not use defensive cloning for values for
|
||||
* performance reasons. It is the responsibility of the consumer to ensure
|
||||
* that no mutable elements are modified.
|
||||
*
|
||||
* @see CRLDistributionPointsExtension
|
||||
* @see IssuingDistributionPointExtension
|
||||
* @since 1.6
|
||||
*/
|
||||
public class DistributionPointName {
|
||||
|
||||
// ASN.1 context specific tag values
|
||||
private static final byte TAG_FULL_NAME = 0;
|
||||
private static final byte TAG_RELATIVE_NAME = 1;
|
||||
|
||||
// Only one of fullName and relativeName can be set
|
||||
private GeneralNames fullName = null;
|
||||
private RDN relativeName = null;
|
||||
|
||||
// Cached hashCode value
|
||||
private volatile int hashCode;
|
||||
|
||||
/**
|
||||
* Creates a distribution point name using a full name.
|
||||
*
|
||||
* @param fullName the name for the distribution point.
|
||||
* @exception IllegalArgumentException if <code>fullName</code> is null.
|
||||
*/
|
||||
public DistributionPointName(GeneralNames fullName) {
|
||||
|
||||
if (fullName == null) {
|
||||
throw new IllegalArgumentException("fullName must not be null");
|
||||
}
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a distribution point name using a relative name.
|
||||
*
|
||||
* @param relativeName the name of the distribution point relative to
|
||||
* the name of the issuer of the CRL.
|
||||
* @exception IllegalArgumentException if <code>relativeName</code> is null.
|
||||
*/
|
||||
public DistributionPointName(RDN relativeName) {
|
||||
|
||||
if (relativeName == null) {
|
||||
throw new IllegalArgumentException("relativeName must not be null");
|
||||
}
|
||||
this.relativeName = relativeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a distribution point name from its DER-encoded form.
|
||||
*
|
||||
* @param encoding the DER-encoded value.
|
||||
* @throws IOException on decoding error.
|
||||
*/
|
||||
public DistributionPointName(DerValue encoding) throws IOException {
|
||||
|
||||
if (encoding.isContextSpecific(TAG_FULL_NAME) &&
|
||||
encoding.isConstructed()) {
|
||||
|
||||
encoding.resetTag(DerValue.tag_Sequence);
|
||||
fullName = new GeneralNames(encoding);
|
||||
|
||||
} else if (encoding.isContextSpecific(TAG_RELATIVE_NAME) &&
|
||||
encoding.isConstructed()) {
|
||||
|
||||
encoding.resetTag(DerValue.tag_Set);
|
||||
relativeName = new RDN(encoding);
|
||||
|
||||
} else {
|
||||
throw new IOException("Invalid encoding for DistributionPointName");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full name for the distribution point or null if not set.
|
||||
*/
|
||||
public GeneralNames getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the relative name for the distribution point or null if not set.
|
||||
*/
|
||||
public RDN getRelativeName() {
|
||||
return relativeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the distribution point name and writes it to the DerOutputStream.
|
||||
*
|
||||
* @param out the output stream.
|
||||
* @exception IOException on encoding error.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
|
||||
DerOutputStream theChoice = new DerOutputStream();
|
||||
|
||||
if (fullName != null) {
|
||||
fullName.encode(theChoice);
|
||||
out.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_FULL_NAME),
|
||||
theChoice);
|
||||
|
||||
} else {
|
||||
relativeName.encode(theChoice);
|
||||
out.writeImplicit(
|
||||
DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_RELATIVE_NAME),
|
||||
theChoice);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare an object to this distribution point name for equality.
|
||||
*
|
||||
* @param obj Object to be compared to this
|
||||
* @return true if objects match; false otherwise
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof DistributionPointName == false) {
|
||||
return false;
|
||||
}
|
||||
DistributionPointName other = (DistributionPointName)obj;
|
||||
|
||||
return Objects.equals(this.fullName, other.fullName) &&
|
||||
Objects.equals(this.relativeName, other.relativeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this distribution point name.
|
||||
*
|
||||
* @return the hash code.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int hash = hashCode;
|
||||
if (hash == 0) {
|
||||
hash = 1;
|
||||
if (fullName != null) {
|
||||
hash += fullName.hashCode();
|
||||
|
||||
} else {
|
||||
hash += relativeName.hashCode();
|
||||
}
|
||||
hashCode = hash;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable string of the distribution point name.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (fullName != null) {
|
||||
sb.append("DistributionPointName:\n " + fullName + "\n");
|
||||
|
||||
} else {
|
||||
sb.append("DistributionPointName:\n " + relativeName + "\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
257
jdkSrc/jdk8/sun/security/x509/EDIPartyName.java
Normal file
257
jdkSrc/jdk8/sun/security/x509/EDIPartyName.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the EDIPartyName of the GeneralName choice.
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* EDIPartyName ::= SEQUENCE {
|
||||
* nameAssigner [0] DirectoryString OPTIONAL,
|
||||
* partyName [1] DirectoryString }
|
||||
* </pre>
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
* @see GeneralName
|
||||
* @see GeneralNames
|
||||
* @see GeneralNameInterface
|
||||
*/
|
||||
public class EDIPartyName implements GeneralNameInterface {
|
||||
|
||||
// Private data members
|
||||
private static final byte TAG_ASSIGNER = 0;
|
||||
private static final byte TAG_PARTYNAME = 1;
|
||||
|
||||
private String assigner = null;
|
||||
private String party = null;
|
||||
|
||||
private int myhash = -1;
|
||||
|
||||
/**
|
||||
* Create the EDIPartyName object from the specified names.
|
||||
*
|
||||
* @param assignerName the name of the assigner
|
||||
* @param partyName the name of the EDI party.
|
||||
*/
|
||||
public EDIPartyName(String assignerName, String partyName) {
|
||||
this.assigner = assignerName;
|
||||
this.party = partyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the EDIPartyName object from the specified name.
|
||||
*
|
||||
* @param partyName the name of the EDI party.
|
||||
*/
|
||||
public EDIPartyName(String partyName) {
|
||||
this.party = partyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the EDIPartyName object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER EDIPartyName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public EDIPartyName(DerValue derValue) throws IOException {
|
||||
DerInputStream in = new DerInputStream(derValue.toByteArray());
|
||||
DerValue[] seq = in.getSequence(2);
|
||||
|
||||
int len = seq.length;
|
||||
if (len < 1 || len > 2)
|
||||
throw new IOException("Invalid encoding of EDIPartyName");
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
DerValue opt = seq[i];
|
||||
if (opt.isContextSpecific(TAG_ASSIGNER) &&
|
||||
!opt.isConstructed()) {
|
||||
if (assigner != null)
|
||||
throw new IOException("Duplicate nameAssigner found in"
|
||||
+ " EDIPartyName");
|
||||
opt = opt.data.getDerValue();
|
||||
assigner = opt.getAsString();
|
||||
}
|
||||
if (opt.isContextSpecific(TAG_PARTYNAME) &&
|
||||
!opt.isConstructed()) {
|
||||
if (party != null)
|
||||
throw new IOException("Duplicate partyName found in"
|
||||
+ " EDIPartyName");
|
||||
opt = opt.data.getDerValue();
|
||||
party = opt.getAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return (GeneralNameInterface.NAME_EDI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the EDI party name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the EDIPartyName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (assigner != null) {
|
||||
DerOutputStream tmp2 = new DerOutputStream();
|
||||
// XXX - shd check is chars fit into PrintableString
|
||||
tmp2.putPrintableString(assigner);
|
||||
tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_ASSIGNER), tmp2);
|
||||
}
|
||||
if (party == null)
|
||||
throw new IOException("Cannot have null partyName");
|
||||
|
||||
// XXX - shd check is chars fit into PrintableString
|
||||
tmp.putPrintableString(party);
|
||||
tagged.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_PARTYNAME), tmp);
|
||||
|
||||
out.write(DerValue.tag_Sequence, tagged);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the assignerName
|
||||
*
|
||||
* @returns String assignerName
|
||||
*/
|
||||
public String getAssignerName() {
|
||||
return assigner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the partyName
|
||||
*
|
||||
* @returns String partyName
|
||||
*/
|
||||
public String getPartyName() {
|
||||
return party;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this EDIPartyName with another. Does a byte-string
|
||||
* comparison without regard to type of the partyName and
|
||||
* the assignerName.
|
||||
*
|
||||
* @returns true if the two names match
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof EDIPartyName))
|
||||
return false;
|
||||
String otherAssigner = ((EDIPartyName)other).assigner;
|
||||
if (this.assigner == null) {
|
||||
if (otherAssigner != null)
|
||||
return false;
|
||||
} else {
|
||||
if (!(this.assigner.equals(otherAssigner)))
|
||||
return false;
|
||||
}
|
||||
String otherParty = ((EDIPartyName)other).party;
|
||||
if (this.party == null) {
|
||||
if (otherParty != null)
|
||||
return false;
|
||||
} else {
|
||||
if (!(this.party.equals(otherParty)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this EDIPartyName.
|
||||
*
|
||||
* @return a hash code value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (myhash == -1) {
|
||||
myhash = 37 + (party == null ? 1 : party.hashCode());
|
||||
if (assigner != null) {
|
||||
myhash = 37 * myhash + assigner.hashCode();
|
||||
}
|
||||
}
|
||||
return myhash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("EDIPartyName: " +
|
||||
((assigner == null) ? "" :
|
||||
(" nameAssigner = " + assigner + ","))
|
||||
+ " partyName = " + party);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return constraint type:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain)
|
||||
* <li>NAME_MATCH = 0: input name matches name
|
||||
* <li>NAME_NARROWS = 1: input name narrows name
|
||||
* <li>NAME_WIDENS = 2: input name widens name
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
*
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is same type, but comparison operations are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != NAME_EDI)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else {
|
||||
throw new UnsupportedOperationException("Narrowing, widening, and matching of names not supported for EDIPartyName");
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("subtreeDepth() not supported for EDIPartyName");
|
||||
}
|
||||
|
||||
}
|
||||
313
jdkSrc/jdk8/sun/security/x509/ExtendedKeyUsageExtension.java
Normal file
313
jdkSrc/jdk8/sun/security/x509/ExtendedKeyUsageExtension.java
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
|
||||
/**
|
||||
* This class defines the Extended Key Usage Extension, which
|
||||
* indicates one or more purposes for which the certified public key
|
||||
* may be used, in addition to or in place of the basic purposes
|
||||
* indicated in the key usage extension field. This field is defined
|
||||
* as follows:<p>
|
||||
*
|
||||
* id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}<p>
|
||||
*
|
||||
* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId<p>
|
||||
*
|
||||
* KeyPurposeId ::= OBJECT IDENTIFIER<p>
|
||||
*
|
||||
* Key purposes may be defined by any organization with a need. Object
|
||||
* identifiers used to identify key purposes shall be assigned in
|
||||
* accordance with IANA or ITU-T Rec. X.660 | ISO/IEC/ITU 9834-1.<p>
|
||||
*
|
||||
* This extension may, at the option of the certificate issuer, be
|
||||
* either critical or non-critical.<p>
|
||||
*
|
||||
* If the extension is flagged critical, then the certificate MUST be
|
||||
* used only for one of the purposes indicated.<p>
|
||||
*
|
||||
* If the extension is flagged non-critical, then it indicates the
|
||||
* intended purpose or purposes of the key, and may be used in finding
|
||||
* the correct key/certificate of an entity that has multiple
|
||||
* keys/certificates. It is an advisory field and does not imply that
|
||||
* usage of the key is restricted by the certification authority to
|
||||
* the purpose indicated. Certificate using applications may
|
||||
* nevertheless require that a particular purpose be indicated in
|
||||
* order for the certificate to be acceptable to that application.<p>
|
||||
|
||||
* If a certificate contains both a critical key usage field and a
|
||||
* critical extended key usage field, then both fields MUST be
|
||||
* processed independently and the certificate MUST only be used for a
|
||||
* purpose consistent with both fields. If there is no purpose
|
||||
* consistent with both fields, then the certificate MUST NOT be used
|
||||
* for any purpose.<p>
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public class ExtendedKeyUsageExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.ExtendedKeyUsage";
|
||||
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "ExtendedKeyUsage";
|
||||
public static final String USAGES = "usages";
|
||||
|
||||
// OID defined in RFC 5280 Sections 4.2.1.12
|
||||
// more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
|
||||
private static final Map <ObjectIdentifier, String> map =
|
||||
new HashMap <ObjectIdentifier, String> ();
|
||||
|
||||
private static final int[] anyExtendedKeyUsageOidData = {2, 5, 29, 37, 0};
|
||||
private static final int[] serverAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 1};
|
||||
private static final int[] clientAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 2};
|
||||
private static final int[] codeSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 3};
|
||||
private static final int[] emailProtectionOidData = {1, 3, 6, 1, 5, 5, 7, 3, 4};
|
||||
private static final int[] ipsecEndSystemOidData = {1, 3, 6, 1, 5, 5, 7, 3, 5};
|
||||
private static final int[] ipsecTunnelOidData = {1, 3, 6, 1, 5, 5, 7, 3, 6};
|
||||
private static final int[] ipsecUserOidData = {1, 3, 6, 1, 5, 5, 7, 3, 7};
|
||||
private static final int[] timeStampingOidData = {1, 3, 6, 1, 5, 5, 7, 3, 8};
|
||||
private static final int[] OCSPSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 9};
|
||||
|
||||
static {
|
||||
map.put(ObjectIdentifier.newInternal(anyExtendedKeyUsageOidData), "anyExtendedKeyUsage");
|
||||
map.put(ObjectIdentifier.newInternal(serverAuthOidData), "serverAuth");
|
||||
map.put(ObjectIdentifier.newInternal(clientAuthOidData), "clientAuth");
|
||||
map.put(ObjectIdentifier.newInternal(codeSigningOidData), "codeSigning");
|
||||
map.put(ObjectIdentifier.newInternal(emailProtectionOidData), "emailProtection");
|
||||
map.put(ObjectIdentifier.newInternal(ipsecEndSystemOidData), "ipsecEndSystem");
|
||||
map.put(ObjectIdentifier.newInternal(ipsecTunnelOidData), "ipsecTunnel");
|
||||
map.put(ObjectIdentifier.newInternal(ipsecUserOidData), "ipsecUser");
|
||||
map.put(ObjectIdentifier.newInternal(timeStampingOidData), "timeStamping");
|
||||
map.put(ObjectIdentifier.newInternal(OCSPSigningOidData), "OCSPSigning");
|
||||
};
|
||||
|
||||
/**
|
||||
* Vector of KeyUsages for this object.
|
||||
*/
|
||||
private Vector<ObjectIdentifier> keyUsages;
|
||||
|
||||
// Encode this extension value.
|
||||
private void encodeThis() throws IOException {
|
||||
if (keyUsages == null || keyUsages.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
for (int i = 0; i < keyUsages.size(); i++) {
|
||||
tmp.putOID(keyUsages.elementAt(i));
|
||||
}
|
||||
|
||||
os.write(DerValue.tag_Sequence, tmp);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ExtendedKeyUsageExtension object from
|
||||
* a Vector of Key Usages; the criticality is set to false.
|
||||
*
|
||||
* @param keyUsages the Vector of KeyUsages (ObjectIdentifiers)
|
||||
*/
|
||||
public ExtendedKeyUsageExtension(Vector<ObjectIdentifier> keyUsages)
|
||||
throws IOException {
|
||||
this(Boolean.FALSE, keyUsages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ExtendedKeyUsageExtension object from
|
||||
* a Vector of KeyUsages with specified criticality.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param keyUsages the Vector of KeyUsages (ObjectIdentifiers)
|
||||
*/
|
||||
public ExtendedKeyUsageExtension(Boolean critical, Vector<ObjectIdentifier> keyUsages)
|
||||
throws IOException {
|
||||
this.keyUsages = keyUsages;
|
||||
this.extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from its DER encoded value and criticality.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public ExtendedKeyUsageExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"ExtendedKeyUsageExtension.");
|
||||
}
|
||||
keyUsages = new Vector<ObjectIdentifier>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
ObjectIdentifier usage = seq.getOID();
|
||||
keyUsages.addElement(usage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
if (keyUsages == null) return "";
|
||||
String usage = " ";
|
||||
boolean first = true;
|
||||
for (ObjectIdentifier oid: keyUsages) {
|
||||
if(!first) {
|
||||
usage += "\n ";
|
||||
}
|
||||
|
||||
String result = map.get(oid);
|
||||
if (result != null) {
|
||||
usage += result;
|
||||
} else {
|
||||
usage += oid.toString();
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
return super.toString() + "ExtendedKeyUsages [\n"
|
||||
+ usage + "\n]\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with instanceof
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(USAGES)) {
|
||||
if (!(obj instanceof Vector)) {
|
||||
throw new IOException("Attribute value should be of type Vector.");
|
||||
}
|
||||
this.keyUsages = (Vector<ObjectIdentifier>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:ExtendedKeyUsageExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Vector<ObjectIdentifier> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(USAGES)) {
|
||||
//XXXX May want to consider cloning this
|
||||
return keyUsages;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:ExtendedKeyUsageExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(USAGES)) {
|
||||
keyUsages = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:ExtendedKeyUsageExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(USAGES);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
|
||||
public List<String> getExtendedKeyUsage() {
|
||||
List<String> al = new ArrayList<String>(keyUsages.size());
|
||||
for (ObjectIdentifier oid : keyUsages) {
|
||||
al.add(oid.toString());
|
||||
}
|
||||
return al;
|
||||
}
|
||||
|
||||
}
|
||||
276
jdkSrc/jdk8/sun/security/x509/Extension.java
Normal file
276
jdkSrc/jdk8/sun/security/x509/Extension.java
Normal file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent a X509 Extension Attribute.
|
||||
*
|
||||
* <p>Extensions are additional attributes which can be inserted in a X509
|
||||
* v3 certificate. For example a "Driving License Certificate" could have
|
||||
* the driving license number as a extension.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
* <pre>
|
||||
* ASN.1 definition of Extension:
|
||||
* Extension ::= SEQUENCE {
|
||||
* ExtensionId OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extensionValue OCTET STRING
|
||||
* }
|
||||
* </pre>
|
||||
* All subclasses need to implement a constructor of the form
|
||||
* <pre>
|
||||
* <subclass> (Boolean, Object)
|
||||
* </pre>
|
||||
* where the Object is typically an array of DER encoded bytes.
|
||||
* <p>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class Extension implements java.security.cert.Extension {
|
||||
|
||||
protected ObjectIdentifier extensionId = null;
|
||||
protected boolean critical = false;
|
||||
protected byte[] extensionValue = null;
|
||||
|
||||
/**
|
||||
* Default constructor. Used only by sub-classes.
|
||||
*/
|
||||
public Extension() { }
|
||||
|
||||
/**
|
||||
* Constructs an extension from a DER encoded array of bytes.
|
||||
*/
|
||||
public Extension(DerValue derVal) throws IOException {
|
||||
|
||||
DerInputStream in = derVal.toDerInputStream();
|
||||
|
||||
// Object identifier
|
||||
extensionId = in.getOID();
|
||||
|
||||
// If the criticality flag was false, it will not have been encoded.
|
||||
DerValue val = in.getDerValue();
|
||||
if (val.tag == DerValue.tag_Boolean) {
|
||||
critical = val.getBoolean();
|
||||
|
||||
// Extension value (DER encoded)
|
||||
val = in.getDerValue();
|
||||
extensionValue = val.getOctetString();
|
||||
} else {
|
||||
critical = false;
|
||||
extensionValue = val.getOctetString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an Extension from individual components of ObjectIdentifier,
|
||||
* criticality and the DER encoded OctetString.
|
||||
*
|
||||
* @param extensionId the ObjectIdentifier of the extension
|
||||
* @param critical the boolean indicating if the extension is critical
|
||||
* @param extensionValue the DER encoded octet string of the value.
|
||||
*/
|
||||
public Extension(ObjectIdentifier extensionId, boolean critical,
|
||||
byte[] extensionValue) throws IOException {
|
||||
this.extensionId = extensionId;
|
||||
this.critical = critical;
|
||||
// passed in a DER encoded octet string, strip off the tag
|
||||
// and length
|
||||
DerValue inDerVal = new DerValue(extensionValue);
|
||||
this.extensionValue = inDerVal.getOctetString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an Extension from another extension. To be used for
|
||||
* creating decoded subclasses.
|
||||
*
|
||||
* @param ext the extension to create from.
|
||||
*/
|
||||
public Extension(Extension ext) {
|
||||
this.extensionId = ext.extensionId;
|
||||
this.critical = ext.critical;
|
||||
this.extensionValue = ext.extensionValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an Extension from individual components of ObjectIdentifier,
|
||||
* criticality and the raw encoded extension value.
|
||||
*
|
||||
* @param extensionId the ObjectIdentifier of the extension
|
||||
* @param critical the boolean indicating if the extension is critical
|
||||
* @param rawExtensionValue the raw DER-encoded extension value (this
|
||||
* is not the encoded OctetString).
|
||||
*/
|
||||
public static Extension newExtension(ObjectIdentifier extensionId,
|
||||
boolean critical, byte[] rawExtensionValue) throws IOException {
|
||||
Extension ext = new Extension();
|
||||
ext.extensionId = extensionId;
|
||||
ext.critical = critical;
|
||||
ext.extensionValue = rawExtensionValue;
|
||||
return ext;
|
||||
}
|
||||
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
if (out == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
DerOutputStream dos1 = new DerOutputStream();
|
||||
DerOutputStream dos2 = new DerOutputStream();
|
||||
|
||||
dos1.putOID(extensionId);
|
||||
if (critical) {
|
||||
dos1.putBoolean(critical);
|
||||
}
|
||||
dos1.putOctetString(extensionValue);
|
||||
|
||||
dos2.write(DerValue.tag_Sequence, dos1);
|
||||
out.write(dos2.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
|
||||
if (extensionId == null)
|
||||
throw new IOException("Null OID to encode for the extension!");
|
||||
if (extensionValue == null)
|
||||
throw new IOException("No value to encode for the extension!");
|
||||
|
||||
DerOutputStream dos = new DerOutputStream();
|
||||
|
||||
dos.putOID(extensionId);
|
||||
if (critical)
|
||||
dos.putBoolean(critical);
|
||||
dos.putOctetString(extensionValue);
|
||||
|
||||
out.write(DerValue.tag_Sequence, dos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if extension is critical.
|
||||
*/
|
||||
public boolean isCritical() {
|
||||
return critical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ObjectIdentifier of the extension.
|
||||
*/
|
||||
public ObjectIdentifier getExtensionId() {
|
||||
return extensionId;
|
||||
}
|
||||
|
||||
public byte[] getValue() {
|
||||
return extensionValue.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension value as an byte array for further processing.
|
||||
* Note, this is the raw DER value of the extension, not the DER
|
||||
* encoded octet string which is in the certificate.
|
||||
* This method does not return a clone; it is the responsibility of the
|
||||
* caller to clone the array if necessary.
|
||||
*/
|
||||
public byte[] getExtensionValue() {
|
||||
return extensionValue;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return extensionId.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Extension in user readable form.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "ObjectId: " + extensionId.toString();
|
||||
if (critical) {
|
||||
s += " Criticality=true\n";
|
||||
} else {
|
||||
s += " Criticality=false\n";
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
// Value to mix up the hash
|
||||
private static final int hashMagic = 31;
|
||||
|
||||
/**
|
||||
* Returns a hashcode value for this Extension.
|
||||
*
|
||||
* @return the hashcode value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
if (extensionValue != null) {
|
||||
byte[] val = extensionValue;
|
||||
int len = val.length;
|
||||
while (len > 0)
|
||||
h += len * val[--len];
|
||||
}
|
||||
h = h * hashMagic + extensionId.hashCode();
|
||||
h = h * hashMagic + (critical?1231:1237);
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this Extension for equality with the specified
|
||||
* object. If the <code>other</code> object is an
|
||||
* <code>instanceof</code> <code>Extension</code>, then
|
||||
* its encoded form is retrieved and compared with the
|
||||
* encoded form of this Extension.
|
||||
*
|
||||
* @param other the object to test for equality with this Extension.
|
||||
* @return true iff the other object is of type Extension, and the
|
||||
* criticality flag, object identifier and encoded extension value of
|
||||
* the two Extensions match, false otherwise.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
if (!(other instanceof Extension))
|
||||
return false;
|
||||
Extension otherExt = (Extension) other;
|
||||
if (critical != otherExt.critical)
|
||||
return false;
|
||||
if (!extensionId.equals((Object)otherExt.extensionId))
|
||||
return false;
|
||||
return Arrays.equals(extensionValue, otherExt.extensionValue);
|
||||
}
|
||||
}
|
||||
99
jdkSrc/jdk8/sun/security/x509/FreshestCRLExtension.java
Normal file
99
jdkSrc/jdk8/sun/security/x509/FreshestCRLExtension.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represents the Freshest CRL Extension.
|
||||
*
|
||||
* <p>
|
||||
* The extension identifies how delta CRL information for a
|
||||
* complete CRL is obtained.
|
||||
*
|
||||
* <p>
|
||||
* The extension is defined in Section 5.2.6 of
|
||||
* <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
|
||||
ate and Certificate Revocation List (CRL) Profile</a>.
|
||||
*
|
||||
* <p>
|
||||
* Its ASN.1 definition is as follows:
|
||||
* <pre>
|
||||
* id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
|
||||
*
|
||||
* FreshestCRL ::= CRLDistributionPoints
|
||||
* </pre>
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class FreshestCRLExtension extends CRLDistributionPointsExtension {
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "FreshestCRL";
|
||||
|
||||
/**
|
||||
* Creates a freshest CRL extension.
|
||||
* The criticality is set to false.
|
||||
*
|
||||
* @param distributionPoints the list of delta CRL distribution points.
|
||||
*/
|
||||
public FreshestCRLExtension(List<DistributionPoint> distributionPoints)
|
||||
throws IOException {
|
||||
|
||||
super(PKIXExtensions.FreshestCRL_Id, false, distributionPoints, NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception IOException on decoding error.
|
||||
*/
|
||||
public FreshestCRLExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
super(PKIXExtensions.FreshestCRL_Id, critical.booleanValue(), value,
|
||||
NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
super.encode(out, PKIXExtensions.FreshestCRL_Id, false);
|
||||
}
|
||||
}
|
||||
249
jdkSrc/jdk8/sun/security/x509/GeneralName.java
Normal file
249
jdkSrc/jdk8/sun/security/x509/GeneralName.java
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the ASN.1 GeneralName object class.
|
||||
* <p>
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* GeneralName ::= CHOICE {
|
||||
* otherName [0] OtherName,
|
||||
* rfc822Name [1] IA5String,
|
||||
* dNSName [2] IA5String,
|
||||
* x400Address [3] ORAddress,
|
||||
* directoryName [4] Name,
|
||||
* ediPartyName [5] EDIPartyName,
|
||||
* uniformResourceIdentifier [6] IA5String,
|
||||
* iPAddress [7] OCTET STRING,
|
||||
* registeredID [8] OBJECT IDENTIFIER
|
||||
* }
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class GeneralName {
|
||||
|
||||
// Private data members
|
||||
private GeneralNameInterface name = null;
|
||||
|
||||
/**
|
||||
* Default constructor for the class.
|
||||
*
|
||||
* @param name the selected CHOICE from the list.
|
||||
* @throws NullPointerException if name is null
|
||||
*/
|
||||
public GeneralName(GeneralNameInterface name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException("GeneralName must not be null");
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from its DER encoded value.
|
||||
*
|
||||
* @param encName the DER encoded GeneralName.
|
||||
*/
|
||||
public GeneralName(DerValue encName) throws IOException {
|
||||
this(encName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from its DER encoded value.
|
||||
*
|
||||
* @param encName the DER encoded GeneralName.
|
||||
* @param nameConstraint true if general name is a name constraint
|
||||
*/
|
||||
public GeneralName(DerValue encName, boolean nameConstraint)
|
||||
throws IOException {
|
||||
short tag = (byte)(encName.tag & 0x1f);
|
||||
|
||||
// All names except for NAME_DIRECTORY should be encoded with the
|
||||
// IMPLICIT tag.
|
||||
switch (tag) {
|
||||
case GeneralNameInterface.NAME_ANY:
|
||||
if (encName.isContextSpecific() && encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_Sequence);
|
||||
name = new OtherName(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of Other-Name");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_RFC822:
|
||||
if (encName.isContextSpecific() && !encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_IA5String);
|
||||
name = new RFC822Name(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of RFC822 name");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_DNS:
|
||||
if (encName.isContextSpecific() && !encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_IA5String);
|
||||
name = new DNSName(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of DNSName");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_URI:
|
||||
if (encName.isContextSpecific() && !encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_IA5String);
|
||||
name = (nameConstraint ? URIName.nameConstraint(encName) :
|
||||
new URIName(encName));
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of URI");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_IP:
|
||||
if (encName.isContextSpecific() && !encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_OctetString);
|
||||
name = new IPAddressName(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of IP address");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_OID:
|
||||
if (encName.isContextSpecific() && !encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_ObjectId);
|
||||
name = new OIDName(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of OID name");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_DIRECTORY:
|
||||
if (encName.isContextSpecific() && encName.isConstructed()) {
|
||||
name = new X500Name(encName.getData());
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of Directory name");
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneralNameInterface.NAME_EDI:
|
||||
if (encName.isContextSpecific() && encName.isConstructed()) {
|
||||
encName.resetTag(DerValue.tag_Sequence);
|
||||
name = new EDIPartyName(encName);
|
||||
} else {
|
||||
throw new IOException("Invalid encoding of EDI name");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IOException("Unrecognized GeneralName tag, ("
|
||||
+ tag +")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the general name.
|
||||
*/
|
||||
public int getType() {
|
||||
return name.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the GeneralNameInterface name.
|
||||
*/
|
||||
public GeneralNameInterface getName() {
|
||||
//XXXX May want to consider cloning this
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name as user readable string
|
||||
*/
|
||||
public String toString() {
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this GeneralName with another
|
||||
*
|
||||
* @param other GeneralName to compare to this
|
||||
* @returns true if match
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof GeneralName))
|
||||
return false;
|
||||
GeneralNameInterface otherGNI = ((GeneralName)other).name;
|
||||
try {
|
||||
return name.constrains(otherGNI) == GeneralNameInterface.NAME_MATCH;
|
||||
} catch (UnsupportedOperationException ioe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this GeneralName.
|
||||
*
|
||||
* @return a hash code value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the name to the specified DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to encode the the GeneralName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
name.encode(tmp);
|
||||
int nameType = name.getType();
|
||||
if (nameType == GeneralNameInterface.NAME_ANY ||
|
||||
nameType == GeneralNameInterface.NAME_X400 ||
|
||||
nameType == GeneralNameInterface.NAME_EDI) {
|
||||
|
||||
// implicit, constructed form
|
||||
out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)nameType), tmp);
|
||||
} else if (nameType == GeneralNameInterface.NAME_DIRECTORY) {
|
||||
// explicit, constructed form since underlying tag is CHOICE
|
||||
// (see X.680 section 30.6, part c)
|
||||
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, (byte)nameType), tmp);
|
||||
} else {
|
||||
// implicit, primitive form
|
||||
out.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, (byte)nameType), tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
jdkSrc/jdk8/sun/security/x509/GeneralNameInterface.java
Normal file
103
jdkSrc/jdk8/sun/security/x509/GeneralNameInterface.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This interface specifies the abstract methods which have to be
|
||||
* implemented by all the members of the GeneralNames ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public interface GeneralNameInterface {
|
||||
/**
|
||||
* The list of names supported.
|
||||
*/
|
||||
public static final int NAME_ANY = 0;
|
||||
public static final int NAME_RFC822 = 1;
|
||||
public static final int NAME_DNS = 2;
|
||||
public static final int NAME_X400 = 3;
|
||||
public static final int NAME_DIRECTORY = 4;
|
||||
public static final int NAME_EDI = 5;
|
||||
public static final int NAME_URI = 6;
|
||||
public static final int NAME_IP = 7;
|
||||
public static final int NAME_OID = 8;
|
||||
|
||||
/**
|
||||
* The list of constraint results.
|
||||
*/
|
||||
public static final int NAME_DIFF_TYPE = -1; /* input name is different type from name (i.e. does not constrain) */
|
||||
public static final int NAME_MATCH = 0; /* input name matches name */
|
||||
public static final int NAME_NARROWS = 1; /* input name narrows name */
|
||||
public static final int NAME_WIDENS = 2; /* input name widens name */
|
||||
public static final int NAME_SAME_TYPE = 3; /* input name does not match, narrow, or widen, but is same type */
|
||||
|
||||
/**
|
||||
* Return the type of the general name, as
|
||||
* defined above.
|
||||
*/
|
||||
int getType();
|
||||
|
||||
/**
|
||||
* Encode the name to the specified DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to encode the GeneralName to.
|
||||
* @exception IOException thrown if the GeneralName could not be
|
||||
* encoded.
|
||||
*/
|
||||
void encode(DerOutputStream out) throws IOException;
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
*
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is same type, but comparison operations are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
int subtreeDepth() throws UnsupportedOperationException;
|
||||
}
|
||||
150
jdkSrc/jdk8/sun/security/x509/GeneralNames.java
Normal file
150
jdkSrc/jdk8/sun/security/x509/GeneralNames.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This object class represents the GeneralNames type required in
|
||||
* X509 certificates.
|
||||
* <p>The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
* </pre>
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*
|
||||
*/
|
||||
public class GeneralNames {
|
||||
|
||||
private final List<GeneralName> names;
|
||||
|
||||
/**
|
||||
* Create the GeneralNames, decoding from the passed DerValue.
|
||||
*
|
||||
* @param derVal the DerValue to construct the GeneralNames from.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public GeneralNames(DerValue derVal) throws IOException {
|
||||
this();
|
||||
if (derVal.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for GeneralNames.");
|
||||
}
|
||||
if (derVal.data.available() == 0) {
|
||||
throw new IOException("No data available in "
|
||||
+ "passed DER encoded value.");
|
||||
}
|
||||
// Decode all the GeneralName's
|
||||
while (derVal.data.available() != 0) {
|
||||
DerValue encName = derVal.data.getDerValue();
|
||||
|
||||
GeneralName name = new GeneralName(encName);
|
||||
add(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class.
|
||||
*/
|
||||
public GeneralNames() {
|
||||
names = new ArrayList<GeneralName>();
|
||||
}
|
||||
|
||||
public GeneralNames add(GeneralName name) {
|
||||
if (name == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
names.add(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeneralName get(int index) {
|
||||
return names.get(index);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return names.isEmpty();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return names.size();
|
||||
}
|
||||
|
||||
public Iterator<GeneralName> iterator() {
|
||||
return names.iterator();
|
||||
}
|
||||
|
||||
public List<GeneralName> names() {
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DerOutputStream temp = new DerOutputStream();
|
||||
for (GeneralName gn : names) {
|
||||
gn.encode(temp);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* compare this GeneralNames to other object for equality
|
||||
*
|
||||
* @returns true iff this equals other
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof GeneralNames == false) {
|
||||
return false;
|
||||
}
|
||||
GeneralNames other = (GeneralNames)obj;
|
||||
return this.names.equals(other.names);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return names.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return names.toString();
|
||||
}
|
||||
|
||||
}
|
||||
211
jdkSrc/jdk8/sun/security/x509/GeneralSubtree.java
Normal file
211
jdkSrc/jdk8/sun/security/x509/GeneralSubtree.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the GeneralSubtree ASN.1 object, whose syntax is:
|
||||
* <pre>
|
||||
* GeneralSubtree ::= SEQUENCE {
|
||||
* base GeneralName,
|
||||
* minimum [0] BaseDistance DEFAULT 0,
|
||||
* maximum [1] BaseDistance OPTIONAL
|
||||
* }
|
||||
* BaseDistance ::= INTEGER (0..MAX)
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class GeneralSubtree {
|
||||
private static final byte TAG_MIN = 0;
|
||||
private static final byte TAG_MAX = 1;
|
||||
private static final int MIN_DEFAULT = 0;
|
||||
|
||||
private GeneralName name;
|
||||
private int minimum = MIN_DEFAULT;
|
||||
private int maximum = -1;
|
||||
|
||||
private int myhash = -1;
|
||||
|
||||
/**
|
||||
* The default constructor for the class.
|
||||
*
|
||||
* @params name the GeneralName
|
||||
* @params min the minimum BaseDistance
|
||||
* @params max the maximum BaseDistance
|
||||
*/
|
||||
public GeneralSubtree(GeneralName name, int min, int max) {
|
||||
this.name = name;
|
||||
this.minimum = min;
|
||||
this.maximum = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from its DER encoded form.
|
||||
*
|
||||
* @param val the DER encoded from of the same.
|
||||
*/
|
||||
public GeneralSubtree(DerValue val) throws IOException {
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for GeneralSubtree.");
|
||||
}
|
||||
name = new GeneralName(val.data.getDerValue(), true);
|
||||
|
||||
// NB. this is always encoded with the IMPLICIT tag
|
||||
// The checks only make sense if we assume implicit tagging,
|
||||
// with explicit tagging the form is always constructed.
|
||||
while (val.data.available() != 0) {
|
||||
DerValue opt = val.data.getDerValue();
|
||||
|
||||
if (opt.isContextSpecific(TAG_MIN) && !opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Integer);
|
||||
minimum = opt.getInteger();
|
||||
|
||||
} else if (opt.isContextSpecific(TAG_MAX) && !opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Integer);
|
||||
maximum = opt.getInteger();
|
||||
} else
|
||||
throw new IOException("Invalid encoding of GeneralSubtree.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the GeneralName.
|
||||
*
|
||||
* @return the GeneralName
|
||||
*/
|
||||
public GeneralName getName() {
|
||||
//XXXX May want to consider cloning this
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum BaseDistance.
|
||||
*
|
||||
* @return the minimum BaseDistance. Default is 0 if not set.
|
||||
*/
|
||||
public int getMinimum() {
|
||||
return minimum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum BaseDistance.
|
||||
*
|
||||
* @return the maximum BaseDistance, or -1 if not set.
|
||||
*/
|
||||
public int getMaximum() {
|
||||
return maximum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a printable string of the GeneralSubtree.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "\n GeneralSubtree: [\n" +
|
||||
" GeneralName: " + ((name == null) ? "" : name.toString()) +
|
||||
"\n Minimum: " + minimum;
|
||||
if (maximum == -1) {
|
||||
s += "\t Maximum: undefined";
|
||||
} else
|
||||
s += "\t Maximum: " + maximum;
|
||||
s += " ]\n";
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this GeneralSubtree with another
|
||||
*
|
||||
* @param other GeneralSubtree to compare to this
|
||||
* @returns true if match
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof GeneralSubtree))
|
||||
return false;
|
||||
GeneralSubtree otherGS = (GeneralSubtree)other;
|
||||
if (this.name == null) {
|
||||
if (otherGS.name != null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!((this.name).equals(otherGS.name)))
|
||||
return false;
|
||||
}
|
||||
if (this.minimum != otherGS.minimum)
|
||||
return false;
|
||||
if (this.maximum != otherGS.maximum)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this GeneralSubtree.
|
||||
*
|
||||
* @return a hash code value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (myhash == -1) {
|
||||
myhash = 17;
|
||||
if (name != null) {
|
||||
myhash = 37 * myhash + name.hashCode();
|
||||
}
|
||||
if (minimum != MIN_DEFAULT) {
|
||||
myhash = 37 * myhash + minimum;
|
||||
}
|
||||
if (maximum != -1) {
|
||||
myhash = 37 * myhash + maximum;
|
||||
}
|
||||
}
|
||||
return myhash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the GeneralSubtree.
|
||||
*
|
||||
* @params out the DerOutputStream to encode this object to.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
|
||||
name.encode(seq);
|
||||
|
||||
if (minimum != MIN_DEFAULT) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putInteger(minimum);
|
||||
seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_MIN), tmp);
|
||||
}
|
||||
if (maximum != -1) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putInteger(maximum);
|
||||
seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_MAX), tmp);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, seq);
|
||||
}
|
||||
}
|
||||
525
jdkSrc/jdk8/sun/security/x509/GeneralSubtrees.java
Normal file
525
jdkSrc/jdk8/sun/security/x509/GeneralSubtrees.java
Normal file
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the GeneralSubtrees ASN.1 object.
|
||||
* <p>
|
||||
* The ASN.1 for this is
|
||||
* <pre>
|
||||
* GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||||
* </pre>
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @author Andreas Sterbenz
|
||||
*/
|
||||
public class GeneralSubtrees implements Cloneable {
|
||||
|
||||
private final List<GeneralSubtree> trees;
|
||||
|
||||
// Private variables
|
||||
private static final int NAME_DIFF_TYPE = GeneralNameInterface.NAME_DIFF_TYPE;
|
||||
private static final int NAME_MATCH = GeneralNameInterface.NAME_MATCH;
|
||||
private static final int NAME_NARROWS = GeneralNameInterface.NAME_NARROWS;
|
||||
private static final int NAME_WIDENS = GeneralNameInterface.NAME_WIDENS;
|
||||
private static final int NAME_SAME_TYPE = GeneralNameInterface.NAME_SAME_TYPE;
|
||||
|
||||
/**
|
||||
* The default constructor for the class.
|
||||
*/
|
||||
public GeneralSubtrees() {
|
||||
trees = new ArrayList<GeneralSubtree>();
|
||||
}
|
||||
|
||||
private GeneralSubtrees(GeneralSubtrees source) {
|
||||
trees = new ArrayList<GeneralSubtree>(source.trees);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from the passed DER encoded form.
|
||||
*
|
||||
* @param val the DER encoded form of the same.
|
||||
*/
|
||||
public GeneralSubtrees(DerValue val) throws IOException {
|
||||
this();
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding of GeneralSubtrees.");
|
||||
}
|
||||
while (val.data.available() != 0) {
|
||||
DerValue opt = val.data.getDerValue();
|
||||
GeneralSubtree tree = new GeneralSubtree(opt);
|
||||
add(tree);
|
||||
}
|
||||
}
|
||||
|
||||
public GeneralSubtree get(int index) {
|
||||
return trees.get(index);
|
||||
}
|
||||
|
||||
public void remove(int index) {
|
||||
trees.remove(index);
|
||||
}
|
||||
|
||||
public void add(GeneralSubtree tree) {
|
||||
if (tree == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
trees.add(tree);
|
||||
}
|
||||
|
||||
public boolean contains(GeneralSubtree tree) {
|
||||
if (tree == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return trees.contains(tree);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return trees.size();
|
||||
}
|
||||
|
||||
public Iterator<GeneralSubtree> iterator() {
|
||||
return trees.iterator();
|
||||
}
|
||||
|
||||
public List<GeneralSubtree> trees() {
|
||||
return trees;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new GeneralSubtrees(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a printable string of the GeneralSubtree.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = " GeneralSubtrees:\n" + trees.toString() + "\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the GeneralSubtrees.
|
||||
*
|
||||
* @params out the DerOutputStrean to encode this object to.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
|
||||
for (int i = 0, n = size(); i < n; i++) {
|
||||
get(i).encode(seq);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two general subtrees by comparing the subtrees
|
||||
* of each.
|
||||
*
|
||||
* @param other GeneralSubtrees to compare to this
|
||||
* @returns true if match
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof GeneralSubtrees == false) {
|
||||
return false;
|
||||
}
|
||||
GeneralSubtrees other = (GeneralSubtrees)obj;
|
||||
return this.trees.equals(other.trees);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return trees.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the GeneralNameInterface form of the GeneralName in one of
|
||||
* the GeneralSubtrees.
|
||||
*
|
||||
* @param ndx index of the GeneralSubtree from which to obtain the name
|
||||
*/
|
||||
private GeneralNameInterface getGeneralNameInterface(int ndx) {
|
||||
return getGeneralNameInterface(get(ndx));
|
||||
}
|
||||
|
||||
private static GeneralNameInterface getGeneralNameInterface(GeneralSubtree gs) {
|
||||
GeneralName gn = gs.getName();
|
||||
GeneralNameInterface gni = gn.getName();
|
||||
return gni;
|
||||
}
|
||||
|
||||
/**
|
||||
* minimize this GeneralSubtrees by removing all redundant entries.
|
||||
* Internal method used by intersect and reduce.
|
||||
*/
|
||||
private void minimize() {
|
||||
|
||||
// Algorithm: compare each entry n to all subsequent entries in
|
||||
// the list: if any subsequent entry matches or widens entry n,
|
||||
// remove entry n. If any subsequent entries narrow entry n, remove
|
||||
// the subsequent entries.
|
||||
for (int i = 0; i < (size() - 1); i++) {
|
||||
GeneralNameInterface current = getGeneralNameInterface(i);
|
||||
boolean remove1 = false;
|
||||
|
||||
/* compare current to subsequent elements */
|
||||
for (int j = i + 1; j < size(); j++) {
|
||||
GeneralNameInterface subsequent = getGeneralNameInterface(j);
|
||||
switch (current.constrains(subsequent)) {
|
||||
case GeneralNameInterface.NAME_DIFF_TYPE:
|
||||
/* not comparable; different name types; keep checking */
|
||||
continue;
|
||||
case GeneralNameInterface.NAME_MATCH:
|
||||
/* delete one of the duplicates */
|
||||
remove1 = true;
|
||||
break;
|
||||
case GeneralNameInterface.NAME_NARROWS:
|
||||
/* subsequent narrows current */
|
||||
/* remove narrower name (subsequent) */
|
||||
remove(j);
|
||||
j--; /* continue check with new subsequent */
|
||||
continue;
|
||||
case GeneralNameInterface.NAME_WIDENS:
|
||||
/* subsequent widens current */
|
||||
/* remove narrower name current */
|
||||
remove1 = true;
|
||||
break;
|
||||
case GeneralNameInterface.NAME_SAME_TYPE:
|
||||
/* keep both for now; keep checking */
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
} /* end of this pass of subsequent elements */
|
||||
|
||||
if (remove1) {
|
||||
remove(i);
|
||||
i--; /* check the new i value */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a subtree containing an instance of the input
|
||||
* name type that widens all other names of that type.
|
||||
*
|
||||
* @params name GeneralNameInterface name
|
||||
* @returns GeneralSubtree containing widest name of that type
|
||||
* @throws RuntimeException on error (should not occur)
|
||||
*/
|
||||
private GeneralSubtree createWidestSubtree(GeneralNameInterface name) {
|
||||
try {
|
||||
GeneralName newName;
|
||||
switch (name.getType()) {
|
||||
case GeneralNameInterface.NAME_ANY:
|
||||
// Create new OtherName with same OID as baseName, but
|
||||
// empty value
|
||||
ObjectIdentifier otherOID = ((OtherName)name).getOID();
|
||||
newName = new GeneralName(new OtherName(otherOID, null));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_RFC822:
|
||||
newName = new GeneralName(new RFC822Name(""));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_DNS:
|
||||
newName = new GeneralName(new DNSName(""));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_X400:
|
||||
newName = new GeneralName(new X400Address((byte[])null));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_DIRECTORY:
|
||||
newName = new GeneralName(new X500Name(""));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_EDI:
|
||||
newName = new GeneralName(new EDIPartyName(""));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_URI:
|
||||
newName = new GeneralName(new URIName(""));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_IP:
|
||||
newName = new GeneralName(new IPAddressName((byte[])null));
|
||||
break;
|
||||
case GeneralNameInterface.NAME_OID:
|
||||
newName = new GeneralName
|
||||
(new OIDName(new ObjectIdentifier((int[])null)));
|
||||
break;
|
||||
default:
|
||||
throw new IOException
|
||||
("Unsupported GeneralNameInterface type: " + name.getType());
|
||||
}
|
||||
return new GeneralSubtree(newName, 0, -1);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected error: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* intersect this GeneralSubtrees with other. This function
|
||||
* is used in merging permitted NameConstraints. The operation
|
||||
* is performed as follows:
|
||||
* <ul>
|
||||
* <li>If a name in other narrows all names of the same type in this,
|
||||
* the result will contain the narrower name and none of the
|
||||
* names it narrows.
|
||||
* <li>If a name in other widens all names of the same type in this,
|
||||
* the result will not contain the wider name.
|
||||
* <li>If a name in other does not share the same subtree with any name
|
||||
* of the same type in this, then the name is added to the list
|
||||
* of GeneralSubtrees returned. These names should be added to
|
||||
* the list of names that are specifically excluded. The reason
|
||||
* is that, if the intersection is empty, then no names of that
|
||||
* type are permitted, and the only way to express this in
|
||||
* NameConstraints is to include the name in excludedNames.
|
||||
* <li>If a name in this has no name of the same type in other, then
|
||||
* the result contains the name in this. No name of a given type
|
||||
* means the name type is completely permitted.
|
||||
* <li>If a name in other has no name of the same type in this, then
|
||||
* the result contains the name in other. This means that
|
||||
* the name is now constrained in some way, whereas before it was
|
||||
* completely permitted.
|
||||
* <ul>
|
||||
*
|
||||
* @param other GeneralSubtrees to be intersected with this
|
||||
* @returns GeneralSubtrees to be merged with excluded; these are
|
||||
* empty-valued name types corresponding to entries that were
|
||||
* of the same type but did not share the same subtree between
|
||||
* this and other. Returns null if no such.
|
||||
*/
|
||||
public GeneralSubtrees intersect(GeneralSubtrees other) {
|
||||
|
||||
if (other == null) {
|
||||
throw new NullPointerException("other GeneralSubtrees must not be null");
|
||||
}
|
||||
|
||||
GeneralSubtrees newThis = new GeneralSubtrees();
|
||||
GeneralSubtrees newExcluded = null;
|
||||
|
||||
// Step 1: If this is empty, just add everything in other to this and
|
||||
// return no new excluded entries
|
||||
if (size() == 0) {
|
||||
union(other);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Step 2: For ease of checking the subtrees, minimize them by
|
||||
// constructing versions that contain only the widest instance of
|
||||
// each type
|
||||
this.minimize();
|
||||
other.minimize();
|
||||
|
||||
// Step 3: Check each entry in this to see whether we keep it or
|
||||
// remove it, and whether we add anything to newExcluded or newThis.
|
||||
// We keep an entry in this unless it is narrowed by all entries in
|
||||
// other. We add an entry to newExcluded if there is at least one
|
||||
// entry of the same nameType in other, but this entry does
|
||||
// not share the same subtree with any of the entries in other.
|
||||
// We add an entry from other to newThis if there is no name of the
|
||||
// same type in this.
|
||||
for (int i = 0; i < size(); i++) {
|
||||
GeneralNameInterface thisEntry = getGeneralNameInterface(i);
|
||||
boolean removeThisEntry = false;
|
||||
|
||||
// Step 3a: If the widest name of this type in other narrows
|
||||
// thisEntry, remove thisEntry and add widest other to newThis.
|
||||
// Simultaneously, check for situation where there is a name of
|
||||
// this type in other, but no name in other matches, narrows,
|
||||
// or widens thisEntry.
|
||||
boolean sameType = false;
|
||||
for (int j = 0; j < other.size(); j++) {
|
||||
GeneralSubtree otherEntryGS = other.get(j);
|
||||
GeneralNameInterface otherEntry =
|
||||
getGeneralNameInterface(otherEntryGS);
|
||||
switch (thisEntry.constrains(otherEntry)) {
|
||||
case NAME_NARROWS:
|
||||
remove(i);
|
||||
i--;
|
||||
newThis.add(otherEntryGS);
|
||||
sameType = false;
|
||||
break;
|
||||
case NAME_SAME_TYPE:
|
||||
sameType = true;
|
||||
continue;
|
||||
case NAME_MATCH:
|
||||
case NAME_WIDENS:
|
||||
sameType = false;
|
||||
break;
|
||||
case NAME_DIFF_TYPE:
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Step 3b: If sameType is still true, we have the situation
|
||||
// where there was a name of the same type as thisEntry in
|
||||
// other, but no name in other widened, matched, or narrowed
|
||||
// thisEntry.
|
||||
if (sameType) {
|
||||
|
||||
// Step 3b.1: See if there are any entries in this and other
|
||||
// with this type that match, widen, or narrow each other.
|
||||
// If not, then we need to add a "widest subtree" of this
|
||||
// type to excluded.
|
||||
boolean intersection = false;
|
||||
for (int j = 0; j < size(); j++) {
|
||||
GeneralNameInterface thisAltEntry = getGeneralNameInterface(j);
|
||||
|
||||
if (thisAltEntry.getType() == thisEntry.getType()) {
|
||||
for (int k = 0; k < other.size(); k++) {
|
||||
GeneralNameInterface othAltEntry =
|
||||
other.getGeneralNameInterface(k);
|
||||
|
||||
int constraintType =
|
||||
thisAltEntry.constrains(othAltEntry);
|
||||
if (constraintType == NAME_MATCH ||
|
||||
constraintType == NAME_WIDENS ||
|
||||
constraintType == NAME_NARROWS) {
|
||||
intersection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intersection == false) {
|
||||
if (newExcluded == null) {
|
||||
newExcluded = new GeneralSubtrees();
|
||||
}
|
||||
GeneralSubtree widestSubtree =
|
||||
createWidestSubtree(thisEntry);
|
||||
if (!newExcluded.contains(widestSubtree)) {
|
||||
newExcluded.add(widestSubtree);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3b.2: Remove thisEntry from this
|
||||
remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Add all entries in newThis to this
|
||||
if (newThis.size() > 0) {
|
||||
union(newThis);
|
||||
}
|
||||
|
||||
// Step 5: Add all entries in other that do not have any entry of the
|
||||
// same type in this to this
|
||||
for (int i = 0; i < other.size(); i++) {
|
||||
GeneralSubtree otherEntryGS = other.get(i);
|
||||
GeneralNameInterface otherEntry = getGeneralNameInterface(otherEntryGS);
|
||||
boolean diffType = false;
|
||||
for (int j = 0; j < size(); j++) {
|
||||
GeneralNameInterface thisEntry = getGeneralNameInterface(j);
|
||||
switch (thisEntry.constrains(otherEntry)) {
|
||||
case NAME_DIFF_TYPE:
|
||||
diffType = true;
|
||||
// continue to see if we find something later of the
|
||||
// same type
|
||||
continue;
|
||||
case NAME_NARROWS:
|
||||
case NAME_SAME_TYPE:
|
||||
case NAME_MATCH:
|
||||
case NAME_WIDENS:
|
||||
diffType = false; // we found an entry of the same type
|
||||
// break because we know we won't be adding it to
|
||||
// this now
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (diffType) {
|
||||
add(otherEntryGS);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: Return the newExcluded GeneralSubtrees
|
||||
return newExcluded;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct union of this GeneralSubtrees with other.
|
||||
*
|
||||
* @param other GeneralSubtrees to be united with this
|
||||
*/
|
||||
public void union(GeneralSubtrees other) {
|
||||
if (other != null) {
|
||||
for (int i = 0, n = other.size(); i < n; i++) {
|
||||
add(other.get(i));
|
||||
}
|
||||
// Minimize this
|
||||
minimize();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce this GeneralSubtrees by contents of another. This function
|
||||
* is used in merging excluded NameConstraints with permitted NameConstraints
|
||||
* to obtain a minimal form of permitted NameConstraints. It is an
|
||||
* optimization, and does not affect correctness of the results.
|
||||
*
|
||||
* @param excluded GeneralSubtrees
|
||||
*/
|
||||
public void reduce(GeneralSubtrees excluded) {
|
||||
if (excluded == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0, n = excluded.size(); i < n; i++) {
|
||||
GeneralNameInterface excludedName = excluded.getGeneralNameInterface(i);
|
||||
for (int j = 0; j < size(); j++) {
|
||||
GeneralNameInterface permitted = getGeneralNameInterface(j);
|
||||
switch (excludedName.constrains(permitted)) {
|
||||
case GeneralNameInterface.NAME_DIFF_TYPE:
|
||||
break;
|
||||
case GeneralNameInterface.NAME_MATCH:
|
||||
remove(j);
|
||||
j--;
|
||||
break;
|
||||
case GeneralNameInterface.NAME_NARROWS:
|
||||
/* permitted narrows excluded */
|
||||
remove(j);
|
||||
j--;
|
||||
break;
|
||||
case GeneralNameInterface.NAME_WIDENS:
|
||||
/* permitted widens excluded */
|
||||
break;
|
||||
case GeneralNameInterface.NAME_SAME_TYPE:
|
||||
break;
|
||||
}
|
||||
} /* end of this pass of permitted */
|
||||
} /* end of pass of excluded */
|
||||
}
|
||||
}
|
||||
491
jdkSrc/jdk8/sun/security/x509/IPAddressName.java
Normal file
491
jdkSrc/jdk8/sun/security/x509/IPAddressName.java
Normal file
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.Integer;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.util.BitArray;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* This class implements the IPAddressName as required by the GeneralNames
|
||||
* ASN.1 object. Both IPv4 and IPv6 addresses are supported using the
|
||||
* formats specified in IETF PKIX RFC2459.
|
||||
* <p>
|
||||
* [RFC2459 4.2.1.7 Subject Alternative Name]
|
||||
* When the subjectAltName extension contains a iPAddress, the address
|
||||
* MUST be stored in the octet string in "network byte order," as
|
||||
* specified in RFC 791. The least significant bit (LSB) of
|
||||
* each octet is the LSB of the corresponding byte in the network
|
||||
* address. For IP Version 4, as specified in RFC 791, the octet string
|
||||
* MUST contain exactly four octets. For IP Version 6, as specified in
|
||||
* RFC 1883, the octet string MUST contain exactly sixteen octets.
|
||||
* <p>
|
||||
* [RFC2459 4.2.1.11 Name Constraints]
|
||||
* The syntax of iPAddress MUST be as described in section 4.2.1.7 with
|
||||
* the following additions specifically for Name Constraints. For IPv4
|
||||
* addresses, the ipAddress field of generalName MUST contain eight (8)
|
||||
* octets, encoded in the style of RFC 1519 (CIDR) to represent an
|
||||
* address range.[RFC 1519] For IPv6 addresses, the ipAddress field
|
||||
* MUST contain 32 octets similarly encoded. For example, a name
|
||||
* constraint for "class C" subnet 10.9.8.0 shall be represented as the
|
||||
* octets 0A 09 08 00 FF FF FF 00, representing the CIDR notation
|
||||
* 10.9.8.0/255.255.255.0.
|
||||
* <p>
|
||||
* @see GeneralName
|
||||
* @see GeneralNameInterface
|
||||
* @see GeneralNames
|
||||
*
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class IPAddressName implements GeneralNameInterface {
|
||||
private byte[] address;
|
||||
private boolean isIPv4;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create the IPAddressName object from the passed encoded Der value.
|
||||
*
|
||||
* @params derValue the encoded DER IPAddressName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public IPAddressName(DerValue derValue) throws IOException {
|
||||
this(derValue.getOctetString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the IPAddressName object with the specified octets.
|
||||
*
|
||||
* @params address the IP address
|
||||
* @throws IOException if address is not a valid IPv4 or IPv6 address
|
||||
*/
|
||||
public IPAddressName(byte[] address) throws IOException {
|
||||
/*
|
||||
* A valid address must consist of 4 bytes of address and
|
||||
* optional 4 bytes of 4 bytes of mask, or 16 bytes of address
|
||||
* and optional 16 bytes of mask.
|
||||
*/
|
||||
if (address.length == 4 || address.length == 8) {
|
||||
isIPv4 = true;
|
||||
} else if (address.length == 16 || address.length == 32) {
|
||||
isIPv4 = false;
|
||||
} else {
|
||||
throw new IOException("Invalid IPAddressName");
|
||||
}
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an IPAddressName from a String.
|
||||
* [IETF RFC1338 Supernetting & IETF RFC1519 Classless Inter-Domain
|
||||
* Routing (CIDR)] For IPv4 addresses, the forms are
|
||||
* "b1.b2.b3.b4" or "b1.b2.b3.b4/m1.m2.m3.m4", where b1 - b4 are decimal
|
||||
* byte values 0-255 and m1 - m4 are decimal mask values
|
||||
* 0 - 255.
|
||||
* <p>
|
||||
* [IETF RFC2373 IP Version 6 Addressing Architecture]
|
||||
* For IPv6 addresses, the forms are "a1:a2:...:a8" or "a1:a2:...:a8/n",
|
||||
* where a1-a8 are hexadecimal values representing the eight 16-bit pieces
|
||||
* of the address. If /n is used, n is a decimal number indicating how many
|
||||
* of the leftmost contiguous bits of the address comprise the prefix for
|
||||
* this subnet. Internally, a mask value is created using the prefix length.
|
||||
* <p>
|
||||
* @param name String form of IPAddressName
|
||||
* @throws IOException if name can not be converted to a valid IPv4 or IPv6
|
||||
* address
|
||||
*/
|
||||
public IPAddressName(String name) throws IOException {
|
||||
|
||||
if (name == null || name.length() == 0) {
|
||||
throw new IOException("IPAddress cannot be null or empty");
|
||||
}
|
||||
if (name.charAt(name.length() - 1) == '/') {
|
||||
throw new IOException("Invalid IPAddress: " + name);
|
||||
}
|
||||
|
||||
if (name.indexOf(':') >= 0) {
|
||||
// name is IPv6: uses colons as value separators
|
||||
// Parse name into byte-value address components and optional
|
||||
// prefix
|
||||
parseIPv6(name);
|
||||
isIPv4 = false;
|
||||
} else if (name.indexOf('.') >= 0) {
|
||||
//name is IPv4: uses dots as value separators
|
||||
parseIPv4(name);
|
||||
isIPv4 = true;
|
||||
} else {
|
||||
throw new IOException("Invalid IPAddress: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an IPv4 address.
|
||||
*
|
||||
* @param name IPv4 address with optional mask values
|
||||
* @throws IOException on error
|
||||
*/
|
||||
private void parseIPv4(String name) throws IOException {
|
||||
|
||||
// Parse name into byte-value address components
|
||||
int slashNdx = name.indexOf('/');
|
||||
if (slashNdx == -1) {
|
||||
address = InetAddress.getByName(name).getAddress();
|
||||
} else {
|
||||
address = new byte[8];
|
||||
|
||||
// parse mask
|
||||
byte[] mask = InetAddress.getByName
|
||||
(name.substring(slashNdx+1)).getAddress();
|
||||
|
||||
// parse base address
|
||||
byte[] host = InetAddress.getByName
|
||||
(name.substring(0, slashNdx)).getAddress();
|
||||
|
||||
System.arraycopy(host, 0, address, 0, 4);
|
||||
System.arraycopy(mask, 0, address, 4, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an IPv6 address.
|
||||
*
|
||||
* @param name String IPv6 address with optional /<prefix length>
|
||||
* If /<prefix length> is present, address[] array will
|
||||
* be 32 bytes long, otherwise 16.
|
||||
* @throws IOException on error
|
||||
*/
|
||||
private final static int MASKSIZE = 16;
|
||||
private void parseIPv6(String name) throws IOException {
|
||||
|
||||
int slashNdx = name.indexOf('/');
|
||||
if (slashNdx == -1) {
|
||||
address = InetAddress.getByName(name).getAddress();
|
||||
} else {
|
||||
address = new byte[32];
|
||||
byte[] base = InetAddress.getByName
|
||||
(name.substring(0, slashNdx)).getAddress();
|
||||
System.arraycopy(base, 0, address, 0, 16);
|
||||
|
||||
// append a mask corresponding to the num of prefix bits specified
|
||||
int prefixLen = Integer.parseInt(name.substring(slashNdx+1));
|
||||
if (prefixLen < 0 || prefixLen > 128) {
|
||||
throw new IOException("IPv6Address prefix length (" +
|
||||
prefixLen + ") in out of valid range [0,128]");
|
||||
}
|
||||
|
||||
// create new bit array initialized to zeros
|
||||
BitArray bitArray = new BitArray(MASKSIZE * 8);
|
||||
|
||||
// set all most significant bits up to prefix length
|
||||
for (int i = 0; i < prefixLen; i++)
|
||||
bitArray.set(i, true);
|
||||
byte[] maskArray = bitArray.toByteArray();
|
||||
|
||||
// copy mask bytes into mask portion of address
|
||||
for (int i = 0; i < MASKSIZE; i++)
|
||||
address[MASKSIZE+i] = maskArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return NAME_IP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the IPAddress name into the DerOutputStream.
|
||||
*
|
||||
* @params out the DER stream to encode the IPAddressName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putOctetString(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a printable string of IPaddress
|
||||
*/
|
||||
public String toString() {
|
||||
try {
|
||||
return "IPAddress: " + getName();
|
||||
} catch (IOException ioe) {
|
||||
// dump out hex rep for debugging purposes
|
||||
HexDumpEncoder enc = new HexDumpEncoder();
|
||||
return "IPAddress: " + enc.encodeBuffer(address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a standard String representation of IPAddress.
|
||||
* See IPAddressName(String) for the formats used for IPv4
|
||||
* and IPv6 addresses.
|
||||
*
|
||||
* @throws IOException if the IPAddress cannot be converted to a String
|
||||
*/
|
||||
public String getName() throws IOException {
|
||||
if (name != null)
|
||||
return name;
|
||||
|
||||
if (isIPv4) {
|
||||
//IPv4 address or subdomain
|
||||
byte[] host = new byte[4];
|
||||
System.arraycopy(address, 0, host, 0, 4);
|
||||
name = InetAddress.getByAddress(host).getHostAddress();
|
||||
if (address.length == 8) {
|
||||
byte[] mask = new byte[4];
|
||||
System.arraycopy(address, 4, mask, 0, 4);
|
||||
name = name + "/" +
|
||||
InetAddress.getByAddress(mask).getHostAddress();
|
||||
}
|
||||
} else {
|
||||
//IPv6 address or subdomain
|
||||
byte[] host = new byte[16];
|
||||
System.arraycopy(address, 0, host, 0, 16);
|
||||
name = InetAddress.getByAddress(host).getHostAddress();
|
||||
if (address.length == 32) {
|
||||
// IPv6 subdomain: display prefix length
|
||||
|
||||
// copy subdomain into new array and convert to BitArray
|
||||
byte[] maskBytes = new byte[16];
|
||||
for (int i=16; i < 32; i++)
|
||||
maskBytes[i-16] = address[i];
|
||||
BitArray ba = new BitArray(16*8, maskBytes);
|
||||
// Find first zero bit
|
||||
int i=0;
|
||||
for (; i < 16*8; i++) {
|
||||
if (!ba.get(i))
|
||||
break;
|
||||
}
|
||||
name = name + "/" + i;
|
||||
// Verify remaining bits 0
|
||||
for (; i < 16*8; i++) {
|
||||
if (ba.get(i)) {
|
||||
throw new IOException("Invalid IPv6 subdomain - set " +
|
||||
"bit " + i + " not contiguous");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this IPAddress name as a byte array.
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
return address.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are identical.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof IPAddressName))
|
||||
return false;
|
||||
|
||||
IPAddressName otherName = (IPAddressName)obj;
|
||||
byte[] other = otherName.address;
|
||||
|
||||
if (other.length != address.length)
|
||||
return false;
|
||||
|
||||
if (address.length == 8 || address.length == 32) {
|
||||
// Two subnet addresses
|
||||
// Mask each and compare masked values
|
||||
int maskLen = address.length/2;
|
||||
for (int i=0; i < maskLen; i++) {
|
||||
byte maskedThis = (byte)(address[i] & address[i+maskLen]);
|
||||
byte maskedOther = (byte)(other[i] & other[i+maskLen]);
|
||||
if (maskedThis != maskedOther) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Now compare masks
|
||||
for (int i=maskLen; i < address.length; i++)
|
||||
if (address[i] != other[i])
|
||||
return false;
|
||||
return true;
|
||||
} else {
|
||||
// Two IPv4 host addresses or two IPv6 host addresses
|
||||
// Compare bytes
|
||||
return Arrays.equals(other, address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int retval = 0;
|
||||
|
||||
for (int i=0; i<address.length; i++)
|
||||
retval += address[i] * i;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name
|
||||
* (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming
|
||||
* subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming
|
||||
* subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but
|
||||
* is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
* <p>
|
||||
* [RFC2459] The syntax of iPAddress MUST be as described in section
|
||||
* 4.2.1.7 with the following additions specifically for Name Constraints.
|
||||
* For IPv4 addresses, the ipAddress field of generalName MUST contain
|
||||
* eight (8) octets, encoded in the style of RFC 1519 (CIDR) to represent an
|
||||
* address range.[RFC 1519] For IPv6 addresses, the ipAddress field
|
||||
* MUST contain 32 octets similarly encoded. For example, a name
|
||||
* constraint for "class C" subnet 10.9.8.0 shall be represented as the
|
||||
* octets 0A 09 08 00 FF FF FF 00, representing the CIDR notation
|
||||
* 10.9.8.0/255.255.255.0.
|
||||
* <p>
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is not exact match, but
|
||||
* narrowing and widening are not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName)
|
||||
throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != NAME_IP)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (((IPAddressName)inputName).equals(this))
|
||||
constraintType = NAME_MATCH;
|
||||
else {
|
||||
IPAddressName otherName = (IPAddressName)inputName;
|
||||
byte[] otherAddress = otherName.address;
|
||||
if (otherAddress.length == 4 && address.length == 4)
|
||||
// Two host addresses
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
else if ((otherAddress.length == 8 && address.length == 8) ||
|
||||
(otherAddress.length == 32 && address.length == 32)) {
|
||||
// Two subnet addresses
|
||||
// See if one address fully encloses the other address
|
||||
boolean otherSubsetOfThis = true;
|
||||
boolean thisSubsetOfOther = true;
|
||||
boolean thisEmpty = false;
|
||||
boolean otherEmpty = false;
|
||||
int maskOffset = address.length/2;
|
||||
for (int i=0; i < maskOffset; i++) {
|
||||
if ((byte)(address[i] & address[i+maskOffset]) != address[i])
|
||||
thisEmpty=true;
|
||||
if ((byte)(otherAddress[i] & otherAddress[i+maskOffset]) != otherAddress[i])
|
||||
otherEmpty=true;
|
||||
if (!(((byte)(address[i+maskOffset] & otherAddress[i+maskOffset]) == address[i+maskOffset]) &&
|
||||
((byte)(address[i] & address[i+maskOffset]) == (byte)(otherAddress[i] & address[i+maskOffset])))) {
|
||||
otherSubsetOfThis = false;
|
||||
}
|
||||
if (!(((byte)(otherAddress[i+maskOffset] & address[i+maskOffset]) == otherAddress[i+maskOffset]) &&
|
||||
((byte)(otherAddress[i] & otherAddress[i+maskOffset]) == (byte)(address[i] & otherAddress[i+maskOffset])))) {
|
||||
thisSubsetOfOther = false;
|
||||
}
|
||||
}
|
||||
if (thisEmpty || otherEmpty) {
|
||||
if (thisEmpty && otherEmpty)
|
||||
constraintType = NAME_MATCH;
|
||||
else if (thisEmpty)
|
||||
constraintType = NAME_WIDENS;
|
||||
else
|
||||
constraintType = NAME_NARROWS;
|
||||
} else if (otherSubsetOfThis)
|
||||
constraintType = NAME_NARROWS;
|
||||
else if (thisSubsetOfOther)
|
||||
constraintType = NAME_WIDENS;
|
||||
else
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else if (otherAddress.length == 8 || otherAddress.length == 32) {
|
||||
//Other is a subnet, this is a host address
|
||||
int i = 0;
|
||||
int maskOffset = otherAddress.length/2;
|
||||
for (; i < maskOffset; i++) {
|
||||
// Mask this address by other address mask and compare to other address
|
||||
// If all match, then this address is in other address subnet
|
||||
if ((address[i] & otherAddress[i+maskOffset]) != otherAddress[i])
|
||||
break;
|
||||
}
|
||||
if (i == maskOffset)
|
||||
constraintType = NAME_WIDENS;
|
||||
else
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else if (address.length == 8 || address.length == 32) {
|
||||
//This is a subnet, other is a host address
|
||||
int i = 0;
|
||||
int maskOffset = address.length/2;
|
||||
for (; i < maskOffset; i++) {
|
||||
// Mask other address by this address mask and compare to this address
|
||||
if ((otherAddress[i] & address[i+maskOffset]) != address[i])
|
||||
break;
|
||||
}
|
||||
if (i == maskOffset)
|
||||
constraintType = NAME_NARROWS;
|
||||
else
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException
|
||||
("subtreeDepth() not defined for IPAddressName");
|
||||
}
|
||||
}
|
||||
263
jdkSrc/jdk8/sun/security/x509/InhibitAnyPolicyExtension.java
Normal file
263
jdkSrc/jdk8/sun/security/x509/InhibitAnyPolicyExtension.java
Normal file
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
|
||||
/**
|
||||
* This class represents the Inhibit Any-Policy Extension.
|
||||
*
|
||||
* <p>The inhibit any-policy extension can be used in certificates issued
|
||||
* to CAs. The inhibit any-policy indicates that the special any-policy
|
||||
* OID, with the value {2 5 29 32 0}, is not considered an explicit
|
||||
* match for other certificate policies. The value indicates the number
|
||||
* of additional certificates that may appear in the path before any-
|
||||
* policy is no longer permitted. For example, a value of one indicates
|
||||
* that any-policy may be processed in certificates issued by the sub-
|
||||
* ject of this certificate, but not in additional certificates in the
|
||||
* path.
|
||||
* <p>
|
||||
* This extension MUST be critical.
|
||||
* <p>
|
||||
* The ASN.1 syntax for this extension is:
|
||||
* <code><pre>
|
||||
* id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
|
||||
*
|
||||
* InhibitAnyPolicy ::= SkipCerts
|
||||
*
|
||||
* SkipCerts ::= INTEGER (0..MAX)
|
||||
* </pre></code>
|
||||
* @author Anne Anderson
|
||||
* @see CertAttrSet
|
||||
* @see Extension
|
||||
*/
|
||||
public class InhibitAnyPolicyExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
private static final Debug debug = Debug.getInstance("certpath");
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.InhibitAnyPolicy";
|
||||
|
||||
/**
|
||||
* Object identifier for "any-policy"
|
||||
*/
|
||||
public static ObjectIdentifier AnyPolicy_Id;
|
||||
static {
|
||||
try {
|
||||
AnyPolicy_Id = new ObjectIdentifier("2.5.29.32.0");
|
||||
} catch (IOException ioe) {
|
||||
// Should not happen
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "InhibitAnyPolicy";
|
||||
public static final String SKIP_CERTS = "skip_certs";
|
||||
|
||||
// Private data members
|
||||
private int skipCerts = Integer.MAX_VALUE;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putInteger(skipCerts);
|
||||
this.extensionValue = out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor for this object.
|
||||
*
|
||||
* @param skipCerts specifies the depth of the certification path.
|
||||
* Use value of -1 to request unlimited depth.
|
||||
*/
|
||||
public InhibitAnyPolicyExtension(int skipCerts) throws IOException {
|
||||
if (skipCerts < -1)
|
||||
throw new IOException("Invalid value for skipCerts");
|
||||
if (skipCerts == -1)
|
||||
this.skipCerts = Integer.MAX_VALUE;
|
||||
else
|
||||
this.skipCerts = skipCerts;
|
||||
this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
|
||||
critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical criticality flag to use. Must be true for this
|
||||
* extension.
|
||||
* @param value a byte array holding the DER-encoded extension value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public InhibitAnyPolicyExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
|
||||
this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
|
||||
|
||||
if (!critical.booleanValue())
|
||||
throw new IOException("Criticality cannot be false for " +
|
||||
"InhibitAnyPolicy");
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Integer)
|
||||
throw new IOException("Invalid encoding of InhibitAnyPolicy: "
|
||||
+ "data not integer");
|
||||
|
||||
if (val.data == null)
|
||||
throw new IOException("Invalid encoding of InhibitAnyPolicy: "
|
||||
+ "null data");
|
||||
int skipCertsValue = val.getInteger();
|
||||
if (skipCertsValue < -1)
|
||||
throw new IOException("Invalid value for skipCerts");
|
||||
if (skipCertsValue == -1) {
|
||||
this.skipCerts = Integer.MAX_VALUE;
|
||||
} else {
|
||||
this.skipCerts = skipCertsValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user readable form of extension.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = super.toString() + "InhibitAnyPolicy: " + skipCerts + "\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode this extension value to the output stream.
|
||||
*
|
||||
* @param out the DerOutputStream to encode the extension to.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
|
||||
critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*
|
||||
* @param name name of attribute to set. Must be SKIP_CERTS.
|
||||
* @param obj value to which attribute is to be set. Must be Integer
|
||||
* type.
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(SKIP_CERTS)) {
|
||||
if (!(obj instanceof Integer))
|
||||
throw new IOException("Attribute value should be of type Integer.");
|
||||
int skipCertsValue = ((Integer)obj).intValue();
|
||||
if (skipCertsValue < -1)
|
||||
throw new IOException("Invalid value for skipCerts");
|
||||
if (skipCertsValue == -1) {
|
||||
skipCerts = Integer.MAX_VALUE;
|
||||
} else {
|
||||
skipCerts = skipCertsValue;
|
||||
}
|
||||
} else
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:InhibitAnyPolicy.");
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*
|
||||
* @param name name of attribute to get. Must be SKIP_CERTS.
|
||||
* @returns value of the attribute. In this case it will be of type
|
||||
* Integer.
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public Integer get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(SKIP_CERTS))
|
||||
return (new Integer(skipCerts));
|
||||
else
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:InhibitAnyPolicy.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*
|
||||
* @param name name of attribute to delete. Must be SKIP_CERTS.
|
||||
* @throws IOException on error. In this case, IOException will always be
|
||||
* thrown, because the only attribute, SKIP_CERTS, is
|
||||
* required.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(SKIP_CERTS))
|
||||
throw new IOException("Attribute " + SKIP_CERTS +
|
||||
" may not be deleted.");
|
||||
else
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:InhibitAnyPolicy.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*
|
||||
* @returns enumeration of elements
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(SKIP_CERTS);
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*
|
||||
* @returns name of attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
219
jdkSrc/jdk8/sun/security/x509/InvalidityDateExtension.java
Normal file
219
jdkSrc/jdk8/sun/security/x509/InvalidityDateExtension.java
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* From RFC 5280:
|
||||
* <p>
|
||||
* The invalidity date is a non-critical CRL entry extension that
|
||||
* provides the date on which it is known or suspected that the private
|
||||
* key was compromised or that the certificate otherwise became invalid.
|
||||
* This date may be earlier than the revocation date in the CRL entry,
|
||||
* which is the date at which the CA processed the revocation. When a
|
||||
* revocation is first posted by a CRL issuer in a CRL, the invalidity
|
||||
* date may precede the date of issue of earlier CRLs, but the
|
||||
* revocation date SHOULD NOT precede the date of issue of earlier CRLs.
|
||||
* Whenever this information is available, CRL issuers are strongly
|
||||
* encouraged to share it with CRL users.
|
||||
* <p>
|
||||
* The GeneralizedTime values included in this field MUST be expressed
|
||||
* in Greenwich Mean Time (Zulu), and MUST be specified and interpreted
|
||||
* as defined in section 4.1.2.5.2.
|
||||
* <pre>
|
||||
* id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
|
||||
*
|
||||
* invalidityDate ::= GeneralizedTime
|
||||
* </pre>
|
||||
*
|
||||
* @author Sean Mullan
|
||||
*/
|
||||
public class InvalidityDateExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Attribute name and Reason codes
|
||||
*/
|
||||
public static final String NAME = "InvalidityDate";
|
||||
public static final String DATE = "date";
|
||||
|
||||
private Date date;
|
||||
|
||||
private void encodeThis() throws IOException {
|
||||
if (date == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream dos = new DerOutputStream();
|
||||
dos.putGeneralizedTime(date);
|
||||
this.extensionValue = dos.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a InvalidityDateExtension with the passed in date.
|
||||
* Criticality automatically set to false.
|
||||
*
|
||||
* @param date the invalidity date
|
||||
*/
|
||||
public InvalidityDateExtension(Date date) throws IOException {
|
||||
this(false, date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a InvalidityDateExtension with the passed in date.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param date the invalidity date
|
||||
*/
|
||||
public InvalidityDateExtension(boolean critical, Date date)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.InvalidityDate_Id;
|
||||
this.critical = critical;
|
||||
this.date = date;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public InvalidityDateExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.InvalidityDate_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.date = val.getGeneralizedTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Date)) {
|
||||
throw new IOException("Attribute must be of type Date.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(DATE)) {
|
||||
date = (Date) obj;
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by InvalidityDateExtension");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Date get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DATE)) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (new Date(date.getTime())); // clone
|
||||
}
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by InvalidityDateExtension");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DATE)) {
|
||||
date = null;
|
||||
} else {
|
||||
throw new IOException
|
||||
("Name not supported by InvalidityDateExtension");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the Invalidity Date.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + " Invalidity Date: " + String.valueOf(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to
|
||||
* @exception IOException on encoding errors
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.InvalidityDate_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DATE);
|
||||
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
public static InvalidityDateExtension toImpl(java.security.cert.Extension ext)
|
||||
throws IOException {
|
||||
if (ext instanceof InvalidityDateExtension) {
|
||||
return (InvalidityDateExtension) ext;
|
||||
} else {
|
||||
return new InvalidityDateExtension
|
||||
(Boolean.valueOf(ext.isCritical()), ext.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This represents the Issuer Alternative Name Extension.
|
||||
*
|
||||
* This extension, if present, allows the issuer to specify multiple
|
||||
* alternative names.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class IssuerAlternativeNameExtension
|
||||
extends Extension implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.IssuerAlternativeName";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "IssuerAlternativeName";
|
||||
public static final String ISSUER_NAME = "issuer_name";
|
||||
|
||||
// private data members
|
||||
GeneralNames names = null;
|
||||
|
||||
// Encode this extension
|
||||
private void encodeThis() throws IOException {
|
||||
if (names == null || names.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
names.encode(os);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a IssuerAlternativeNameExtension with the passed GeneralNames.
|
||||
*
|
||||
* @param names the GeneralNames for the issuer.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public IssuerAlternativeNameExtension(GeneralNames names)
|
||||
throws IOException {
|
||||
this.names = names;
|
||||
this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a IssuerAlternativeNameExtension with the passed criticality
|
||||
* and GeneralNames.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param names the GeneralNames for the issuer.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public IssuerAlternativeNameExtension(Boolean critical, GeneralNames names)
|
||||
throws IOException {
|
||||
this.names = names;
|
||||
this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default IssuerAlternativeNameExtension.
|
||||
*/
|
||||
public IssuerAlternativeNameExtension() {
|
||||
extensionId = PKIXExtensions.IssuerAlternativeName_Id;
|
||||
critical = false;
|
||||
names = new GeneralNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public IssuerAlternativeNameExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.IssuerAlternativeName_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.data == null) {
|
||||
names = new GeneralNames();
|
||||
return;
|
||||
}
|
||||
|
||||
names = new GeneralNames(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the IssuerAlternativeName.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
String result = super.toString() + "IssuerAlternativeName [\n";
|
||||
if(names == null) {
|
||||
result += " null\n";
|
||||
} else {
|
||||
for(GeneralName name: names.names()) {
|
||||
result += " "+name+"\n";
|
||||
}
|
||||
}
|
||||
result += "]\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding error.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.IssuerAlternativeName_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER_NAME)) {
|
||||
if (!(obj instanceof GeneralNames)) {
|
||||
throw new IOException("Attribute value should be of" +
|
||||
" type GeneralNames.");
|
||||
}
|
||||
names = (GeneralNames)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:IssuerAlternativeName.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public GeneralNames get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER_NAME)) {
|
||||
return (names);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:IssuerAlternativeName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ISSUER_NAME)) {
|
||||
names = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:IssuerAlternativeName.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(ISSUER_NAME);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.DerInputStream;
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* Represents the CRL Issuing Distribution Point Extension (OID = 2.5.29.28).
|
||||
*
|
||||
* <p>
|
||||
* The issuing distribution point is a critical CRL extension that
|
||||
* identifies the CRL distribution point and scope for a particular CRL,
|
||||
* and it indicates whether the CRL covers revocation for end entity
|
||||
* certificates only, CA certificates only, attribute certificates only,
|
||||
* or a limited set of reason codes.
|
||||
*
|
||||
* <p>
|
||||
* The extension is defined in Section 5.2.5 of
|
||||
* <a href="http://tools.ietf.org/html/rfc5280">Internet X.509 PKI Certific
|
||||
ate and Certificate Revocation List (CRL) Profile</a>.
|
||||
*
|
||||
* <p>
|
||||
* Its ASN.1 definition is as follows:
|
||||
* <pre>
|
||||
* id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
|
||||
*
|
||||
* issuingDistributionPoint ::= SEQUENCE {
|
||||
* distributionPoint [0] DistributionPointName OPTIONAL,
|
||||
* onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
|
||||
* onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
|
||||
* onlySomeReasons [3] ReasonFlags OPTIONAL,
|
||||
* indirectCRL [4] BOOLEAN DEFAULT FALSE,
|
||||
* onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
|
||||
* </pre>
|
||||
*
|
||||
* @see DistributionPoint
|
||||
* @since 1.6
|
||||
*/
|
||||
public class IssuingDistributionPointExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.IssuingDistributionPoint";
|
||||
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "IssuingDistributionPoint";
|
||||
public static final String POINT = "point";
|
||||
public static final String REASONS = "reasons";
|
||||
public static final String ONLY_USER_CERTS = "only_user_certs";
|
||||
public static final String ONLY_CA_CERTS = "only_ca_certs";
|
||||
public static final String ONLY_ATTRIBUTE_CERTS = "only_attribute_certs";
|
||||
public static final String INDIRECT_CRL = "indirect_crl";
|
||||
|
||||
/*
|
||||
* The distribution point name for the CRL.
|
||||
*/
|
||||
private DistributionPointName distributionPoint = null;
|
||||
|
||||
/*
|
||||
* The scope settings for the CRL.
|
||||
*/
|
||||
private ReasonFlags revocationReasons = null;
|
||||
private boolean hasOnlyUserCerts = false;
|
||||
private boolean hasOnlyCACerts = false;
|
||||
private boolean hasOnlyAttributeCerts = false;
|
||||
private boolean isIndirectCRL = false;
|
||||
|
||||
/*
|
||||
* ASN.1 context specific tag values
|
||||
*/
|
||||
private static final byte TAG_DISTRIBUTION_POINT = 0;
|
||||
private static final byte TAG_ONLY_USER_CERTS = 1;
|
||||
private static final byte TAG_ONLY_CA_CERTS = 2;
|
||||
private static final byte TAG_ONLY_SOME_REASONS = 3;
|
||||
private static final byte TAG_INDIRECT_CRL = 4;
|
||||
private static final byte TAG_ONLY_ATTRIBUTE_CERTS = 5;
|
||||
|
||||
/**
|
||||
* Creates a critical IssuingDistributionPointExtension.
|
||||
*
|
||||
* @param distributionPoint the name of the distribution point, or null for
|
||||
* none.
|
||||
* @param revocationReasons the revocation reasons associated with the
|
||||
* distribution point, or null for none.
|
||||
* @param hasOnlyUserCerts if <code>true</code> then scope of the CRL
|
||||
* includes only user certificates.
|
||||
* @param hasOnlyCACerts if <code>true</code> then scope of the CRL
|
||||
* includes only CA certificates.
|
||||
* @param hasOnlyAttributeCerts if <code>true</code> then scope of the CRL
|
||||
* includes only attribute certificates.
|
||||
* @param isIndirectCRL if <code>true</code> then the scope of the CRL
|
||||
* includes certificates issued by authorities other than the CRL
|
||||
* issuer. The responsible authority is indicated by a certificate
|
||||
* issuer CRL entry extension.
|
||||
* @throws IllegalArgumentException if more than one of
|
||||
* <code>hasOnlyUserCerts</code>, <code>hasOnlyCACerts</code>,
|
||||
* <code>hasOnlyAttributeCerts</code> is set to <code>true</code>.
|
||||
* @throws IOException on encoding error.
|
||||
*/
|
||||
public IssuingDistributionPointExtension(
|
||||
DistributionPointName distributionPoint, ReasonFlags revocationReasons,
|
||||
boolean hasOnlyUserCerts, boolean hasOnlyCACerts,
|
||||
boolean hasOnlyAttributeCerts, boolean isIndirectCRL)
|
||||
throws IOException {
|
||||
|
||||
if ((hasOnlyUserCerts && (hasOnlyCACerts || hasOnlyAttributeCerts)) ||
|
||||
(hasOnlyCACerts && (hasOnlyUserCerts || hasOnlyAttributeCerts)) ||
|
||||
(hasOnlyAttributeCerts && (hasOnlyUserCerts || hasOnlyCACerts))) {
|
||||
throw new IllegalArgumentException(
|
||||
"Only one of hasOnlyUserCerts, hasOnlyCACerts, " +
|
||||
"hasOnlyAttributeCerts may be set to true");
|
||||
}
|
||||
this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id;
|
||||
this.critical = true;
|
||||
this.distributionPoint = distributionPoint;
|
||||
this.revocationReasons = revocationReasons;
|
||||
this.hasOnlyUserCerts = hasOnlyUserCerts;
|
||||
this.hasOnlyCACerts = hasOnlyCACerts;
|
||||
this.hasOnlyAttributeCerts = hasOnlyAttributeCerts;
|
||||
this.isIndirectCRL = isIndirectCRL;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a critical IssuingDistributionPointExtension from its
|
||||
* DER-encoding.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value the DER-encoded value. It must be a <code>byte[]</code>.
|
||||
* @exception IOException on decoding error.
|
||||
*/
|
||||
public IssuingDistributionPointExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
if (!(value instanceof byte[])) {
|
||||
throw new IOException("Illegal argument type");
|
||||
}
|
||||
|
||||
extensionValue = (byte[])value;
|
||||
DerValue val = new DerValue(extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"IssuingDistributionPointExtension.");
|
||||
}
|
||||
|
||||
// All the elements in issuingDistributionPoint are optional
|
||||
if ((val.data == null) || (val.data.available() == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DerInputStream in = val.data;
|
||||
while (in != null && in.available() != 0) {
|
||||
DerValue opt = in.getDerValue();
|
||||
|
||||
if (opt.isContextSpecific(TAG_DISTRIBUTION_POINT) &&
|
||||
opt.isConstructed()) {
|
||||
distributionPoint =
|
||||
new DistributionPointName(opt.data.getDerValue());
|
||||
} else if (opt.isContextSpecific(TAG_ONLY_USER_CERTS) &&
|
||||
!opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Boolean);
|
||||
hasOnlyUserCerts = opt.getBoolean();
|
||||
} else if (opt.isContextSpecific(TAG_ONLY_CA_CERTS) &&
|
||||
!opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Boolean);
|
||||
hasOnlyCACerts = opt.getBoolean();
|
||||
} else if (opt.isContextSpecific(TAG_ONLY_SOME_REASONS) &&
|
||||
!opt.isConstructed()) {
|
||||
revocationReasons = new ReasonFlags(opt); // expects tag implicit
|
||||
} else if (opt.isContextSpecific(TAG_INDIRECT_CRL) &&
|
||||
!opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Boolean);
|
||||
isIndirectCRL = opt.getBoolean();
|
||||
} else if (opt.isContextSpecific(TAG_ONLY_ATTRIBUTE_CERTS) &&
|
||||
!opt.isConstructed()) {
|
||||
opt.resetTag(DerValue.tag_Boolean);
|
||||
hasOnlyAttributeCerts = opt.getBoolean();
|
||||
} else {
|
||||
throw new IOException
|
||||
("Invalid encoding of IssuingDistributionPoint");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the issuing distribution point extension and writes it to the
|
||||
* DerOutputStream.
|
||||
*
|
||||
* @param out the output stream.
|
||||
* @exception IOException on encoding error.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.IssuingDistributionPoint_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINT)) {
|
||||
if (!(obj instanceof DistributionPointName)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type DistributionPointName.");
|
||||
}
|
||||
distributionPoint = (DistributionPointName)obj;
|
||||
|
||||
} else if (name.equalsIgnoreCase(REASONS)) {
|
||||
if (!(obj instanceof ReasonFlags)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type ReasonFlags.");
|
||||
}
|
||||
revocationReasons = (ReasonFlags)obj;
|
||||
|
||||
} else if (name.equalsIgnoreCase(INDIRECT_CRL)) {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type Boolean.");
|
||||
}
|
||||
isIndirectCRL = ((Boolean)obj).booleanValue();
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_USER_CERTS)) {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type Boolean.");
|
||||
}
|
||||
hasOnlyUserCerts = ((Boolean)obj).booleanValue();
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_CA_CERTS)) {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type Boolean.");
|
||||
}
|
||||
hasOnlyCACerts = ((Boolean)obj).booleanValue();
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_ATTRIBUTE_CERTS)) {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException(
|
||||
"Attribute value should be of type Boolean.");
|
||||
}
|
||||
hasOnlyAttributeCerts = ((Boolean)obj).booleanValue();
|
||||
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:IssuingDistributionPointExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINT)) {
|
||||
return distributionPoint;
|
||||
|
||||
} else if (name.equalsIgnoreCase(INDIRECT_CRL)) {
|
||||
return Boolean.valueOf(isIndirectCRL);
|
||||
|
||||
} else if (name.equalsIgnoreCase(REASONS)) {
|
||||
return revocationReasons;
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_USER_CERTS)) {
|
||||
return Boolean.valueOf(hasOnlyUserCerts);
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_CA_CERTS)) {
|
||||
return Boolean.valueOf(hasOnlyCACerts);
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_ATTRIBUTE_CERTS)) {
|
||||
return Boolean.valueOf(hasOnlyAttributeCerts);
|
||||
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:IssuingDistributionPointExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(POINT)) {
|
||||
distributionPoint = null;
|
||||
|
||||
} else if (name.equalsIgnoreCase(INDIRECT_CRL)) {
|
||||
isIndirectCRL = false;
|
||||
|
||||
} else if (name.equalsIgnoreCase(REASONS)) {
|
||||
revocationReasons = null;
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_USER_CERTS)) {
|
||||
hasOnlyUserCerts = false;
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_CA_CERTS)) {
|
||||
hasOnlyCACerts = false;
|
||||
|
||||
} else if (name.equalsIgnoreCase(ONLY_ATTRIBUTE_CERTS)) {
|
||||
hasOnlyAttributeCerts = false;
|
||||
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:IssuingDistributionPointExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(POINT);
|
||||
elements.addElement(REASONS);
|
||||
elements.addElement(ONLY_USER_CERTS);
|
||||
elements.addElement(ONLY_CA_CERTS);
|
||||
elements.addElement(ONLY_ATTRIBUTE_CERTS);
|
||||
elements.addElement(INDIRECT_CRL);
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
// Encodes this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
|
||||
if (distributionPoint == null &&
|
||||
revocationReasons == null &&
|
||||
!hasOnlyUserCerts &&
|
||||
!hasOnlyCACerts &&
|
||||
!hasOnlyAttributeCerts &&
|
||||
!isIndirectCRL) {
|
||||
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
|
||||
if (distributionPoint != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
distributionPoint.encode(tmp);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, true,
|
||||
TAG_DISTRIBUTION_POINT), tmp);
|
||||
}
|
||||
|
||||
if (hasOnlyUserCerts) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putBoolean(hasOnlyUserCerts);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false,
|
||||
TAG_ONLY_USER_CERTS), tmp);
|
||||
}
|
||||
|
||||
if (hasOnlyCACerts) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putBoolean(hasOnlyCACerts);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false,
|
||||
TAG_ONLY_CA_CERTS), tmp);
|
||||
}
|
||||
|
||||
if (revocationReasons != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
revocationReasons.encode(tmp);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false,
|
||||
TAG_ONLY_SOME_REASONS), tmp);
|
||||
}
|
||||
|
||||
if (isIndirectCRL) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putBoolean(isIndirectCRL);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false,
|
||||
TAG_INDIRECT_CRL), tmp);
|
||||
}
|
||||
|
||||
if (hasOnlyAttributeCerts) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putBoolean(hasOnlyAttributeCerts);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, false,
|
||||
TAG_ONLY_ATTRIBUTE_CERTS), tmp);
|
||||
}
|
||||
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, tagged);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
StringBuilder sb = new StringBuilder(super.toString());
|
||||
sb.append("IssuingDistributionPoint [\n ");
|
||||
|
||||
if (distributionPoint != null) {
|
||||
sb.append(distributionPoint);
|
||||
}
|
||||
|
||||
if (revocationReasons != null) {
|
||||
sb.append(revocationReasons);
|
||||
}
|
||||
|
||||
sb.append((hasOnlyUserCerts)
|
||||
? (" Only contains user certs: true")
|
||||
: (" Only contains user certs: false")).append("\n");
|
||||
|
||||
sb.append((hasOnlyCACerts)
|
||||
? (" Only contains CA certs: true")
|
||||
: (" Only contains CA certs: false")).append("\n");
|
||||
|
||||
sb.append((hasOnlyAttributeCerts)
|
||||
? (" Only contains attribute certs: true")
|
||||
: (" Only contains attribute certs: false")).append("\n");
|
||||
|
||||
sb.append((isIndirectCRL)
|
||||
? (" Indirect CRL: true")
|
||||
: (" Indirect CRL: false")).append("\n");
|
||||
|
||||
sb.append("]\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
154
jdkSrc/jdk8/sun/security/x509/KeyIdentifier.java
Normal file
154
jdkSrc/jdk8/sun/security/x509/KeyIdentifier.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the Key Identifier ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class KeyIdentifier {
|
||||
private byte[] octetString;
|
||||
|
||||
/**
|
||||
* Create a KeyIdentifier with the passed bit settings.
|
||||
*
|
||||
* @param octetString the octet string identifying the key identifier.
|
||||
*/
|
||||
public KeyIdentifier(byte[] octetString) {
|
||||
this.octetString = octetString.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a KeyIdentifier from the DER encoded value.
|
||||
*
|
||||
* @param val the DerValue
|
||||
*/
|
||||
public KeyIdentifier(DerValue val) throws IOException {
|
||||
octetString = val.getOctetString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a KeyIdentifier from a public-key value.
|
||||
*
|
||||
* <p>From RFC2459: Two common methods for generating key identifiers from
|
||||
* the public key are:
|
||||
* <ol>
|
||||
* <li>The keyIdentifier is composed of the 160-bit SHA-1 hash of the
|
||||
* value of the BIT STRING subjectPublicKey (excluding the tag,
|
||||
* length, and number of unused bits).
|
||||
* <p>
|
||||
* <li>The keyIdentifier is composed of a four bit type field with
|
||||
* the value 0100 followed by the least significant 60 bits of the
|
||||
* SHA-1 hash of the value of the BIT STRING subjectPublicKey.
|
||||
* </ol>
|
||||
* <p>This method supports method 1.
|
||||
*
|
||||
* @param pubKey the public key from which to construct this KeyIdentifier
|
||||
* @throws IOException on parsing errors
|
||||
*/
|
||||
public KeyIdentifier(PublicKey pubKey)
|
||||
throws IOException
|
||||
{
|
||||
DerValue algAndKey = new DerValue(pubKey.getEncoded());
|
||||
if (algAndKey.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("PublicKey value is not a valid "
|
||||
+ "X.509 public key");
|
||||
|
||||
AlgorithmId algid = AlgorithmId.parse(algAndKey.data.getDerValue());
|
||||
byte[] key = algAndKey.data.getUnalignedBitString().toByteArray();
|
||||
|
||||
MessageDigest md = null;
|
||||
try {
|
||||
md = MessageDigest.getInstance("SHA1");
|
||||
} catch (NoSuchAlgorithmException e3) {
|
||||
throw new IOException("SHA1 not supported");
|
||||
}
|
||||
md.update(key);
|
||||
this.octetString = md.digest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the KeyIdentifier as byte array.
|
||||
*/
|
||||
public byte[] getIdentifier() {
|
||||
return octetString.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the KeyUsage.
|
||||
*/
|
||||
public String toString() {
|
||||
String s = "KeyIdentifier [\n";
|
||||
|
||||
HexDumpEncoder encoder = new HexDumpEncoder();
|
||||
s += encoder.encodeBuffer(octetString);
|
||||
s += "]\n";
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the KeyIdentifier to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the object to.
|
||||
* @exception IOException
|
||||
*/
|
||||
void encode(DerOutputStream out) throws IOException {
|
||||
out.putOctetString(octetString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for this object.
|
||||
* Objects that are equal will also have the same hashcode.
|
||||
*/
|
||||
public int hashCode () {
|
||||
int retval = 0;
|
||||
for (int i = 0; i < octetString.length; i++)
|
||||
retval += octetString[i] * i;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other object is "equal to" this one.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other)
|
||||
return true;
|
||||
if (!(other instanceof KeyIdentifier))
|
||||
return false;
|
||||
byte[] otherString = ((KeyIdentifier)other).octetString;
|
||||
return java.util.Arrays.equals(octetString, otherString);
|
||||
}
|
||||
}
|
||||
363
jdkSrc/jdk8/sun/security/x509/KeyUsageExtension.java
Normal file
363
jdkSrc/jdk8/sun/security/x509/KeyUsageExtension.java
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the Key Usage Extension.
|
||||
*
|
||||
* <p>This extension, if present, defines the purpose (e.g., encipherment,
|
||||
* signature, certificate signing) of the key contained in the certificate.
|
||||
* The usage restriction might be employed when a multipurpose key is to be
|
||||
* restricted (e.g., when an RSA key should be used only for signing or only
|
||||
* for key encipherment).
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class KeyUsageExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.KeyUsage";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "KeyUsage";
|
||||
public static final String DIGITAL_SIGNATURE = "digital_signature";
|
||||
public static final String NON_REPUDIATION = "non_repudiation";
|
||||
public static final String KEY_ENCIPHERMENT = "key_encipherment";
|
||||
public static final String DATA_ENCIPHERMENT = "data_encipherment";
|
||||
public static final String KEY_AGREEMENT = "key_agreement";
|
||||
public static final String KEY_CERTSIGN = "key_certsign";
|
||||
public static final String CRL_SIGN = "crl_sign";
|
||||
public static final String ENCIPHER_ONLY = "encipher_only";
|
||||
public static final String DECIPHER_ONLY = "decipher_only";
|
||||
|
||||
// Private data members
|
||||
private boolean[] bitString;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
os.putTruncatedUnalignedBitString(new BitArray(this.bitString));
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if bit is set.
|
||||
*
|
||||
* @param position the position in the bit string to check.
|
||||
*/
|
||||
private boolean isSet(int position) {
|
||||
return (position < bitString.length) &&
|
||||
bitString[position];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bit at the specified position.
|
||||
*/
|
||||
private void set(int position, boolean val) {
|
||||
// enlarge bitString if necessary
|
||||
if (position >= bitString.length) {
|
||||
boolean[] tmp = new boolean[position+1];
|
||||
System.arraycopy(bitString, 0, tmp, 0, bitString.length);
|
||||
bitString = tmp;
|
||||
}
|
||||
bitString[position] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a KeyUsageExtension with the passed bit settings. The criticality
|
||||
* is set to true.
|
||||
*
|
||||
* @param bitString the bits to be set for the extension.
|
||||
*/
|
||||
public KeyUsageExtension(byte[] bitString) throws IOException {
|
||||
this.bitString =
|
||||
new BitArray(bitString.length*8,bitString).toBooleanArray();
|
||||
this.extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a KeyUsageExtension with the passed bit settings. The criticality
|
||||
* is set to true.
|
||||
*
|
||||
* @param bitString the bits to be set for the extension.
|
||||
*/
|
||||
public KeyUsageExtension(boolean[] bitString) throws IOException {
|
||||
this.bitString = bitString;
|
||||
this.extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a KeyUsageExtension with the passed bit settings. The criticality
|
||||
* is set to true.
|
||||
*
|
||||
* @param bitString the bits to be set for the extension.
|
||||
*/
|
||||
public KeyUsageExtension(BitArray bitString) throws IOException {
|
||||
this.bitString = bitString.toBooleanArray();
|
||||
this.extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
* The DER encoded value may be wrapped in an OCTET STRING.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value (possibly
|
||||
* wrapped in an OCTET STRING).
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public KeyUsageExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
/*
|
||||
* The following check should be activated again after
|
||||
* the PKIX profiling work becomes standard and the check
|
||||
* is not a barrier to interoperability !
|
||||
* if (!this.critical) {
|
||||
* throw new IOException("KeyUsageExtension not marked critical,"
|
||||
* + " invalid profile.");
|
||||
* }
|
||||
*/
|
||||
byte[] extValue = (byte[]) value;
|
||||
if (extValue[0] == DerValue.tag_OctetString) {
|
||||
this.extensionValue = new DerValue(extValue).getOctetString();
|
||||
} else {
|
||||
this.extensionValue = extValue;
|
||||
}
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.bitString = val.getUnalignedBitString().toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default key usage.
|
||||
*/
|
||||
public KeyUsageExtension() {
|
||||
extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
critical = true;
|
||||
bitString = new boolean[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException("Attribute must be of type Boolean.");
|
||||
}
|
||||
boolean val = ((Boolean)obj).booleanValue();
|
||||
if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
|
||||
set(0,val);
|
||||
} else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
|
||||
set(1,val);
|
||||
} else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
|
||||
set(2,val);
|
||||
} else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
|
||||
set(3,val);
|
||||
} else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
|
||||
set(4,val);
|
||||
} else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
|
||||
set(5,val);
|
||||
} else if (name.equalsIgnoreCase(CRL_SIGN)) {
|
||||
set(6,val);
|
||||
} else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
|
||||
set(7,val);
|
||||
} else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
|
||||
set(8,val);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:KeyUsage.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Boolean get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
|
||||
return Boolean.valueOf(isSet(0));
|
||||
} else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
|
||||
return Boolean.valueOf(isSet(1));
|
||||
} else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
|
||||
return Boolean.valueOf(isSet(2));
|
||||
} else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
|
||||
return Boolean.valueOf(isSet(3));
|
||||
} else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
|
||||
return Boolean.valueOf(isSet(4));
|
||||
} else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
|
||||
return Boolean.valueOf(isSet(5));
|
||||
} else if (name.equalsIgnoreCase(CRL_SIGN)) {
|
||||
return Boolean.valueOf(isSet(6));
|
||||
} else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
|
||||
return Boolean.valueOf(isSet(7));
|
||||
} else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
|
||||
return Boolean.valueOf(isSet(8));
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:KeyUsage.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
|
||||
set(0,false);
|
||||
} else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
|
||||
set(1,false);
|
||||
} else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
|
||||
set(2,false);
|
||||
} else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
|
||||
set(3,false);
|
||||
} else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
|
||||
set(4,false);
|
||||
} else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
|
||||
set(5,false);
|
||||
} else if (name.equalsIgnoreCase(CRL_SIGN)) {
|
||||
set(6,false);
|
||||
} else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
|
||||
set(7,false);
|
||||
} else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
|
||||
set(8,false);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:KeyUsage.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the KeyUsage.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString());
|
||||
sb.append("KeyUsage [\n");
|
||||
|
||||
if (isSet(0)) {
|
||||
sb.append(" DigitalSignature\n");
|
||||
}
|
||||
if (isSet(1)) {
|
||||
sb.append(" Non_repudiation\n");
|
||||
}
|
||||
if (isSet(2)) {
|
||||
sb.append(" Key_Encipherment\n");
|
||||
}
|
||||
if (isSet(3)) {
|
||||
sb.append(" Data_Encipherment\n");
|
||||
}
|
||||
if (isSet(4)) {
|
||||
sb.append(" Key_Agreement\n");
|
||||
}
|
||||
if (isSet(5)) {
|
||||
sb.append(" Key_CertSign\n");
|
||||
}
|
||||
if (isSet(6)) {
|
||||
sb.append(" Crl_Sign\n");
|
||||
}
|
||||
if (isSet(7)) {
|
||||
sb.append(" Encipher_Only\n");
|
||||
}
|
||||
if (isSet(8)) {
|
||||
sb.append(" Decipher_Only\n");
|
||||
}
|
||||
sb.append("]\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DIGITAL_SIGNATURE);
|
||||
elements.addElement(NON_REPUDIATION);
|
||||
elements.addElement(KEY_ENCIPHERMENT);
|
||||
elements.addElement(DATA_ENCIPHERMENT);
|
||||
elements.addElement(KEY_AGREEMENT);
|
||||
elements.addElement(KEY_CERTSIGN);
|
||||
elements.addElement(CRL_SIGN);
|
||||
elements.addElement(ENCIPHER_ONLY);
|
||||
elements.addElement(DECIPHER_ONLY);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
|
||||
public boolean[] getBits() {
|
||||
return bitString.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
632
jdkSrc/jdk8/sun/security/x509/NameConstraintsExtension.java
Normal file
632
jdkSrc/jdk8/sun/security/x509/NameConstraintsExtension.java
Normal file
@@ -0,0 +1,632 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.*;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.net.util.IPAddressUtil;
|
||||
import sun.security.util.*;
|
||||
import sun.security.pkcs.PKCS9Attribute;
|
||||
|
||||
/**
|
||||
* This class defines the Name Constraints Extension.
|
||||
* <p>
|
||||
* The name constraints extension provides permitted and excluded
|
||||
* subtrees that place restrictions on names that may be included within
|
||||
* a certificate issued by a given CA. Restrictions may apply to the
|
||||
* subject distinguished name or subject alternative names. Any name
|
||||
* matching a restriction in the excluded subtrees field is invalid
|
||||
* regardless of information appearing in the permitted subtrees.
|
||||
* <p>
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* NameConstraints ::= SEQUENCE {
|
||||
* permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||||
* excludedSubtrees [1] GeneralSubtrees OPTIONAL
|
||||
* }
|
||||
* GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||||
* </pre>
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class NameConstraintsExtension extends Extension
|
||||
implements CertAttrSet<String>, Cloneable {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.NameConstraints";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "NameConstraints";
|
||||
public static final String PERMITTED_SUBTREES = "permitted_subtrees";
|
||||
public static final String EXCLUDED_SUBTREES = "excluded_subtrees";
|
||||
|
||||
// Private data members
|
||||
private static final byte TAG_PERMITTED = 0;
|
||||
private static final byte TAG_EXCLUDED = 1;
|
||||
|
||||
private GeneralSubtrees permitted = null;
|
||||
private GeneralSubtrees excluded = null;
|
||||
|
||||
private boolean hasMin;
|
||||
private boolean hasMax;
|
||||
private boolean minMaxValid = false;
|
||||
|
||||
// Recalculate hasMin and hasMax flags.
|
||||
private void calcMinMax() throws IOException {
|
||||
hasMin = false;
|
||||
hasMax = false;
|
||||
if (excluded != null) {
|
||||
for (int i = 0; i < excluded.size(); i++) {
|
||||
GeneralSubtree subtree = excluded.get(i);
|
||||
if (subtree.getMinimum() != 0)
|
||||
hasMin = true;
|
||||
if (subtree.getMaximum() != -1)
|
||||
hasMax = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (permitted != null) {
|
||||
for (int i = 0; i < permitted.size(); i++) {
|
||||
GeneralSubtree subtree = permitted.get(i);
|
||||
if (subtree.getMinimum() != 0)
|
||||
hasMin = true;
|
||||
if (subtree.getMaximum() != -1)
|
||||
hasMax = true;
|
||||
}
|
||||
}
|
||||
minMaxValid = true;
|
||||
}
|
||||
|
||||
// Encode this extension value.
|
||||
private void encodeThis() throws IOException {
|
||||
minMaxValid = false;
|
||||
if (permitted == null && excluded == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
if (permitted != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
permitted.encode(tmp);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, TAG_PERMITTED), tmp);
|
||||
}
|
||||
if (excluded != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
excluded.encode(tmp);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
true, TAG_EXCLUDED), tmp);
|
||||
}
|
||||
seq.write(DerValue.tag_Sequence, tagged);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class. Both parameters
|
||||
* are optional and can be set to null. The extension criticality
|
||||
* is set to true.
|
||||
*
|
||||
* @param permitted the permitted GeneralSubtrees (null for optional).
|
||||
* @param excluded the excluded GeneralSubtrees (null for optional).
|
||||
*/
|
||||
public NameConstraintsExtension(GeneralSubtrees permitted,
|
||||
GeneralSubtrees excluded)
|
||||
throws IOException {
|
||||
this.permitted = permitted;
|
||||
this.excluded = excluded;
|
||||
|
||||
this.extensionId = PKIXExtensions.NameConstraints_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public NameConstraintsExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.NameConstraints_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for" +
|
||||
" NameConstraintsExtension.");
|
||||
}
|
||||
|
||||
// NB. this is always encoded with the IMPLICIT tag
|
||||
// The checks only make sense if we assume implicit tagging,
|
||||
// with explicit tagging the form is always constructed.
|
||||
// Note that all the fields in NameConstraints are defined as
|
||||
// being OPTIONAL, i.e., there could be an empty SEQUENCE, resulting
|
||||
// in val.data being null.
|
||||
if (val.data == null)
|
||||
return;
|
||||
while (val.data.available() != 0) {
|
||||
DerValue opt = val.data.getDerValue();
|
||||
|
||||
if (opt.isContextSpecific(TAG_PERMITTED) && opt.isConstructed()) {
|
||||
if (permitted != null) {
|
||||
throw new IOException("Duplicate permitted " +
|
||||
"GeneralSubtrees in NameConstraintsExtension.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_Sequence);
|
||||
permitted = new GeneralSubtrees(opt);
|
||||
|
||||
} else if (opt.isContextSpecific(TAG_EXCLUDED) &&
|
||||
opt.isConstructed()) {
|
||||
if (excluded != null) {
|
||||
throw new IOException("Duplicate excluded " +
|
||||
"GeneralSubtrees in NameConstraintsExtension.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_Sequence);
|
||||
excluded = new GeneralSubtrees(opt);
|
||||
} else
|
||||
throw new IOException("Invalid encoding of " +
|
||||
"NameConstraintsExtension.");
|
||||
}
|
||||
minMaxValid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return (super.toString() + "NameConstraints: [" +
|
||||
((permitted == null) ? "" :
|
||||
("\n Permitted:" + permitted.toString())) +
|
||||
((excluded == null) ? "" :
|
||||
("\n Excluded:" + excluded.toString()))
|
||||
+ " ]\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.NameConstraints_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
|
||||
if (!(obj instanceof GeneralSubtrees)) {
|
||||
throw new IOException("Attribute value should be"
|
||||
+ " of type GeneralSubtrees.");
|
||||
}
|
||||
permitted = (GeneralSubtrees)obj;
|
||||
} else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
|
||||
if (!(obj instanceof GeneralSubtrees)) {
|
||||
throw new IOException("Attribute value should be "
|
||||
+ "of type GeneralSubtrees.");
|
||||
}
|
||||
excluded = (GeneralSubtrees)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:NameConstraintsExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public GeneralSubtrees get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
|
||||
return (permitted);
|
||||
} else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
|
||||
return (excluded);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:NameConstraintsExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(PERMITTED_SUBTREES)) {
|
||||
permitted = null;
|
||||
} else if (name.equalsIgnoreCase(EXCLUDED_SUBTREES)) {
|
||||
excluded = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:NameConstraintsExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(PERMITTED_SUBTREES);
|
||||
elements.addElement(EXCLUDED_SUBTREES);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge additional name constraints with existing ones.
|
||||
* This function is used in certification path processing
|
||||
* to accumulate name constraints from successive certificates
|
||||
* in the path. Note that NameConstraints can never be
|
||||
* expanded by a merge, just remain constant or become more
|
||||
* limiting.
|
||||
* <p>
|
||||
* IETF RFC2459 specifies the processing of Name Constraints as
|
||||
* follows:
|
||||
* <p>
|
||||
* (j) If permittedSubtrees is present in the certificate, set the
|
||||
* constrained subtrees state variable to the intersection of its
|
||||
* previous value and the value indicated in the extension field.
|
||||
* <p>
|
||||
* (k) If excludedSubtrees is present in the certificate, set the
|
||||
* excluded subtrees state variable to the union of its previous
|
||||
* value and the value indicated in the extension field.
|
||||
* <p>
|
||||
* @param newConstraints additional NameConstraints to be applied
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public void merge(NameConstraintsExtension newConstraints)
|
||||
throws IOException {
|
||||
|
||||
if (newConstraints == null) {
|
||||
// absence of any explicit constraints implies unconstrained
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If excludedSubtrees is present in the certificate, set the
|
||||
* excluded subtrees state variable to the union of its previous
|
||||
* value and the value indicated in the extension field.
|
||||
*/
|
||||
|
||||
GeneralSubtrees newExcluded = newConstraints.get(EXCLUDED_SUBTREES);
|
||||
if (excluded == null) {
|
||||
excluded = (newExcluded != null) ?
|
||||
(GeneralSubtrees)newExcluded.clone() : null;
|
||||
} else {
|
||||
if (newExcluded != null) {
|
||||
// Merge new excluded with current excluded (union)
|
||||
excluded.union(newExcluded);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If permittedSubtrees is present in the certificate, set the
|
||||
* constrained subtrees state variable to the intersection of its
|
||||
* previous value and the value indicated in the extension field.
|
||||
*/
|
||||
|
||||
GeneralSubtrees newPermitted = newConstraints.get(PERMITTED_SUBTREES);
|
||||
if (permitted == null) {
|
||||
permitted = (newPermitted != null) ?
|
||||
(GeneralSubtrees)newPermitted.clone() : null;
|
||||
} else {
|
||||
if (newPermitted != null) {
|
||||
// Merge new permitted with current permitted (intersection)
|
||||
newExcluded = permitted.intersect(newPermitted);
|
||||
|
||||
// Merge new excluded subtrees to current excluded (union)
|
||||
if (newExcluded != null) {
|
||||
if (excluded != null) {
|
||||
excluded.union(newExcluded);
|
||||
} else {
|
||||
excluded = (GeneralSubtrees)newExcluded.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optional optimization: remove permitted subtrees that are excluded.
|
||||
// This is not necessary for algorithm correctness, but it makes
|
||||
// subsequent operations on the NameConstraints faster and require
|
||||
// less space.
|
||||
if (permitted != null) {
|
||||
permitted.reduce(excluded);
|
||||
}
|
||||
|
||||
// The NameConstraints have been changed, so re-encode them. Methods in
|
||||
// this class assume that the encodings have already been done.
|
||||
encodeThis();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether a certificate conforms to these NameConstraints.
|
||||
* This involves verifying that the subject name and subjectAltName
|
||||
* extension (critical or noncritical) is consistent with the permitted
|
||||
* subtrees state variables. Also verify that the subject name and
|
||||
* subjectAltName extension (critical or noncritical) is consistent with
|
||||
* the excluded subtrees state variables.
|
||||
*
|
||||
* @param cert X509Certificate to be verified
|
||||
* @returns true if certificate verifies successfully
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public boolean verify(X509Certificate cert) throws IOException {
|
||||
|
||||
if (cert == null) {
|
||||
throw new IOException("Certificate is null");
|
||||
}
|
||||
|
||||
// Calculate hasMin and hasMax booleans (if necessary)
|
||||
if (!minMaxValid) {
|
||||
calcMinMax();
|
||||
}
|
||||
|
||||
if (hasMin) {
|
||||
throw new IOException("Non-zero minimum BaseDistance in"
|
||||
+ " name constraints not supported");
|
||||
}
|
||||
|
||||
if (hasMax) {
|
||||
throw new IOException("Maximum BaseDistance in"
|
||||
+ " name constraints not supported");
|
||||
}
|
||||
|
||||
X500Principal subjectPrincipal = cert.getSubjectX500Principal();
|
||||
X500Name subject = X500Name.asX500Name(subjectPrincipal);
|
||||
|
||||
// Check subject as an X500Name
|
||||
if (subject.isEmpty() == false) {
|
||||
if (verify(subject) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GeneralNames altNames = null;
|
||||
// extract altNames
|
||||
try {
|
||||
// extract extensions, if any, from certInfo
|
||||
// following returns null if certificate contains no extensions
|
||||
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
|
||||
SubjectAlternativeNameExtension altNameExt =
|
||||
certImpl.getSubjectAlternativeNameExtension();
|
||||
if (altNameExt != null) {
|
||||
// extract altNames from extension; this call does not
|
||||
// return an IOException on null altnames
|
||||
altNames = altNameExt.get(
|
||||
SubjectAlternativeNameExtension.SUBJECT_NAME);
|
||||
}
|
||||
} catch (CertificateException ce) {
|
||||
throw new IOException("Unable to extract extensions from " +
|
||||
"certificate: " + ce.getMessage());
|
||||
}
|
||||
|
||||
if (altNames == null) {
|
||||
altNames = new GeneralNames();
|
||||
|
||||
// RFC 5280 4.2.1.10:
|
||||
// When constraints are imposed on the rfc822Name name form,
|
||||
// but the certificate does not include a subject alternative name,
|
||||
// the rfc822Name constraint MUST be applied to the attribute of
|
||||
// type emailAddress in the subject distinguished name.
|
||||
for (AVA ava : subject.allAvas()) {
|
||||
ObjectIdentifier attrOID = ava.getObjectIdentifier();
|
||||
if (attrOID.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) {
|
||||
String attrValue = ava.getValueString();
|
||||
if (attrValue != null) {
|
||||
try {
|
||||
altNames.add(new GeneralName(
|
||||
new RFC822Name(attrValue)));
|
||||
} catch (IOException ioe) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no IPAddressName or DNSName in subjectAlternativeNames,
|
||||
// see if the last CN inside subjectName can be used instead.
|
||||
DerValue derValue = subject.findMostSpecificAttribute
|
||||
(X500Name.commonName_oid);
|
||||
String cn = derValue == null ? null : derValue.getAsString();
|
||||
|
||||
if (cn != null) {
|
||||
try {
|
||||
if (IPAddressUtil.isIPv4LiteralAddress(cn) ||
|
||||
IPAddressUtil.isIPv6LiteralAddress(cn)) {
|
||||
if (!hasNameType(altNames, GeneralNameInterface.NAME_IP)) {
|
||||
altNames.add(new GeneralName(new IPAddressName(cn)));
|
||||
}
|
||||
} else {
|
||||
if (!hasNameType(altNames, GeneralNameInterface.NAME_DNS)) {
|
||||
altNames.add(new GeneralName(new DNSName(cn)));
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
// OK, cn is neither IP nor DNS
|
||||
}
|
||||
}
|
||||
|
||||
// verify each subjectAltName
|
||||
for (int i = 0; i < altNames.size(); i++) {
|
||||
GeneralNameInterface altGNI = altNames.get(i).getName();
|
||||
if (!verify(altGNI)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All tests passed.
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean hasNameType(GeneralNames names, int type) {
|
||||
for (GeneralName name : names.names()) {
|
||||
if (name.getType() == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether a name conforms to these NameConstraints.
|
||||
* This involves verifying that the name is consistent with the
|
||||
* permitted and excluded subtrees variables.
|
||||
*
|
||||
* @param name GeneralNameInterface name to be verified
|
||||
* @returns true if certificate verifies successfully
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public boolean verify(GeneralNameInterface name) throws IOException {
|
||||
if (name == null) {
|
||||
throw new IOException("name is null");
|
||||
}
|
||||
|
||||
// Verify that the name is consistent with the excluded subtrees
|
||||
if (excluded != null && excluded.size() > 0) {
|
||||
|
||||
for (int i = 0; i < excluded.size(); i++) {
|
||||
GeneralSubtree gs = excluded.get(i);
|
||||
if (gs == null)
|
||||
continue;
|
||||
GeneralName gn = gs.getName();
|
||||
if (gn == null)
|
||||
continue;
|
||||
GeneralNameInterface exName = gn.getName();
|
||||
if (exName == null)
|
||||
continue;
|
||||
|
||||
// if name matches or narrows any excluded subtree,
|
||||
// return false
|
||||
switch (exName.constrains(name)) {
|
||||
case GeneralNameInterface.NAME_DIFF_TYPE:
|
||||
case GeneralNameInterface.NAME_WIDENS: // name widens excluded
|
||||
case GeneralNameInterface.NAME_SAME_TYPE:
|
||||
break;
|
||||
case GeneralNameInterface.NAME_MATCH:
|
||||
case GeneralNameInterface.NAME_NARROWS: // subject name excluded
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the name is consistent with the permitted subtrees
|
||||
if (permitted != null && permitted.size() > 0) {
|
||||
|
||||
boolean sameType = false;
|
||||
|
||||
for (int i = 0; i < permitted.size(); i++) {
|
||||
GeneralSubtree gs = permitted.get(i);
|
||||
if (gs == null)
|
||||
continue;
|
||||
GeneralName gn = gs.getName();
|
||||
if (gn == null)
|
||||
continue;
|
||||
GeneralNameInterface perName = gn.getName();
|
||||
if (perName == null)
|
||||
continue;
|
||||
|
||||
// if Name matches any type in permitted,
|
||||
// and Name does not match or narrow some permitted subtree,
|
||||
// return false
|
||||
switch (perName.constrains(name)) {
|
||||
case GeneralNameInterface.NAME_DIFF_TYPE:
|
||||
continue; // continue checking other permitted names
|
||||
case GeneralNameInterface.NAME_WIDENS: // name widens permitted
|
||||
case GeneralNameInterface.NAME_SAME_TYPE:
|
||||
sameType = true;
|
||||
continue; // continue to look for a match or narrow
|
||||
case GeneralNameInterface.NAME_MATCH:
|
||||
case GeneralNameInterface.NAME_NARROWS:
|
||||
// name narrows permitted
|
||||
return true; // name is definitely OK, so break out of loop
|
||||
}
|
||||
}
|
||||
if (sameType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone all objects that may be modified during certificate validation.
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
NameConstraintsExtension newNCE =
|
||||
(NameConstraintsExtension) super.clone();
|
||||
|
||||
if (permitted != null) {
|
||||
newNCE.permitted = (GeneralSubtrees) permitted.clone();
|
||||
}
|
||||
if (excluded != null) {
|
||||
newNCE.excluded = (GeneralSubtrees) excluded.clone();
|
||||
}
|
||||
return newNCE;
|
||||
} catch (CloneNotSupportedException cnsee) {
|
||||
throw new RuntimeException("CloneNotSupportedException while " +
|
||||
"cloning NameConstraintsException. This should never happen.");
|
||||
}
|
||||
}
|
||||
}
|
||||
329
jdkSrc/jdk8/sun/security/x509/NetscapeCertTypeExtension.java
Normal file
329
jdkSrc/jdk8/sun/security/x509/NetscapeCertTypeExtension.java
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represents Netscape Certificate Type Extension.
|
||||
* The details are defined
|
||||
* <a href=http://www.netscape.com/eng/security/comm4-cert-exts.html>
|
||||
* here </a>.
|
||||
*
|
||||
* <p>This extension, if present, defines both the purpose
|
||||
* (e.g., encipherment, signature, certificate signing) and the application
|
||||
* (e.g., SSL, S/Mime or Object Signing of the key contained in the
|
||||
* certificate. This extension has been superseded by IETF PKIX extensions
|
||||
* but is provided here for compatibility reasons.
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
|
||||
public class NetscapeCertTypeExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.NetscapeCertType";
|
||||
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "NetscapeCertType";
|
||||
public static final String SSL_CLIENT = "ssl_client";
|
||||
public static final String SSL_SERVER = "ssl_server";
|
||||
public static final String S_MIME = "s_mime";
|
||||
public static final String OBJECT_SIGNING = "object_signing";
|
||||
public static final String SSL_CA = "ssl_ca";
|
||||
public static final String S_MIME_CA = "s_mime_ca";
|
||||
public static final String OBJECT_SIGNING_CA = "object_signing_ca";
|
||||
|
||||
private static final int CertType_data[] = { 2, 16, 840, 1, 113730, 1, 1 };
|
||||
|
||||
/**
|
||||
* Object identifier for the Netscape-Cert-Type extension.
|
||||
*/
|
||||
public static ObjectIdentifier NetscapeCertType_Id;
|
||||
|
||||
static {
|
||||
try {
|
||||
NetscapeCertType_Id = new ObjectIdentifier(CertType_data);
|
||||
} catch (IOException ioe) {
|
||||
// should not happen
|
||||
}
|
||||
}
|
||||
|
||||
private boolean[] bitString;
|
||||
|
||||
private static class MapEntry {
|
||||
String mName;
|
||||
int mPosition;
|
||||
|
||||
MapEntry(String name, int position) {
|
||||
mName = name;
|
||||
mPosition = position;
|
||||
}
|
||||
}
|
||||
|
||||
private static MapEntry[] mMapData = {
|
||||
new MapEntry(SSL_CLIENT, 0),
|
||||
new MapEntry(SSL_SERVER, 1),
|
||||
new MapEntry(S_MIME, 2),
|
||||
new MapEntry(OBJECT_SIGNING, 3),
|
||||
// note that bit 4 is reserved
|
||||
new MapEntry(SSL_CA, 5),
|
||||
new MapEntry(S_MIME_CA, 6),
|
||||
new MapEntry(OBJECT_SIGNING_CA, 7),
|
||||
};
|
||||
|
||||
private static final Vector<String> mAttributeNames = new Vector<String>();
|
||||
static {
|
||||
for (MapEntry entry : mMapData) {
|
||||
mAttributeNames.add(entry.mName);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getPosition(String name) throws IOException {
|
||||
for (int i = 0; i < mMapData.length; i++) {
|
||||
if (name.equalsIgnoreCase(mMapData[i].mName))
|
||||
return mMapData[i].mPosition;
|
||||
}
|
||||
throw new IOException("Attribute name [" + name
|
||||
+ "] not recognized by CertAttrSet:NetscapeCertType.");
|
||||
}
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
os.putTruncatedUnalignedBitString(new BitArray(this.bitString));
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if bit is set.
|
||||
*
|
||||
* @param position the position in the bit string to check.
|
||||
*/
|
||||
private boolean isSet(int position) {
|
||||
return (position < bitString.length) &&
|
||||
bitString[position];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bit at the specified position.
|
||||
*/
|
||||
private void set(int position, boolean val) {
|
||||
// enlarge bitString if necessary
|
||||
if (position >= bitString.length) {
|
||||
boolean[] tmp = new boolean[position+1];
|
||||
System.arraycopy(bitString, 0, tmp, 0, bitString.length);
|
||||
bitString = tmp;
|
||||
}
|
||||
bitString[position] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NetscapeCertTypeExtension with the passed bit settings.
|
||||
* The criticality is set to true.
|
||||
*
|
||||
* @param bitString the bits to be set for the extension.
|
||||
*/
|
||||
public NetscapeCertTypeExtension(byte[] bitString) throws IOException {
|
||||
this.bitString =
|
||||
new BitArray(bitString.length*8, bitString).toBooleanArray();
|
||||
this.extensionId = NetscapeCertType_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NetscapeCertTypeExtension with the passed bit settings.
|
||||
* The criticality is set to true.
|
||||
*
|
||||
* @param bitString the bits to be set for the extension.
|
||||
*/
|
||||
public NetscapeCertTypeExtension(boolean[] bitString) throws IOException {
|
||||
this.bitString = bitString;
|
||||
this.extensionId = NetscapeCertType_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public NetscapeCertTypeExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = NetscapeCertType_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.bitString = val.getUnalignedBitString().toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default key usage.
|
||||
*/
|
||||
public NetscapeCertTypeExtension() {
|
||||
extensionId = NetscapeCertType_Id;
|
||||
critical = true;
|
||||
bitString = new boolean[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Boolean))
|
||||
throw new IOException("Attribute must be of type Boolean.");
|
||||
|
||||
boolean val = ((Boolean)obj).booleanValue();
|
||||
set(getPosition(name), val);
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Boolean get(String name) throws IOException {
|
||||
return Boolean.valueOf(isSet(getPosition(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
set(getPosition(name), false);
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the NetscapeCertType.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString());
|
||||
sb.append("NetscapeCertType [\n");
|
||||
|
||||
if (isSet(0)) {
|
||||
sb.append(" SSL client\n");
|
||||
}
|
||||
if (isSet(1)) {
|
||||
sb.append(" SSL server\n");
|
||||
}
|
||||
if (isSet(2)) {
|
||||
sb.append(" S/MIME\n");
|
||||
}
|
||||
if (isSet(3)) {
|
||||
sb.append(" Object Signing\n");
|
||||
}
|
||||
if (isSet(5)) {
|
||||
sb.append(" SSL CA\n");
|
||||
}
|
||||
if (isSet(6)) {
|
||||
sb.append(" S/MIME CA\n");
|
||||
}
|
||||
if (isSet(7)) {
|
||||
sb.append(" Object Signing CA");
|
||||
}
|
||||
|
||||
sb.append("]\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = NetscapeCertType_Id;
|
||||
this.critical = true;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
return mAttributeNames.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boolean array representing the bits of this extension,
|
||||
* as it maps to the KeyUsage extension.
|
||||
* @return the bit values of this extension mapped to the bit values
|
||||
* of the KeyUsage extension as an array of booleans.
|
||||
*/
|
||||
public boolean[] getKeyUsageMappedBits() {
|
||||
KeyUsageExtension keyUsage = new KeyUsageExtension();
|
||||
Boolean val = Boolean.TRUE;
|
||||
|
||||
try {
|
||||
if (isSet(getPosition(SSL_CLIENT)) ||
|
||||
isSet(getPosition(S_MIME)) ||
|
||||
isSet(getPosition(OBJECT_SIGNING)))
|
||||
keyUsage.set(KeyUsageExtension.DIGITAL_SIGNATURE, val);
|
||||
|
||||
if (isSet(getPosition(SSL_SERVER)))
|
||||
keyUsage.set(KeyUsageExtension.KEY_ENCIPHERMENT, val);
|
||||
|
||||
if (isSet(getPosition(SSL_CA)) ||
|
||||
isSet(getPosition(S_MIME_CA)) ||
|
||||
isSet(getPosition(OBJECT_SIGNING_CA)))
|
||||
keyUsage.set(KeyUsageExtension.KEY_CERTSIGN, val);
|
||||
} catch (IOException e) { }
|
||||
return keyUsage.getBits();
|
||||
}
|
||||
}
|
||||
132
jdkSrc/jdk8/sun/security/x509/OCSPNoCheckExtension.java
Normal file
132
jdkSrc/jdk8/sun/security/x509/OCSPNoCheckExtension.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the OCSP NoCheck Extension from RFC2560.
|
||||
* <p>
|
||||
* A CA may specify that an OCSP client can trust a responder for the
|
||||
* lifetime of the responder's certificate. The CA does so by including
|
||||
* the extension id-pkix-ocsp-nocheck. This SHOULD be a non-critical
|
||||
* extension. The value of the extension should be NULL. CAs issuing
|
||||
* such a certificate should realized that a compromise of the
|
||||
* responder's key, is as serious as the compromise of a CA key used to
|
||||
* sign CRLs, at least for the validity period of this certificate. CA's
|
||||
* may choose to issue this type of certificate with a very short
|
||||
* lifetime and renew it frequently.
|
||||
* <pre>
|
||||
* id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
|
||||
* </pre>
|
||||
*
|
||||
* @author Xuelei Fan
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class OCSPNoCheckExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.OCSPNoCheck";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "OCSPNoCheck";
|
||||
|
||||
/**
|
||||
* Create a OCSPNoCheckExtension
|
||||
*/
|
||||
public OCSPNoCheckExtension() throws IOException {
|
||||
this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
|
||||
this.critical = false;
|
||||
this.extensionValue = new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public OCSPNoCheckExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
|
||||
this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
// the value should be null, just ignore it here.
|
||||
this.extensionValue = new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
throw new IOException("No attribute is allowed by " +
|
||||
"CertAttrSet:OCSPNoCheckExtension.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
throw new IOException("No attribute is allowed by " +
|
||||
"CertAttrSet:OCSPNoCheckExtension.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
throw new IOException("No attribute is allowed by " +
|
||||
"CertAttrSet:OCSPNoCheckExtension.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
return (new AttributeNameEnumeration()).elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
}
|
||||
295
jdkSrc/jdk8/sun/security/x509/OIDMap.java
Normal file
295
jdkSrc/jdk8/sun/security/x509/OIDMap.java
Normal file
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the mapping from OID & name to classes and vice
|
||||
* versa. Used by CertificateExtensions & PKCS10 to get the java
|
||||
* classes associated with a particular OID/name.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @author Andreas Sterbenz
|
||||
*
|
||||
*/
|
||||
public class OIDMap {
|
||||
|
||||
private OIDMap() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// "user-friendly" names
|
||||
private static final String ROOT = X509CertImpl.NAME + "." +
|
||||
X509CertInfo.NAME + "." +
|
||||
X509CertInfo.EXTENSIONS;
|
||||
private static final String AUTH_KEY_IDENTIFIER = ROOT + "." +
|
||||
AuthorityKeyIdentifierExtension.NAME;
|
||||
private static final String SUB_KEY_IDENTIFIER = ROOT + "." +
|
||||
SubjectKeyIdentifierExtension.NAME;
|
||||
private static final String KEY_USAGE = ROOT + "." +
|
||||
KeyUsageExtension.NAME;
|
||||
private static final String PRIVATE_KEY_USAGE = ROOT + "." +
|
||||
PrivateKeyUsageExtension.NAME;
|
||||
private static final String POLICY_MAPPINGS = ROOT + "." +
|
||||
PolicyMappingsExtension.NAME;
|
||||
private static final String SUB_ALT_NAME = ROOT + "." +
|
||||
SubjectAlternativeNameExtension.NAME;
|
||||
private static final String ISSUER_ALT_NAME = ROOT + "." +
|
||||
IssuerAlternativeNameExtension.NAME;
|
||||
private static final String BASIC_CONSTRAINTS = ROOT + "." +
|
||||
BasicConstraintsExtension.NAME;
|
||||
private static final String NAME_CONSTRAINTS = ROOT + "." +
|
||||
NameConstraintsExtension.NAME;
|
||||
private static final String POLICY_CONSTRAINTS = ROOT + "." +
|
||||
PolicyConstraintsExtension.NAME;
|
||||
private static final String CRL_NUMBER = ROOT + "." +
|
||||
CRLNumberExtension.NAME;
|
||||
private static final String CRL_REASON = ROOT + "." +
|
||||
CRLReasonCodeExtension.NAME;
|
||||
private static final String NETSCAPE_CERT = ROOT + "." +
|
||||
NetscapeCertTypeExtension.NAME;
|
||||
private static final String CERT_POLICIES = ROOT + "." +
|
||||
CertificatePoliciesExtension.NAME;
|
||||
private static final String EXT_KEY_USAGE = ROOT + "." +
|
||||
ExtendedKeyUsageExtension.NAME;
|
||||
private static final String INHIBIT_ANY_POLICY = ROOT + "." +
|
||||
InhibitAnyPolicyExtension.NAME;
|
||||
private static final String CRL_DIST_POINTS = ROOT + "." +
|
||||
CRLDistributionPointsExtension.NAME;
|
||||
|
||||
private static final String CERT_ISSUER = ROOT + "." +
|
||||
CertificateIssuerExtension.NAME;
|
||||
private static final String SUBJECT_INFO_ACCESS = ROOT + "." +
|
||||
SubjectInfoAccessExtension.NAME;
|
||||
private static final String AUTH_INFO_ACCESS = ROOT + "." +
|
||||
AuthorityInfoAccessExtension.NAME;
|
||||
private static final String ISSUING_DIST_POINT = ROOT + "." +
|
||||
IssuingDistributionPointExtension.NAME;
|
||||
private static final String DELTA_CRL_INDICATOR = ROOT + "." +
|
||||
DeltaCRLIndicatorExtension.NAME;
|
||||
private static final String FRESHEST_CRL = ROOT + "." +
|
||||
FreshestCRLExtension.NAME;
|
||||
private static final String OCSPNOCHECK = ROOT + "." +
|
||||
OCSPNoCheckExtension.NAME;
|
||||
|
||||
private static final int NetscapeCertType_data[] =
|
||||
{ 2, 16, 840, 1, 113730, 1, 1 };
|
||||
|
||||
/** Map ObjectIdentifier(oid) -> OIDInfo(info) */
|
||||
private final static Map<ObjectIdentifier,OIDInfo> oidMap;
|
||||
|
||||
/** Map String(friendly name) -> OIDInfo(info) */
|
||||
private final static Map<String,OIDInfo> nameMap;
|
||||
|
||||
static {
|
||||
oidMap = new HashMap<ObjectIdentifier,OIDInfo>();
|
||||
nameMap = new HashMap<String,OIDInfo>();
|
||||
addInternal(SUB_KEY_IDENTIFIER, PKIXExtensions.SubjectKey_Id,
|
||||
"sun.security.x509.SubjectKeyIdentifierExtension");
|
||||
addInternal(KEY_USAGE, PKIXExtensions.KeyUsage_Id,
|
||||
"sun.security.x509.KeyUsageExtension");
|
||||
addInternal(PRIVATE_KEY_USAGE, PKIXExtensions.PrivateKeyUsage_Id,
|
||||
"sun.security.x509.PrivateKeyUsageExtension");
|
||||
addInternal(SUB_ALT_NAME, PKIXExtensions.SubjectAlternativeName_Id,
|
||||
"sun.security.x509.SubjectAlternativeNameExtension");
|
||||
addInternal(ISSUER_ALT_NAME, PKIXExtensions.IssuerAlternativeName_Id,
|
||||
"sun.security.x509.IssuerAlternativeNameExtension");
|
||||
addInternal(BASIC_CONSTRAINTS, PKIXExtensions.BasicConstraints_Id,
|
||||
"sun.security.x509.BasicConstraintsExtension");
|
||||
addInternal(CRL_NUMBER, PKIXExtensions.CRLNumber_Id,
|
||||
"sun.security.x509.CRLNumberExtension");
|
||||
addInternal(CRL_REASON, PKIXExtensions.ReasonCode_Id,
|
||||
"sun.security.x509.CRLReasonCodeExtension");
|
||||
addInternal(NAME_CONSTRAINTS, PKIXExtensions.NameConstraints_Id,
|
||||
"sun.security.x509.NameConstraintsExtension");
|
||||
addInternal(POLICY_MAPPINGS, PKIXExtensions.PolicyMappings_Id,
|
||||
"sun.security.x509.PolicyMappingsExtension");
|
||||
addInternal(AUTH_KEY_IDENTIFIER, PKIXExtensions.AuthorityKey_Id,
|
||||
"sun.security.x509.AuthorityKeyIdentifierExtension");
|
||||
addInternal(POLICY_CONSTRAINTS, PKIXExtensions.PolicyConstraints_Id,
|
||||
"sun.security.x509.PolicyConstraintsExtension");
|
||||
addInternal(NETSCAPE_CERT, ObjectIdentifier.newInternal
|
||||
(new int[] {2,16,840,1,113730,1,1}),
|
||||
"sun.security.x509.NetscapeCertTypeExtension");
|
||||
addInternal(CERT_POLICIES, PKIXExtensions.CertificatePolicies_Id,
|
||||
"sun.security.x509.CertificatePoliciesExtension");
|
||||
addInternal(EXT_KEY_USAGE, PKIXExtensions.ExtendedKeyUsage_Id,
|
||||
"sun.security.x509.ExtendedKeyUsageExtension");
|
||||
addInternal(INHIBIT_ANY_POLICY, PKIXExtensions.InhibitAnyPolicy_Id,
|
||||
"sun.security.x509.InhibitAnyPolicyExtension");
|
||||
addInternal(CRL_DIST_POINTS, PKIXExtensions.CRLDistributionPoints_Id,
|
||||
"sun.security.x509.CRLDistributionPointsExtension");
|
||||
addInternal(CERT_ISSUER, PKIXExtensions.CertificateIssuer_Id,
|
||||
"sun.security.x509.CertificateIssuerExtension");
|
||||
addInternal(SUBJECT_INFO_ACCESS, PKIXExtensions.SubjectInfoAccess_Id,
|
||||
"sun.security.x509.SubjectInfoAccessExtension");
|
||||
addInternal(AUTH_INFO_ACCESS, PKIXExtensions.AuthInfoAccess_Id,
|
||||
"sun.security.x509.AuthorityInfoAccessExtension");
|
||||
addInternal(ISSUING_DIST_POINT,
|
||||
PKIXExtensions.IssuingDistributionPoint_Id,
|
||||
"sun.security.x509.IssuingDistributionPointExtension");
|
||||
addInternal(DELTA_CRL_INDICATOR, PKIXExtensions.DeltaCRLIndicator_Id,
|
||||
"sun.security.x509.DeltaCRLIndicatorExtension");
|
||||
addInternal(FRESHEST_CRL, PKIXExtensions.FreshestCRL_Id,
|
||||
"sun.security.x509.FreshestCRLExtension");
|
||||
addInternal(OCSPNOCHECK, PKIXExtensions.OCSPNoCheck_Id,
|
||||
"sun.security.x509.OCSPNoCheckExtension");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add attributes to the table. For internal use in the static
|
||||
* initializer.
|
||||
*/
|
||||
private static void addInternal(String name, ObjectIdentifier oid,
|
||||
String className) {
|
||||
OIDInfo info = new OIDInfo(name, oid, className);
|
||||
oidMap.put(oid, info);
|
||||
nameMap.put(name, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class encapsulating the mapping info and Class loading.
|
||||
*/
|
||||
private static class OIDInfo {
|
||||
|
||||
final ObjectIdentifier oid;
|
||||
final String name;
|
||||
final String className;
|
||||
private volatile Class<?> clazz;
|
||||
|
||||
OIDInfo(String name, ObjectIdentifier oid, String className) {
|
||||
this.name = name;
|
||||
this.oid = oid;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
OIDInfo(String name, ObjectIdentifier oid, Class<?> clazz) {
|
||||
this.name = name;
|
||||
this.oid = oid;
|
||||
this.className = clazz.getName();
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Class object associated with this attribute.
|
||||
*/
|
||||
Class<?> getClazz() throws CertificateException {
|
||||
try {
|
||||
Class<?> c = clazz;
|
||||
if (c == null) {
|
||||
c = Class.forName(className);
|
||||
clazz = c;
|
||||
}
|
||||
return c;
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new CertificateException("Could not load class: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a name to lookup table.
|
||||
*
|
||||
* @param name the name of the attr
|
||||
* @param oid the string representation of the object identifier for
|
||||
* the class.
|
||||
* @param clazz the Class object associated with this attribute
|
||||
* @exception CertificateException on errors.
|
||||
*/
|
||||
public static void addAttribute(String name, String oid, Class<?> clazz)
|
||||
throws CertificateException {
|
||||
ObjectIdentifier objId;
|
||||
try {
|
||||
objId = new ObjectIdentifier(oid);
|
||||
} catch (IOException ioe) {
|
||||
throw new CertificateException
|
||||
("Invalid Object identifier: " + oid);
|
||||
}
|
||||
OIDInfo info = new OIDInfo(name, objId, clazz);
|
||||
if (oidMap.put(objId, info) != null) {
|
||||
throw new CertificateException
|
||||
("Object identifier already exists: " + oid);
|
||||
}
|
||||
if (nameMap.put(name, info) != null) {
|
||||
throw new CertificateException("Name already exists: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user friendly name associated with the OID.
|
||||
*
|
||||
* @param oid the name of the object identifier to be returned.
|
||||
* @return the user friendly name or null if no name
|
||||
* is registered for this oid.
|
||||
*/
|
||||
public static String getName(ObjectIdentifier oid) {
|
||||
OIDInfo info = oidMap.get(oid);
|
||||
return (info == null) ? null : info.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return Object identifier for user friendly name.
|
||||
*
|
||||
* @param name the user friendly name.
|
||||
* @return the Object Identifier or null if no oid
|
||||
* is registered for this name.
|
||||
*/
|
||||
public static ObjectIdentifier getOID(String name) {
|
||||
OIDInfo info = nameMap.get(name);
|
||||
return (info == null) ? null : info.oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the java class object associated with the user friendly name.
|
||||
*
|
||||
* @param name the user friendly name.
|
||||
* @exception CertificateException if class cannot be instantiated.
|
||||
*/
|
||||
public static Class<?> getClass(String name) throws CertificateException {
|
||||
OIDInfo info = nameMap.get(name);
|
||||
return (info == null) ? null : info.getClazz();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the java class object associated with the object identifier.
|
||||
*
|
||||
* @param oid the name of the object identifier to be returned.
|
||||
* @exception CertificateException if class cannot be instatiated.
|
||||
*/
|
||||
public static Class<?> getClass(ObjectIdentifier oid)
|
||||
throws CertificateException {
|
||||
OIDInfo info = oidMap.get(oid);
|
||||
return (info == null) ? null : info.getClazz();
|
||||
}
|
||||
|
||||
}
|
||||
175
jdkSrc/jdk8/sun/security/x509/OIDName.java
Normal file
175
jdkSrc/jdk8/sun/security/x509/OIDName.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the OIDName as required by the GeneralNames
|
||||
* ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see GeneralName
|
||||
* @see GeneralNames
|
||||
* @see GeneralNameInterface
|
||||
*/
|
||||
public class OIDName implements GeneralNameInterface {
|
||||
private ObjectIdentifier oid;
|
||||
|
||||
/**
|
||||
* Create the OIDName object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER OIDName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public OIDName(DerValue derValue) throws IOException {
|
||||
oid = derValue.getOID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the OIDName object with the specified name.
|
||||
*
|
||||
* @param name the OIDName.
|
||||
*/
|
||||
public OIDName(ObjectIdentifier oid) {
|
||||
this.oid = oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the OIDName from the String form of the OID
|
||||
*
|
||||
* @param name the OIDName in form "x.y.z..."
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public OIDName(String name) throws IOException {
|
||||
try {
|
||||
oid = new ObjectIdentifier(name);
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Unable to create OIDName: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return (GeneralNameInterface.NAME_OID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the OID name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the OIDName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putOID(oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the name into user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("OIDName: " + oid.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this OID name.
|
||||
*/
|
||||
public ObjectIdentifier getOID() {
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are identical
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof OIDName))
|
||||
return false;
|
||||
|
||||
OIDName other = (OIDName)obj;
|
||||
|
||||
return oid.equals((Object)other.oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return oid.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
*
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is not exact match, but narrowing and widening are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != NAME_OID)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (this.equals((OIDName)inputName))
|
||||
constraintType = NAME_MATCH;
|
||||
else
|
||||
//widens and narrows not defined in RFC2459 for OIDName (aka registeredID)
|
||||
throw new UnsupportedOperationException("Narrowing and widening are not supported for OIDNames");
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("subtreeDepth() not supported for OIDName.");
|
||||
}
|
||||
}
|
||||
269
jdkSrc/jdk8/sun/security/x509/OtherName.java
Normal file
269
jdkSrc/jdk8/sun/security/x509/OtherName.java
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Arrays;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class represents the OtherName as required by the GeneralNames
|
||||
* ASN.1 object. It supplies the generic framework to allow specific
|
||||
* Other Name types, and also provides minimal support for unrecognized
|
||||
* Other Name types.
|
||||
*
|
||||
* The ASN.1 definition for OtherName is:
|
||||
* <pre>
|
||||
* OtherName ::= SEQUENCE {
|
||||
* type-id OBJECT IDENTIFIER,
|
||||
* value [0] EXPLICIT ANY DEFINED BY type-id
|
||||
* }
|
||||
* </pre>
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class OtherName implements GeneralNameInterface {
|
||||
|
||||
private String name;
|
||||
private ObjectIdentifier oid;
|
||||
private byte[] nameValue = null;
|
||||
private GeneralNameInterface gni = null;
|
||||
|
||||
private static final byte TAG_VALUE = 0;
|
||||
|
||||
private int myhash = -1;
|
||||
|
||||
/**
|
||||
* Create the OtherName object from a passed ObjectIdentfier and
|
||||
* byte array name value
|
||||
*
|
||||
* @param oid ObjectIdentifier of this OtherName object
|
||||
* @param value the DER-encoded value of the OtherName
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public OtherName(ObjectIdentifier oid, byte[] value) throws IOException {
|
||||
if (oid == null || value == null) {
|
||||
throw new NullPointerException("parameters may not be null");
|
||||
}
|
||||
this.oid = oid;
|
||||
this.nameValue = value;
|
||||
gni = getGNI(oid, value);
|
||||
if (gni != null) {
|
||||
name = gni.toString();
|
||||
} else {
|
||||
name = "Unrecognized ObjectIdentifier: " + oid.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the OtherName object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER OtherName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public OtherName(DerValue derValue) throws IOException {
|
||||
DerInputStream in = derValue.toDerInputStream();
|
||||
|
||||
oid = in.getOID();
|
||||
DerValue val = in.getDerValue();
|
||||
nameValue = val.toByteArray();
|
||||
gni = getGNI(oid, nameValue);
|
||||
if (gni != null) {
|
||||
name = gni.toString();
|
||||
} else {
|
||||
name = "Unrecognized ObjectIdentifier: " + oid.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ObjectIdentifier
|
||||
*/
|
||||
public ObjectIdentifier getOID() {
|
||||
//XXXX May want to consider cloning this
|
||||
return oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name value
|
||||
*/
|
||||
public byte[] getNameValue() {
|
||||
return nameValue.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get GeneralNameInterface
|
||||
*/
|
||||
private GeneralNameInterface getGNI(ObjectIdentifier oid, byte[] nameValue)
|
||||
throws IOException {
|
||||
try {
|
||||
Class<?> extClass = OIDMap.getClass(oid);
|
||||
if (extClass == null) { // Unsupported OtherName
|
||||
return null;
|
||||
}
|
||||
Class<?>[] params = { Object.class };
|
||||
Constructor<?> cons = extClass.getConstructor(params);
|
||||
|
||||
Object[] passed = new Object[] { nameValue };
|
||||
GeneralNameInterface gni =
|
||||
(GeneralNameInterface)cons.newInstance(passed);
|
||||
return gni;
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Instantiation error: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return GeneralNameInterface.NAME_ANY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the Other name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the Other-Name to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
if (gni != null) {
|
||||
// This OtherName has a supported class
|
||||
gni.encode(out);
|
||||
return;
|
||||
} else {
|
||||
// This OtherName has no supporting class
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putOID(oid);
|
||||
tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, TAG_VALUE), nameValue);
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are identical.
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof OtherName)) {
|
||||
return false;
|
||||
}
|
||||
OtherName otherOther = (OtherName)other;
|
||||
if (!(otherOther.oid.equals((Object)oid))) {
|
||||
return false;
|
||||
}
|
||||
GeneralNameInterface otherGNI = null;
|
||||
try {
|
||||
otherGNI = getGNI(otherOther.oid, otherOther.nameValue);
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean result;
|
||||
if (otherGNI != null) {
|
||||
try {
|
||||
result = (otherGNI.constrains(this) == NAME_MATCH);
|
||||
} catch (UnsupportedOperationException ioe) {
|
||||
result = false;
|
||||
}
|
||||
} else {
|
||||
result = Arrays.equals(nameValue, otherOther.nameValue);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this OtherName.
|
||||
*
|
||||
* @return a hash code value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
if (myhash == -1) {
|
||||
myhash = 37 + oid.hashCode();
|
||||
for (int i = 0; i < nameValue.length; i++) {
|
||||
myhash = 37 * myhash + nameValue[i];
|
||||
}
|
||||
}
|
||||
return myhash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the name into user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return "Other-Name: " + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name
|
||||
* (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the
|
||||
* naming subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the
|
||||
* naming subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name,
|
||||
* but is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
*
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is same type, but
|
||||
* comparison operations are not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) {
|
||||
int constraintType;
|
||||
if (inputName == null) {
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
} else if (inputName.getType() != NAME_ANY) {
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Narrowing, widening, "
|
||||
+ "and matching are not supported for OtherName.");
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() {
|
||||
throw new UnsupportedOperationException
|
||||
("subtreeDepth() not supported for generic OtherName");
|
||||
}
|
||||
|
||||
}
|
||||
284
jdkSrc/jdk8/sun/security/x509/PKIXExtensions.java
Normal file
284
jdkSrc/jdk8/sun/security/x509/PKIXExtensions.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Lists all the object identifiers of the X509 extensions of the PKIX profile.
|
||||
*
|
||||
* <p>Extensions are addiitonal attributes which can be inserted in a X509
|
||||
* v3 certificate. For example a "Driving License Certificate" could have
|
||||
* the driving license number as a extension.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
*
|
||||
* @see Extension
|
||||
*
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class PKIXExtensions {
|
||||
// The object identifiers
|
||||
private static final int[] AuthorityKey_data = { 2, 5, 29, 35 };
|
||||
private static final int[] SubjectKey_data = { 2, 5, 29, 14 };
|
||||
private static final int[] KeyUsage_data = { 2, 5, 29, 15 };
|
||||
private static final int[] PrivateKeyUsage_data = { 2, 5, 29, 16 };
|
||||
private static final int[] CertificatePolicies_data = { 2, 5, 29, 32 };
|
||||
private static final int[] PolicyMappings_data = { 2, 5, 29, 33 };
|
||||
private static final int[] SubjectAlternativeName_data = { 2, 5, 29, 17 };
|
||||
private static final int[] IssuerAlternativeName_data = { 2, 5, 29, 18 };
|
||||
private static final int[] SubjectDirectoryAttributes_data = { 2, 5, 29, 9 };
|
||||
private static final int[] BasicConstraints_data = { 2, 5, 29, 19 };
|
||||
private static final int[] NameConstraints_data = { 2, 5, 29, 30 };
|
||||
private static final int[] PolicyConstraints_data = { 2, 5, 29, 36 };
|
||||
private static final int[] CRLDistributionPoints_data = { 2, 5, 29, 31 };
|
||||
private static final int[] CRLNumber_data = { 2, 5, 29, 20 };
|
||||
private static final int[] IssuingDistributionPoint_data = { 2, 5, 29, 28 };
|
||||
private static final int[] DeltaCRLIndicator_data = { 2, 5, 29, 27 };
|
||||
private static final int[] ReasonCode_data = { 2, 5, 29, 21 };
|
||||
private static final int[] HoldInstructionCode_data = { 2, 5, 29, 23 };
|
||||
private static final int[] InvalidityDate_data = { 2, 5, 29, 24 };
|
||||
private static final int[] ExtendedKeyUsage_data = { 2, 5, 29, 37 };
|
||||
private static final int[] InhibitAnyPolicy_data = { 2, 5, 29, 54 };
|
||||
private static final int[] CertificateIssuer_data = { 2, 5, 29, 29 };
|
||||
private static final int[] AuthInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
|
||||
private static final int[] SubjectInfoAccess_data = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
|
||||
private static final int[] FreshestCRL_data = { 2, 5, 29, 46 };
|
||||
private static final int[] OCSPNoCheck_data = { 1, 3, 6, 1, 5, 5, 7,
|
||||
48, 1, 5};
|
||||
|
||||
// Additional extensions under the PKIX arc that are not necessarily
|
||||
// used in X.509 Certificates or CRLs.
|
||||
private static final int[] OCSPNonce_data = { 1, 3, 6, 1, 5, 5, 7,
|
||||
48, 1, 2};
|
||||
|
||||
/**
|
||||
* Identifies the particular public key used to sign the certificate.
|
||||
*/
|
||||
public static final ObjectIdentifier AuthorityKey_Id;
|
||||
|
||||
/**
|
||||
* Identifies the particular public key used in an application.
|
||||
*/
|
||||
public static final ObjectIdentifier SubjectKey_Id;
|
||||
|
||||
/**
|
||||
* Defines the purpose of the key contained in the certificate.
|
||||
*/
|
||||
public static final ObjectIdentifier KeyUsage_Id;
|
||||
|
||||
/**
|
||||
* Allows the certificate issuer to specify a different validity period
|
||||
* for the private key than the certificate.
|
||||
*/
|
||||
public static final ObjectIdentifier PrivateKeyUsage_Id;
|
||||
|
||||
/**
|
||||
* Contains the sequence of policy information terms.
|
||||
*/
|
||||
public static final ObjectIdentifier CertificatePolicies_Id;
|
||||
|
||||
/**
|
||||
* Lists pairs of object identifiers of policies considered equivalent by
|
||||
* the issuing CA to the subject CA.
|
||||
*/
|
||||
public static final ObjectIdentifier PolicyMappings_Id;
|
||||
|
||||
/**
|
||||
* Allows additional identities to be bound to the subject of the
|
||||
* certificate.
|
||||
*/
|
||||
public static final ObjectIdentifier SubjectAlternativeName_Id;
|
||||
|
||||
/**
|
||||
* Allows additional identities to be associated with the certificate
|
||||
* issuer.
|
||||
*/
|
||||
public static final ObjectIdentifier IssuerAlternativeName_Id;
|
||||
|
||||
/**
|
||||
* Identifies additional directory attributes.
|
||||
* This extension is always non-critical.
|
||||
*/
|
||||
public static final ObjectIdentifier SubjectDirectoryAttributes_Id;
|
||||
|
||||
/**
|
||||
* Identifies whether the subject of the certificate is a CA and how deep
|
||||
* a certification path may exist through that CA.
|
||||
*/
|
||||
public static final ObjectIdentifier BasicConstraints_Id;
|
||||
|
||||
/**
|
||||
* Provides for permitted and excluded subtrees that place restrictions
|
||||
* on names that may be included within a certificate issued by a given CA.
|
||||
*/
|
||||
public static final ObjectIdentifier NameConstraints_Id;
|
||||
|
||||
/**
|
||||
* Used to either prohibit policy mapping or limit the set of policies
|
||||
* that can be in subsequent certificates.
|
||||
*/
|
||||
public static final ObjectIdentifier PolicyConstraints_Id;
|
||||
|
||||
/**
|
||||
* Identifies how CRL information is obtained.
|
||||
*/
|
||||
public static final ObjectIdentifier CRLDistributionPoints_Id;
|
||||
|
||||
/**
|
||||
* Conveys a monotonically increasing sequence number for each CRL
|
||||
* issued by a given CA.
|
||||
*/
|
||||
public static final ObjectIdentifier CRLNumber_Id;
|
||||
|
||||
/**
|
||||
* Identifies the CRL distribution point for a particular CRL.
|
||||
*/
|
||||
public static final ObjectIdentifier IssuingDistributionPoint_Id;
|
||||
|
||||
/**
|
||||
* Identifies the delta CRL.
|
||||
*/
|
||||
public static final ObjectIdentifier DeltaCRLIndicator_Id;
|
||||
|
||||
/**
|
||||
* Identifies the reason for the certificate revocation.
|
||||
*/
|
||||
public static final ObjectIdentifier ReasonCode_Id;
|
||||
|
||||
/**
|
||||
* This extension provides a registered instruction identifier indicating
|
||||
* the action to be taken, after encountering a certificate that has been
|
||||
* placed on hold.
|
||||
*/
|
||||
public static final ObjectIdentifier HoldInstructionCode_Id;
|
||||
|
||||
/**
|
||||
* Identifies the date on which it is known or suspected that the private
|
||||
* key was compromised or that the certificate otherwise became invalid.
|
||||
*/
|
||||
public static final ObjectIdentifier InvalidityDate_Id;
|
||||
/**
|
||||
* Identifies one or more purposes for which the certified public key
|
||||
* may be used, in addition to or in place of the basic purposes
|
||||
* indicated in the key usage extension field.
|
||||
*/
|
||||
public static final ObjectIdentifier ExtendedKeyUsage_Id;
|
||||
|
||||
/**
|
||||
* Specifies whether any-policy policy OID is permitted
|
||||
*/
|
||||
public static final ObjectIdentifier InhibitAnyPolicy_Id;
|
||||
|
||||
/**
|
||||
* Identifies the certificate issuer associated with an entry in an
|
||||
* indirect CRL.
|
||||
*/
|
||||
public static final ObjectIdentifier CertificateIssuer_Id;
|
||||
|
||||
/**
|
||||
* This extension indicates how to access CA information and services for
|
||||
* the issuer of the certificate in which the extension appears.
|
||||
* This information may be used for on-line certification validation
|
||||
* services.
|
||||
*/
|
||||
public static final ObjectIdentifier AuthInfoAccess_Id;
|
||||
|
||||
/**
|
||||
* This extension indicates how to access CA information and services for
|
||||
* the subject of the certificate in which the extension appears.
|
||||
*/
|
||||
public static final ObjectIdentifier SubjectInfoAccess_Id;
|
||||
|
||||
/**
|
||||
* Identifies how delta CRL information is obtained.
|
||||
*/
|
||||
public static final ObjectIdentifier FreshestCRL_Id;
|
||||
|
||||
/**
|
||||
* Identifies the OCSP client can trust the responder for the
|
||||
* lifetime of the responder's certificate.
|
||||
*/
|
||||
public static final ObjectIdentifier OCSPNoCheck_Id;
|
||||
|
||||
/**
|
||||
* This extension is used to provide nonce data for OCSP requests
|
||||
* or responses.
|
||||
*/
|
||||
public static final ObjectIdentifier OCSPNonce_Id;
|
||||
|
||||
static {
|
||||
AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data);
|
||||
SubjectKey_Id = ObjectIdentifier.newInternal(SubjectKey_data);
|
||||
KeyUsage_Id = ObjectIdentifier.newInternal(KeyUsage_data);
|
||||
PrivateKeyUsage_Id = ObjectIdentifier.newInternal(PrivateKeyUsage_data);
|
||||
CertificatePolicies_Id =
|
||||
ObjectIdentifier.newInternal(CertificatePolicies_data);
|
||||
PolicyMappings_Id = ObjectIdentifier.newInternal(PolicyMappings_data);
|
||||
SubjectAlternativeName_Id =
|
||||
ObjectIdentifier.newInternal(SubjectAlternativeName_data);
|
||||
IssuerAlternativeName_Id =
|
||||
ObjectIdentifier.newInternal(IssuerAlternativeName_data);
|
||||
ExtendedKeyUsage_Id = ObjectIdentifier.newInternal(ExtendedKeyUsage_data);
|
||||
InhibitAnyPolicy_Id = ObjectIdentifier.newInternal(InhibitAnyPolicy_data);
|
||||
SubjectDirectoryAttributes_Id =
|
||||
ObjectIdentifier.newInternal(SubjectDirectoryAttributes_data);
|
||||
BasicConstraints_Id =
|
||||
ObjectIdentifier.newInternal(BasicConstraints_data);
|
||||
ReasonCode_Id = ObjectIdentifier.newInternal(ReasonCode_data);
|
||||
HoldInstructionCode_Id =
|
||||
ObjectIdentifier.newInternal(HoldInstructionCode_data);
|
||||
InvalidityDate_Id = ObjectIdentifier.newInternal(InvalidityDate_data);
|
||||
|
||||
NameConstraints_Id = ObjectIdentifier.newInternal(NameConstraints_data);
|
||||
PolicyConstraints_Id =
|
||||
ObjectIdentifier.newInternal(PolicyConstraints_data);
|
||||
CRLDistributionPoints_Id =
|
||||
ObjectIdentifier.newInternal(CRLDistributionPoints_data);
|
||||
CRLNumber_Id =
|
||||
ObjectIdentifier.newInternal(CRLNumber_data);
|
||||
IssuingDistributionPoint_Id =
|
||||
ObjectIdentifier.newInternal(IssuingDistributionPoint_data);
|
||||
DeltaCRLIndicator_Id =
|
||||
ObjectIdentifier.newInternal(DeltaCRLIndicator_data);
|
||||
CertificateIssuer_Id =
|
||||
ObjectIdentifier.newInternal(CertificateIssuer_data);
|
||||
AuthInfoAccess_Id =
|
||||
ObjectIdentifier.newInternal(AuthInfoAccess_data);
|
||||
SubjectInfoAccess_Id =
|
||||
ObjectIdentifier.newInternal(SubjectInfoAccess_data);
|
||||
FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data);
|
||||
OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data);
|
||||
OCSPNonce_Id = ObjectIdentifier.newInternal(OCSPNonce_data);
|
||||
}
|
||||
}
|
||||
278
jdkSrc/jdk8/sun/security/x509/PolicyConstraintsExtension.java
Normal file
278
jdkSrc/jdk8/sun/security/x509/PolicyConstraintsExtension.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the certificate extension which specifies the
|
||||
* Policy constraints.
|
||||
* <p>
|
||||
* The policy constraints extension can be used in certificates issued
|
||||
* to CAs. The policy constraints extension constrains path validation
|
||||
* in two ways. It can be used to prohibit policy mapping or require
|
||||
* that each certificate in a path contain an acceptable policy
|
||||
* identifier.<p>
|
||||
* The ASN.1 syntax for this is (IMPLICIT tagging is defined in the
|
||||
* module definition):
|
||||
* <pre>
|
||||
* PolicyConstraints ::= SEQUENCE {
|
||||
* requireExplicitPolicy [0] SkipCerts OPTIONAL,
|
||||
* inhibitPolicyMapping [1] SkipCerts OPTIONAL
|
||||
* }
|
||||
* SkipCerts ::= INTEGER (0..MAX)
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class PolicyConstraintsExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.PolicyConstraints";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "PolicyConstraints";
|
||||
public static final String REQUIRE = "require";
|
||||
public static final String INHIBIT = "inhibit";
|
||||
|
||||
private static final byte TAG_REQUIRE = 0;
|
||||
private static final byte TAG_INHIBIT = 1;
|
||||
|
||||
private int require = -1;
|
||||
private int inhibit = -1;
|
||||
|
||||
// Encode this extension value.
|
||||
private void encodeThis() throws IOException {
|
||||
if (require == -1 && inhibit == -1) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
|
||||
if (require != -1) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putInteger(require);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_REQUIRE), tmp);
|
||||
}
|
||||
if (inhibit != -1) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putInteger(inhibit);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_INHIBIT), tmp);
|
||||
}
|
||||
seq.write(DerValue.tag_Sequence, tagged);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PolicyConstraintsExtension object with both
|
||||
* require explicit policy and inhibit policy mapping. The
|
||||
* extension is marked non-critical.
|
||||
*
|
||||
* @param require require explicit policy (-1 for optional).
|
||||
* @param inhibit inhibit policy mapping (-1 for optional).
|
||||
*/
|
||||
public PolicyConstraintsExtension(int require, int inhibit)
|
||||
throws IOException {
|
||||
this(Boolean.FALSE, require, inhibit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PolicyConstraintsExtension object with specified
|
||||
* criticality and both require explicit policy and inhibit
|
||||
* policy mapping.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param require require explicit policy (-1 for optional).
|
||||
* @param inhibit inhibit policy mapping (-1 for optional).
|
||||
*/
|
||||
public PolicyConstraintsExtension(Boolean critical, int require, int inhibit)
|
||||
throws IOException {
|
||||
this.require = require;
|
||||
this.inhibit = inhibit;
|
||||
this.extensionId = PKIXExtensions.PolicyConstraints_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from its DER encoded value and criticality.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public PolicyConstraintsExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.PolicyConstraints_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Sequence tag missing for PolicyConstraint.");
|
||||
}
|
||||
DerInputStream in = val.data;
|
||||
while (in != null && in.available() != 0) {
|
||||
DerValue next = in.getDerValue();
|
||||
|
||||
if (next.isContextSpecific(TAG_REQUIRE) && !next.isConstructed()) {
|
||||
if (this.require != -1)
|
||||
throw new IOException("Duplicate requireExplicitPolicy" +
|
||||
"found in the PolicyConstraintsExtension");
|
||||
next.resetTag(DerValue.tag_Integer);
|
||||
this.require = next.getInteger();
|
||||
|
||||
} else if (next.isContextSpecific(TAG_INHIBIT) &&
|
||||
!next.isConstructed()) {
|
||||
if (this.inhibit != -1)
|
||||
throw new IOException("Duplicate inhibitPolicyMapping" +
|
||||
"found in the PolicyConstraintsExtension");
|
||||
next.resetTag(DerValue.tag_Integer);
|
||||
this.inhibit = next.getInteger();
|
||||
} else
|
||||
throw new IOException("Invalid encoding of PolicyConstraint");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
String s;
|
||||
s = super.toString() + "PolicyConstraints: [" + " Require: ";
|
||||
if (require == -1)
|
||||
s += "unspecified;";
|
||||
else
|
||||
s += require + ";";
|
||||
s += "\tInhibit: ";
|
||||
if (inhibit == -1)
|
||||
s += "unspecified";
|
||||
else
|
||||
s += inhibit;
|
||||
s += " ]\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.PolicyConstraints_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Integer)) {
|
||||
throw new IOException("Attribute value should be of type Integer.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(REQUIRE)) {
|
||||
require = ((Integer)obj).intValue();
|
||||
} else if (name.equalsIgnoreCase(INHIBIT)) {
|
||||
inhibit = ((Integer)obj).intValue();
|
||||
} else {
|
||||
throw new IOException("Attribute name " + "[" + name + "]" +
|
||||
" not recognized by " +
|
||||
"CertAttrSet:PolicyConstraints.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Integer get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(REQUIRE)) {
|
||||
return new Integer(require);
|
||||
} else if (name.equalsIgnoreCase(INHIBIT)) {
|
||||
return new Integer(inhibit);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:PolicyConstraints.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(REQUIRE)) {
|
||||
require = -1;
|
||||
} else if (name.equalsIgnoreCase(INHIBIT)) {
|
||||
inhibit = -1;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:PolicyConstraints.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(REQUIRE);
|
||||
elements.addElement(INHIBIT);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
284
jdkSrc/jdk8/sun/security/x509/PolicyInformation.java
Normal file
284
jdkSrc/jdk8/sun/security/x509/PolicyInformation.java
Normal file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.PolicyQualifierInfo;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.DerOutputStream;
|
||||
/**
|
||||
* PolicyInformation is the class that contains a specific certificate policy
|
||||
* that is part of the CertificatePoliciesExtension. A
|
||||
* CertificatePolicyExtension value consists of a vector of these objects.
|
||||
* <p>
|
||||
* The ASN.1 syntax for PolicyInformation (IMPLICIT tagging is defined in the
|
||||
* module definition):
|
||||
* <pre>
|
||||
*
|
||||
* PolicyInformation ::= SEQUENCE {
|
||||
* policyIdentifier CertPolicyId,
|
||||
* policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||||
* PolicyQualifierInfo OPTIONAL }
|
||||
*
|
||||
* CertPolicyId ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* PolicyQualifierInfo ::= SEQUENCE {
|
||||
* policyQualifierId PolicyQualifierId,
|
||||
* qualifier ANY DEFINED BY policyQualifierId }
|
||||
* </pre>
|
||||
*
|
||||
* @author Sean Mullan
|
||||
* @author Anne Anderson
|
||||
* @since 1.4
|
||||
*/
|
||||
public class PolicyInformation {
|
||||
|
||||
// Attribute names
|
||||
public static final String NAME = "PolicyInformation";
|
||||
public static final String ID = "id";
|
||||
public static final String QUALIFIERS = "qualifiers";
|
||||
|
||||
/* The policy OID */
|
||||
private CertificatePolicyId policyIdentifier;
|
||||
|
||||
/* A Set of java.security.cert.PolicyQualifierInfo objects */
|
||||
private Set<PolicyQualifierInfo> policyQualifiers;
|
||||
|
||||
/**
|
||||
* Create an instance of PolicyInformation
|
||||
*
|
||||
* @param policyIdentifier the policyIdentifier as a
|
||||
* CertificatePolicyId
|
||||
* @param policyQualifiers a Set of PolicyQualifierInfo objects.
|
||||
* Must not be NULL. Specify an empty Set for no qualifiers.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public PolicyInformation(CertificatePolicyId policyIdentifier,
|
||||
Set<PolicyQualifierInfo> policyQualifiers) throws IOException {
|
||||
if (policyQualifiers == null) {
|
||||
throw new NullPointerException("policyQualifiers is null");
|
||||
}
|
||||
this.policyQualifiers =
|
||||
new LinkedHashSet<PolicyQualifierInfo>(policyQualifiers);
|
||||
this.policyIdentifier = policyIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of PolicyInformation, decoding from
|
||||
* the passed DerValue.
|
||||
*
|
||||
* @param val the DerValue to construct the PolicyInformation from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public PolicyInformation(DerValue val) throws IOException {
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding of PolicyInformation");
|
||||
}
|
||||
policyIdentifier = new CertificatePolicyId(val.data.getDerValue());
|
||||
if (val.data.available() != 0) {
|
||||
policyQualifiers = new LinkedHashSet<PolicyQualifierInfo>();
|
||||
DerValue opt = val.data.getDerValue();
|
||||
if (opt.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("Invalid encoding of PolicyInformation");
|
||||
if (opt.data.available() == 0)
|
||||
throw new IOException("No data available in policyQualifiers");
|
||||
while (opt.data.available() != 0)
|
||||
policyQualifiers.add(new PolicyQualifierInfo
|
||||
(opt.data.getDerValue().toByteArray()));
|
||||
} else {
|
||||
policyQualifiers = Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this PolicyInformation with another object for equality
|
||||
*
|
||||
* @param other object to be compared with this
|
||||
* @return true iff the PolicyInformation objects match
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof PolicyInformation))
|
||||
return false;
|
||||
PolicyInformation piOther = (PolicyInformation)other;
|
||||
|
||||
if (!policyIdentifier.equals(piOther.getPolicyIdentifier()))
|
||||
return false;
|
||||
|
||||
return policyQualifiers.equals(piOther.getPolicyQualifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this PolicyInformation.
|
||||
*
|
||||
* @return a hash code value.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int myhash = 37 + policyIdentifier.hashCode();
|
||||
myhash = 37 * myhash + policyQualifiers.hashCode();
|
||||
return myhash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the policyIdentifier value
|
||||
*
|
||||
* @return The CertificatePolicyId object containing
|
||||
* the policyIdentifier (not a copy).
|
||||
*/
|
||||
public CertificatePolicyId getPolicyIdentifier() {
|
||||
return policyIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the policyQualifiers value
|
||||
*
|
||||
* @return a Set of PolicyQualifierInfo objects associated
|
||||
* with this certificate policy (not a copy).
|
||||
* Returns an empty Set if there are no qualifiers.
|
||||
* Never returns null.
|
||||
*/
|
||||
public Set<PolicyQualifierInfo> getPolicyQualifiers() {
|
||||
return policyQualifiers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(ID)) {
|
||||
return policyIdentifier;
|
||||
} else if (name.equalsIgnoreCase(QUALIFIERS)) {
|
||||
return policyQualifiers;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by PolicyInformation.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with instanceof
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(ID)) {
|
||||
if (obj instanceof CertificatePolicyId)
|
||||
policyIdentifier = (CertificatePolicyId)obj;
|
||||
else
|
||||
throw new IOException("Attribute value must be instance " +
|
||||
"of CertificatePolicyId.");
|
||||
} else if (name.equalsIgnoreCase(QUALIFIERS)) {
|
||||
if (policyIdentifier == null) {
|
||||
throw new IOException("Attribute must have a " +
|
||||
"CertificatePolicyIdentifier value before " +
|
||||
"PolicyQualifierInfo can be set.");
|
||||
}
|
||||
if (obj instanceof Set) {
|
||||
Iterator<?> i = ((Set<?>)obj).iterator();
|
||||
while (i.hasNext()) {
|
||||
Object obj1 = i.next();
|
||||
if (!(obj1 instanceof PolicyQualifierInfo)) {
|
||||
throw new IOException("Attribute value must be a" +
|
||||
"Set of PolicyQualifierInfo objects.");
|
||||
}
|
||||
}
|
||||
policyQualifiers = (Set<PolicyQualifierInfo>) obj;
|
||||
} else {
|
||||
throw new IOException("Attribute value must be of type Set.");
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by PolicyInformation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(QUALIFIERS)) {
|
||||
policyQualifiers = Collections.emptySet();
|
||||
} else if (name.equalsIgnoreCase(ID)) {
|
||||
throw new IOException("Attribute ID may not be deleted from " +
|
||||
"PolicyInformation.");
|
||||
} else {
|
||||
//ID may not be deleted
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by PolicyInformation.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(ID);
|
||||
elements.addElement(QUALIFIERS);
|
||||
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a printable representation of the PolicyInformation.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder(" [" + policyIdentifier.toString());
|
||||
s.append(policyQualifiers + " ]\n");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the PolicyInformation to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
policyIdentifier.encode(tmp);
|
||||
if (!policyQualifiers.isEmpty()) {
|
||||
DerOutputStream tmp2 = new DerOutputStream();
|
||||
for (PolicyQualifierInfo pq : policyQualifiers) {
|
||||
tmp2.write(pq.getEncoded());
|
||||
}
|
||||
tmp.write(DerValue.tag_Sequence, tmp2);
|
||||
}
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
}
|
||||
}
|
||||
223
jdkSrc/jdk8/sun/security/x509/PolicyMappingsExtension.java
Normal file
223
jdkSrc/jdk8/sun/security/x509/PolicyMappingsExtension.java
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the Policy Mappings Extension.
|
||||
*
|
||||
* This extension, if present, identifies the certificate policies considered
|
||||
* identical between the issuing and the subject CA.
|
||||
* <p>Extensions are addiitonal attributes which can be inserted in a X509
|
||||
* v3 certificate. For example a "Driving License Certificate" could have
|
||||
* the driving license number as a extension.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class PolicyMappingsExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.PolicyMappings";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "PolicyMappings";
|
||||
public static final String MAP = "map";
|
||||
|
||||
// Private data members
|
||||
private List<CertificatePolicyMap> maps;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (maps == null || maps.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
for (CertificatePolicyMap map : maps) {
|
||||
map.encode(tmp);
|
||||
}
|
||||
|
||||
os.write(DerValue.tag_Sequence, tmp);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PolicyMappings with the List of CertificatePolicyMap.
|
||||
*
|
||||
* @param maps the List of CertificatePolicyMap.
|
||||
*/
|
||||
public PolicyMappingsExtension(List<CertificatePolicyMap> map)
|
||||
throws IOException {
|
||||
this.maps = map;
|
||||
this.extensionId = PKIXExtensions.PolicyMappings_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default PolicyMappingsExtension.
|
||||
*/
|
||||
public PolicyMappingsExtension() {
|
||||
extensionId = PKIXExtensions.KeyUsage_Id;
|
||||
critical = false;
|
||||
maps = Collections.<CertificatePolicyMap>emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @params critical true if the extension is to be treated as critical.
|
||||
* @params value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public PolicyMappingsExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.PolicyMappings_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"PolicyMappingsExtension.");
|
||||
}
|
||||
maps = new ArrayList<CertificatePolicyMap>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
CertificatePolicyMap map = new CertificatePolicyMap(seq);
|
||||
maps.add(map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the policy map.
|
||||
*/
|
||||
public String toString() {
|
||||
if (maps == null) return "";
|
||||
String s = super.toString() + "PolicyMappings [\n"
|
||||
+ maps.toString() + "]\n";
|
||||
|
||||
return (s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.PolicyMappings_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with instanceof
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(MAP)) {
|
||||
if (!(obj instanceof List)) {
|
||||
throw new IOException("Attribute value should be of" +
|
||||
" type List.");
|
||||
}
|
||||
maps = (List<CertificatePolicyMap>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:PolicyMappingsExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public List<CertificatePolicyMap> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(MAP)) {
|
||||
return (maps);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:PolicyMappingsExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(MAP)) {
|
||||
maps = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:PolicyMappingsExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements () {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(MAP);
|
||||
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName () {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
312
jdkSrc/jdk8/sun/security/x509/PrivateKeyUsageExtension.java
Normal file
312
jdkSrc/jdk8/sun/security/x509/PrivateKeyUsageExtension.java
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the Private Key Usage Extension.
|
||||
*
|
||||
* <p>The Private Key Usage Period extension allows the certificate issuer
|
||||
* to specify a different validity period for the private key than the
|
||||
* certificate. This extension is intended for use with digital
|
||||
* signature keys. This extension consists of two optional components
|
||||
* notBefore and notAfter. The private key associated with the
|
||||
* certificate should not be used to sign objects before or after the
|
||||
* times specified by the two components, respectively.
|
||||
*
|
||||
* <pre>
|
||||
* PrivateKeyUsagePeriod ::= SEQUENCE {
|
||||
* notBefore [0] GeneralizedTime OPTIONAL,
|
||||
* notAfter [1] GeneralizedTime OPTIONAL }
|
||||
* </pre>
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class PrivateKeyUsageExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info.extensions.PrivateKeyUsage";
|
||||
/**
|
||||
* Sub attributes name for this CertAttrSet.
|
||||
*/
|
||||
public static final String NAME = "PrivateKeyUsage";
|
||||
public static final String NOT_BEFORE = "not_before";
|
||||
public static final String NOT_AFTER = "not_after";
|
||||
|
||||
// Private data members
|
||||
private static final byte TAG_BEFORE = 0;
|
||||
private static final byte TAG_AFTER = 1;
|
||||
|
||||
private Date notBefore = null;
|
||||
private Date notAfter = null;
|
||||
|
||||
// Encode this extension value.
|
||||
private void encodeThis() throws IOException {
|
||||
if (notBefore == null && notAfter == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
|
||||
DerOutputStream tagged = new DerOutputStream();
|
||||
if (notBefore != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putGeneralizedTime(notBefore);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_BEFORE), tmp);
|
||||
}
|
||||
if (notAfter != null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
tmp.putGeneralizedTime(notAfter);
|
||||
tagged.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false, TAG_AFTER), tmp);
|
||||
}
|
||||
seq.write(DerValue.tag_Sequence, tagged);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for PrivateKeyUsageExtension.
|
||||
*
|
||||
* @param notBefore the date/time before which the private key
|
||||
* should not be used.
|
||||
* @param notAfter the date/time after which the private key
|
||||
* should not be used.
|
||||
*/
|
||||
public PrivateKeyUsageExtension(Date notBefore, Date notAfter)
|
||||
throws IOException {
|
||||
this.notBefore = notBefore;
|
||||
this.notAfter = notAfter;
|
||||
|
||||
this.extensionId = PKIXExtensions.PrivateKeyUsage_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception CertificateException on certificate parsing errors.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public PrivateKeyUsageExtension(Boolean critical, Object value)
|
||||
throws CertificateException, IOException {
|
||||
this.extensionId = PKIXExtensions.PrivateKeyUsage_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerInputStream str = new DerInputStream(this.extensionValue);
|
||||
DerValue[] seq = str.getSequence(2);
|
||||
|
||||
// NB. this is always encoded with the IMPLICIT tag
|
||||
// The checks only make sense if we assume implicit tagging,
|
||||
// with explicit tagging the form is always constructed.
|
||||
for (int i = 0; i < seq.length; i++) {
|
||||
DerValue opt = seq[i];
|
||||
|
||||
if (opt.isContextSpecific(TAG_BEFORE) &&
|
||||
!opt.isConstructed()) {
|
||||
if (notBefore != null) {
|
||||
throw new CertificateParsingException(
|
||||
"Duplicate notBefore in PrivateKeyUsage.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_GeneralizedTime);
|
||||
str = new DerInputStream(opt.toByteArray());
|
||||
notBefore = str.getGeneralizedTime();
|
||||
|
||||
} else if (opt.isContextSpecific(TAG_AFTER) &&
|
||||
!opt.isConstructed()) {
|
||||
if (notAfter != null) {
|
||||
throw new CertificateParsingException(
|
||||
"Duplicate notAfter in PrivateKeyUsage.");
|
||||
}
|
||||
opt.resetTag(DerValue.tag_GeneralizedTime);
|
||||
str = new DerInputStream(opt.toByteArray());
|
||||
notAfter = str.getGeneralizedTime();
|
||||
} else
|
||||
throw new IOException("Invalid encoding of " +
|
||||
"PrivateKeyUsageExtension");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return(super.toString() +
|
||||
"PrivateKeyUsage: [\n" +
|
||||
((notBefore == null) ? "" : "From: " + notBefore.toString() + ", ")
|
||||
+ ((notAfter == null) ? "" : "To: " + notAfter.toString())
|
||||
+ "]\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that that the current time is within the validity period.
|
||||
*
|
||||
* @exception CertificateExpiredException if the certificate has expired.
|
||||
* @exception CertificateNotYetValidException if the certificate is not
|
||||
* yet valid.
|
||||
*/
|
||||
public void valid()
|
||||
throws CertificateNotYetValidException, CertificateExpiredException {
|
||||
Date now = new Date();
|
||||
valid(now);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that that the passed time is within the validity period.
|
||||
*
|
||||
* @exception CertificateExpiredException if the certificate has expired
|
||||
* with respect to the <code>Date</code> supplied.
|
||||
* @exception CertificateNotYetValidException if the certificate is not
|
||||
* yet valid with respect to the <code>Date</code> supplied.
|
||||
*
|
||||
*/
|
||||
public void valid(Date now)
|
||||
throws CertificateNotYetValidException, CertificateExpiredException {
|
||||
Objects.requireNonNull(now);
|
||||
/*
|
||||
* we use the internal Dates rather than the passed in Date
|
||||
* because someone could override the Date methods after()
|
||||
* and before() to do something entirely different.
|
||||
*/
|
||||
if (notBefore != null && notBefore.after(now)) {
|
||||
throw new CertificateNotYetValidException("NotBefore: " +
|
||||
notBefore.toString());
|
||||
}
|
||||
if (notAfter != null && notAfter.before(now)) {
|
||||
throw new CertificateExpiredException("NotAfter: " +
|
||||
notAfter.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.PrivateKeyUsage_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
*/
|
||||
public void set(String name, Object obj)
|
||||
throws CertificateException, IOException {
|
||||
if (!(obj instanceof Date)) {
|
||||
throw new CertificateException("Attribute must be of type Date.");
|
||||
}
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
notBefore = (Date)obj;
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
notAfter = (Date)obj;
|
||||
} else {
|
||||
throw new CertificateException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:PrivateKeyUsage.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
*/
|
||||
public Date get(String name) throws CertificateException {
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
return (new Date(notBefore.getTime()));
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
return (new Date(notAfter.getTime()));
|
||||
} else {
|
||||
throw new CertificateException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:PrivateKeyUsage.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
* @exception CertificateException on attribute handling errors.
|
||||
*/
|
||||
public void delete(String name) throws CertificateException, IOException {
|
||||
if (name.equalsIgnoreCase(NOT_BEFORE)) {
|
||||
notBefore = null;
|
||||
} else if (name.equalsIgnoreCase(NOT_AFTER)) {
|
||||
notAfter = null;
|
||||
} else {
|
||||
throw new CertificateException("Attribute name not recognized by"
|
||||
+ " CertAttrSet:PrivateKeyUsage.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(NOT_BEFORE);
|
||||
elements.addElement(NOT_AFTER);
|
||||
|
||||
return(elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
}
|
||||
496
jdkSrc/jdk8/sun/security/x509/RDN.java
Normal file
496
jdkSrc/jdk8/sun/security/x509/RDN.java
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* RDNs are a set of {attribute = value} assertions. Some of those
|
||||
* attributes are "distinguished" (unique w/in context). Order is
|
||||
* never relevant.
|
||||
*
|
||||
* Some X.500 names include only a single distinguished attribute
|
||||
* per RDN. This style is currently common.
|
||||
*
|
||||
* Note that DER-encoded RDNs sort AVAs by assertion OID ... so that
|
||||
* when we parse this data we don't have to worry about canonicalizing
|
||||
* it, but we'll need to sort them when we expose the RDN class more.
|
||||
* <p>
|
||||
* The ASN.1 for RDNs is:
|
||||
* <pre>
|
||||
* RelativeDistinguishedName ::=
|
||||
* SET OF AttributeTypeAndValue
|
||||
*
|
||||
* AttributeTypeAndValue ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* value AttributeValue }
|
||||
*
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
*
|
||||
* AttributeValue ::= ANY DEFINED BY AttributeType
|
||||
* </pre>
|
||||
*
|
||||
* Note that instances of this class are immutable.
|
||||
*
|
||||
*/
|
||||
public class RDN {
|
||||
|
||||
// currently not private, accessed directly from X500Name
|
||||
final AVA[] assertion;
|
||||
|
||||
// cached immutable List of the AVAs
|
||||
private volatile List<AVA> avaList;
|
||||
|
||||
// cache canonical String form
|
||||
private volatile String canonicalString;
|
||||
|
||||
/**
|
||||
* Constructs an RDN from its printable representation.
|
||||
*
|
||||
* An RDN may consist of one or multiple Attribute Value Assertions (AVAs),
|
||||
* using '+' as a separator.
|
||||
* If the '+' should be considered part of an AVA value, it must be
|
||||
* preceded by '\'.
|
||||
*
|
||||
* @param name String form of RDN
|
||||
* @throws IOException on parsing error
|
||||
*/
|
||||
public RDN(String name) throws IOException {
|
||||
this(name, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an RDN from its printable representation.
|
||||
*
|
||||
* An RDN may consist of one or multiple Attribute Value Assertions (AVAs),
|
||||
* using '+' as a separator.
|
||||
* If the '+' should be considered part of an AVA value, it must be
|
||||
* preceded by '\'.
|
||||
*
|
||||
* @param name String form of RDN
|
||||
* @param keyword an additional mapping of keywords to OIDs
|
||||
* @throws IOException on parsing error
|
||||
*/
|
||||
public RDN(String name, Map<String, String> keywordMap) throws IOException {
|
||||
int quoteCount = 0;
|
||||
int searchOffset = 0;
|
||||
int avaOffset = 0;
|
||||
List<AVA> avaVec = new ArrayList<AVA>(3);
|
||||
int nextPlus = name.indexOf('+');
|
||||
while (nextPlus >= 0) {
|
||||
quoteCount += X500Name.countQuotes(name, searchOffset, nextPlus);
|
||||
/*
|
||||
* We have encountered an AVA delimiter (plus sign).
|
||||
* If the plus sign in the RDN under consideration is
|
||||
* preceded by a backslash (escape), or by a double quote, it
|
||||
* is part of the AVA. Otherwise, it is used as a separator, to
|
||||
* delimit the AVA under consideration from any subsequent AVAs.
|
||||
*/
|
||||
if (nextPlus > 0 && name.charAt(nextPlus - 1) != '\\'
|
||||
&& quoteCount != 1) {
|
||||
/*
|
||||
* Plus sign is a separator
|
||||
*/
|
||||
String avaString = name.substring(avaOffset, nextPlus);
|
||||
if (avaString.length() == 0) {
|
||||
throw new IOException("empty AVA in RDN \"" + name + "\"");
|
||||
}
|
||||
|
||||
// Parse AVA, and store it in vector
|
||||
AVA ava = new AVA(new StringReader(avaString), keywordMap);
|
||||
avaVec.add(ava);
|
||||
|
||||
// Increase the offset
|
||||
avaOffset = nextPlus + 1;
|
||||
|
||||
// Set quote counter back to zero
|
||||
quoteCount = 0;
|
||||
}
|
||||
searchOffset = nextPlus + 1;
|
||||
nextPlus = name.indexOf('+', searchOffset);
|
||||
}
|
||||
|
||||
// parse last or only AVA
|
||||
String avaString = name.substring(avaOffset);
|
||||
if (avaString.length() == 0) {
|
||||
throw new IOException("empty AVA in RDN \"" + name + "\"");
|
||||
}
|
||||
AVA ava = new AVA(new StringReader(avaString), keywordMap);
|
||||
avaVec.add(ava);
|
||||
|
||||
assertion = avaVec.toArray(new AVA[avaVec.size()]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs an RDN from its printable representation.
|
||||
*
|
||||
* An RDN may consist of one or multiple Attribute Value Assertions (AVAs),
|
||||
* using '+' as a separator.
|
||||
* If the '+' should be considered part of an AVA value, it must be
|
||||
* preceded by '\'.
|
||||
*
|
||||
* @param name String form of RDN
|
||||
* @throws IOException on parsing error
|
||||
*/
|
||||
RDN(String name, String format) throws IOException {
|
||||
this(name, format, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs an RDN from its printable representation.
|
||||
*
|
||||
* An RDN may consist of one or multiple Attribute Value Assertions (AVAs),
|
||||
* using '+' as a separator.
|
||||
* If the '+' should be considered part of an AVA value, it must be
|
||||
* preceded by '\'.
|
||||
*
|
||||
* @param name String form of RDN
|
||||
* @param keyword an additional mapping of keywords to OIDs
|
||||
* @throws IOException on parsing error
|
||||
*/
|
||||
RDN(String name, String format, Map<String, String> keywordMap)
|
||||
throws IOException {
|
||||
if (format.equalsIgnoreCase("RFC2253") == false) {
|
||||
throw new IOException("Unsupported format " + format);
|
||||
}
|
||||
int searchOffset = 0;
|
||||
int avaOffset = 0;
|
||||
List<AVA> avaVec = new ArrayList<AVA>(3);
|
||||
int nextPlus = name.indexOf('+');
|
||||
while (nextPlus >= 0) {
|
||||
/*
|
||||
* We have encountered an AVA delimiter (plus sign).
|
||||
* If the plus sign in the RDN under consideration is
|
||||
* preceded by a backslash (escape), or by a double quote, it
|
||||
* is part of the AVA. Otherwise, it is used as a separator, to
|
||||
* delimit the AVA under consideration from any subsequent AVAs.
|
||||
*/
|
||||
if (nextPlus > 0 && name.charAt(nextPlus - 1) != '\\' ) {
|
||||
/*
|
||||
* Plus sign is a separator
|
||||
*/
|
||||
String avaString = name.substring(avaOffset, nextPlus);
|
||||
if (avaString.length() == 0) {
|
||||
throw new IOException("empty AVA in RDN \"" + name + "\"");
|
||||
}
|
||||
|
||||
// Parse AVA, and store it in vector
|
||||
AVA ava = new AVA
|
||||
(new StringReader(avaString), AVA.RFC2253, keywordMap);
|
||||
avaVec.add(ava);
|
||||
|
||||
// Increase the offset
|
||||
avaOffset = nextPlus + 1;
|
||||
}
|
||||
searchOffset = nextPlus + 1;
|
||||
nextPlus = name.indexOf('+', searchOffset);
|
||||
}
|
||||
|
||||
// parse last or only AVA
|
||||
String avaString = name.substring(avaOffset);
|
||||
if (avaString.length() == 0) {
|
||||
throw new IOException("empty AVA in RDN \"" + name + "\"");
|
||||
}
|
||||
AVA ava = new AVA(new StringReader(avaString), AVA.RFC2253, keywordMap);
|
||||
avaVec.add(ava);
|
||||
|
||||
assertion = avaVec.toArray(new AVA[avaVec.size()]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs an RDN from an ASN.1 encoded value. The encoding
|
||||
* of the name in the stream uses DER (a BER/1 subset).
|
||||
*
|
||||
* @param value a DER-encoded value holding an RDN.
|
||||
* @throws IOException on parsing error.
|
||||
*/
|
||||
RDN(DerValue rdn) throws IOException {
|
||||
if (rdn.tag != DerValue.tag_Set) {
|
||||
throw new IOException("X500 RDN");
|
||||
}
|
||||
DerInputStream dis = new DerInputStream(rdn.toByteArray());
|
||||
DerValue[] avaset = dis.getSet(5);
|
||||
|
||||
assertion = new AVA[avaset.length];
|
||||
for (int i = 0; i < avaset.length; i++) {
|
||||
assertion[i] = new AVA(avaset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Creates an empty RDN with slots for specified
|
||||
* number of AVAs.
|
||||
*
|
||||
* @param i number of AVAs to be in RDN
|
||||
*/
|
||||
RDN(int i) { assertion = new AVA[i]; }
|
||||
|
||||
public RDN(AVA ava) {
|
||||
if (ava == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
assertion = new AVA[] { ava };
|
||||
}
|
||||
|
||||
public RDN(AVA[] avas) {
|
||||
assertion = avas.clone();
|
||||
for (int i = 0; i < assertion.length; i++) {
|
||||
if (assertion[i] == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an immutable List of the AVAs in this RDN.
|
||||
*/
|
||||
public List<AVA> avas() {
|
||||
List<AVA> list = avaList;
|
||||
if (list == null) {
|
||||
list = Collections.unmodifiableList(Arrays.asList(assertion));
|
||||
avaList = list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of AVAs in this RDN.
|
||||
*/
|
||||
public int size() {
|
||||
return assertion.length;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof RDN == false) {
|
||||
return false;
|
||||
}
|
||||
RDN other = (RDN)obj;
|
||||
if (this.assertion.length != other.assertion.length) {
|
||||
return false;
|
||||
}
|
||||
String thisCanon = this.toRFC2253String(true);
|
||||
String otherCanon = other.toRFC2253String(true);
|
||||
return thisCanon.equals(otherCanon);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculates a hash code value for the object. Objects
|
||||
* which are equal will also have the same hashcode.
|
||||
*
|
||||
* @returns int hashCode value
|
||||
*/
|
||||
public int hashCode() {
|
||||
return toRFC2253String(true).hashCode();
|
||||
}
|
||||
|
||||
/*
|
||||
* return specified attribute value from RDN
|
||||
*
|
||||
* @params oid ObjectIdentifier of attribute to be found
|
||||
* @returns DerValue of attribute value; null if attribute does not exist
|
||||
*/
|
||||
DerValue findAttribute(ObjectIdentifier oid) {
|
||||
for (int i = 0; i < assertion.length; i++) {
|
||||
if (assertion[i].oid.equals((Object)oid)) {
|
||||
return assertion[i].value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode the RDN in DER-encoded form.
|
||||
*
|
||||
* @param out DerOutputStream to which RDN is to be written
|
||||
* @throws IOException on error
|
||||
*/
|
||||
void encode(DerOutputStream out) throws IOException {
|
||||
out.putOrderedSetOf(DerValue.tag_Set, assertion);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN, using RFC 1779 style catenation
|
||||
* of attribute/value assertions, and emitting attribute type keywords
|
||||
* from RFCs 1779, 2253, and 5280.
|
||||
*/
|
||||
public String toString() {
|
||||
if (assertion.length == 1) {
|
||||
return assertion[0].toString();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < assertion.length; i++) {
|
||||
if (i != 0) {
|
||||
sb.append(" + ");
|
||||
}
|
||||
sb.append(assertion[i].toString());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN using the algorithm defined in
|
||||
* RFC 1779. Only RFC 1779 attribute type keywords are emitted.
|
||||
*/
|
||||
public String toRFC1779String() {
|
||||
return toRFC1779String(Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN using the algorithm defined in
|
||||
* RFC 1779. RFC 1779 attribute type keywords are emitted, as well
|
||||
* as keywords contained in the OID/keyword map.
|
||||
*/
|
||||
public String toRFC1779String(Map<String, String> oidMap) {
|
||||
if (assertion.length == 1) {
|
||||
return assertion[0].toRFC1779String(oidMap);
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < assertion.length; i++) {
|
||||
if (i != 0) {
|
||||
sb.append(" + ");
|
||||
}
|
||||
sb.append(assertion[i].toRFC1779String(oidMap));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN using the algorithm defined in
|
||||
* RFC 2253. Only RFC 2253 attribute type keywords are emitted.
|
||||
*/
|
||||
public String toRFC2253String() {
|
||||
return toRFC2253StringInternal
|
||||
(false, Collections.<String, String>emptyMap());
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN using the algorithm defined in
|
||||
* RFC 2253. RFC 2253 attribute type keywords are emitted, as well as
|
||||
* keywords contained in the OID/keyword map.
|
||||
*/
|
||||
public String toRFC2253String(Map<String, String> oidMap) {
|
||||
return toRFC2253StringInternal(false, oidMap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable form of this RDN using the algorithm defined in
|
||||
* RFC 2253. Only RFC 2253 attribute type keywords are emitted.
|
||||
* If canonical is true, then additional canonicalizations
|
||||
* documented in X500Principal.getName are performed.
|
||||
*/
|
||||
public String toRFC2253String(boolean canonical) {
|
||||
if (canonical == false) {
|
||||
return toRFC2253StringInternal
|
||||
(false, Collections.<String, String>emptyMap());
|
||||
}
|
||||
String c = canonicalString;
|
||||
if (c == null) {
|
||||
c = toRFC2253StringInternal
|
||||
(true, Collections.<String, String>emptyMap());
|
||||
canonicalString = c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private String toRFC2253StringInternal
|
||||
(boolean canonical, Map<String, String> oidMap) {
|
||||
/*
|
||||
* Section 2.2: When converting from an ASN.1 RelativeDistinguishedName
|
||||
* to a string, the output consists of the string encodings of each
|
||||
* AttributeTypeAndValue (according to 2.3), in any order.
|
||||
*
|
||||
* Where there is a multi-valued RDN, the outputs from adjoining
|
||||
* AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
|
||||
* character.
|
||||
*/
|
||||
|
||||
// normally, an RDN only contains one AVA
|
||||
if (assertion.length == 1) {
|
||||
return canonical ? assertion[0].toRFC2253CanonicalString() :
|
||||
assertion[0].toRFC2253String(oidMap);
|
||||
}
|
||||
|
||||
AVA[] toOutput = assertion;
|
||||
if (canonical) {
|
||||
// order the string type AVA's alphabetically,
|
||||
// followed by the oid type AVA's numerically
|
||||
toOutput = assertion.clone();
|
||||
Arrays.sort(toOutput, AVAComparator.getInstance());
|
||||
}
|
||||
StringJoiner sj = new StringJoiner("+");
|
||||
for (AVA ava : toOutput) {
|
||||
sj.add(canonical ? ava.toRFC2253CanonicalString()
|
||||
: ava.toRFC2253String(oidMap));
|
||||
}
|
||||
return sj.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AVAComparator implements Comparator<AVA> {
|
||||
|
||||
private static final Comparator<AVA> INSTANCE = new AVAComparator();
|
||||
|
||||
private AVAComparator() {
|
||||
// empty
|
||||
}
|
||||
|
||||
static Comparator<AVA> getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* AVA's containing a standard keyword are ordered alphabetically,
|
||||
* followed by AVA's containing an OID keyword, ordered numerically
|
||||
*/
|
||||
public int compare(AVA a1, AVA a2) {
|
||||
boolean a1Has2253 = a1.hasRFC2253Keyword();
|
||||
boolean a2Has2253 = a2.hasRFC2253Keyword();
|
||||
|
||||
if (a1Has2253 == a2Has2253) {
|
||||
return a1.toRFC2253CanonicalString().compareTo
|
||||
(a2.toRFC2253CanonicalString());
|
||||
} else {
|
||||
if (a1Has2253) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
256
jdkSrc/jdk8/sun/security/x509/RFC822Name.java
Normal file
256
jdkSrc/jdk8/sun/security/x509/RFC822Name.java
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the RFC822Name as required by the GeneralNames
|
||||
* ASN.1 object.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see GeneralName
|
||||
* @see GeneralNames
|
||||
* @see GeneralNameInterface
|
||||
*/
|
||||
public class RFC822Name implements GeneralNameInterface
|
||||
{
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Create the RFC822Name object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER RFC822Name.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public RFC822Name(DerValue derValue) throws IOException {
|
||||
name = derValue.getIA5String();
|
||||
parseName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the RFC822Name object with the specified name.
|
||||
*
|
||||
* @param name the RFC822Name.
|
||||
* @throws IOException on invalid input name
|
||||
*/
|
||||
public RFC822Name(String name) throws IOException {
|
||||
parseName(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an RFC822Name string to see if it is a valid
|
||||
* addr-spec according to IETF RFC822 and RFC2459:
|
||||
* [local-part@]domain
|
||||
* <p>
|
||||
* local-part@ could be empty for an RFC822Name NameConstraint,
|
||||
* but the domain at least must be non-empty. Case is not
|
||||
* significant.
|
||||
*
|
||||
* @param name the RFC822Name string
|
||||
* @throws IOException if name is not valid
|
||||
*/
|
||||
public void parseName(String name) throws IOException {
|
||||
if (name == null || name.length() == 0) {
|
||||
throw new IOException("RFC822Name may not be null or empty");
|
||||
}
|
||||
// See if domain is a valid domain name
|
||||
String domain = name.substring(name.indexOf('@')+1);
|
||||
if (domain.length() == 0) {
|
||||
throw new IOException("RFC822Name may not end with @");
|
||||
} else {
|
||||
//An RFC822 NameConstraint could start with a ., although
|
||||
//a DNSName may not
|
||||
if (domain.startsWith(".")) {
|
||||
if (domain.length() == 1)
|
||||
throw new IOException("RFC822Name domain may not be just .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return (GeneralNameInterface.NAME_RFC822);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the actual name value of the GeneralName.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the RFC822 name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the RFC822Name to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putIA5String(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the name into user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("RFC822Name: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are equivalent
|
||||
* according to RFC2459.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
|
||||
if (!(obj instanceof RFC822Name))
|
||||
return false;
|
||||
|
||||
RFC822Name other = (RFC822Name)obj;
|
||||
|
||||
// RFC2459 mandates that these names are
|
||||
// not case-sensitive
|
||||
return name.equalsIgnoreCase(other.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.toUpperCase(Locale.ENGLISH).hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return constraint type:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain)
|
||||
* <li>NAME_MATCH = 0: input name matches name
|
||||
* <li>NAME_NARROWS = 1: input name narrows name
|
||||
* <li>NAME_WIDENS = 2: input name widens name
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
* <p>
|
||||
* [RFC2459] When the subjectAltName extension contains an Internet mail address,
|
||||
* the address MUST be included as an rfc822Name. The format of an
|
||||
* rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822]. An
|
||||
* addr-spec has the form "local-part@domain". Note that an addr-spec
|
||||
* has no phrase (such as a common name) before it, has no comment (text
|
||||
* surrounded in parentheses) after it, and is not surrounded by "<" and
|
||||
* ">". Note that while upper and lower case letters are allowed in an
|
||||
* RFC 822 addr-spec, no significance is attached to the case.
|
||||
* <p>
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is not exact match, but narrowing and widening are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != (GeneralNameInterface.NAME_RFC822)) {
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
} else {
|
||||
//RFC2459 specifies that case is not significant in RFC822Names
|
||||
String inName =
|
||||
(((RFC822Name)inputName).getName()).toLowerCase(Locale.ENGLISH);
|
||||
String thisName = name.toLowerCase(Locale.ENGLISH);
|
||||
if (inName.equals(thisName)) {
|
||||
constraintType = NAME_MATCH;
|
||||
} else if (thisName.endsWith(inName)) {
|
||||
/* if both names contain @, then they had to match exactly */
|
||||
if (inName.indexOf('@') != -1) {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else if (inName.startsWith(".")) {
|
||||
constraintType = NAME_WIDENS;
|
||||
} else {
|
||||
int inNdx = thisName.lastIndexOf(inName);
|
||||
if (thisName.charAt(inNdx-1) == '@' ) {
|
||||
constraintType = NAME_WIDENS;
|
||||
} else {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
}
|
||||
} else if (inName.endsWith(thisName)) {
|
||||
/* if thisName contains @, then they had to match exactly */
|
||||
if (thisName.indexOf('@') != -1) {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else if (thisName.startsWith(".")) {
|
||||
constraintType = NAME_NARROWS;
|
||||
} else {
|
||||
int ndx = inName.lastIndexOf(thisName);
|
||||
if (inName.charAt(ndx-1) == '@') {
|
||||
constraintType = NAME_NARROWS;
|
||||
} else {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
String subtree=name;
|
||||
int i=1;
|
||||
|
||||
/* strip off name@ portion */
|
||||
int atNdx = subtree.lastIndexOf('@');
|
||||
if (atNdx >= 0) {
|
||||
i++;
|
||||
subtree=subtree.substring(atNdx+1);
|
||||
}
|
||||
|
||||
/* count dots in DNSName, adding one if DNSName preceded by @ */
|
||||
for (; subtree.lastIndexOf('.') >= 0; i++) {
|
||||
subtree=subtree.substring(0,subtree.lastIndexOf('.'));
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
258
jdkSrc/jdk8/sun/security/x509/ReasonFlags.java
Normal file
258
jdkSrc/jdk8/sun/security/x509/ReasonFlags.java
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the CRL Reason Flags.
|
||||
*
|
||||
* <p>This extension, if present, defines the identifies
|
||||
* the reason for the certificate revocation.
|
||||
* <p>The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* ReasonFlags ::= BIT STRING {
|
||||
* unused (0),
|
||||
* keyCompromise (1),
|
||||
* cACompromise (2),
|
||||
* affiliationChanged (3),
|
||||
* superseded (4),
|
||||
* cessationOfOperation (5),
|
||||
* certificateHold (6),
|
||||
* privilegeWithdrawn (7),
|
||||
* aACompromise (8) }
|
||||
* </pre>
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class ReasonFlags {
|
||||
|
||||
/**
|
||||
* Reasons
|
||||
*/
|
||||
public static final String UNUSED = "unused";
|
||||
public static final String KEY_COMPROMISE = "key_compromise";
|
||||
public static final String CA_COMPROMISE = "ca_compromise";
|
||||
public static final String AFFILIATION_CHANGED = "affiliation_changed";
|
||||
public static final String SUPERSEDED = "superseded";
|
||||
public static final String CESSATION_OF_OPERATION
|
||||
= "cessation_of_operation";
|
||||
public static final String CERTIFICATE_HOLD = "certificate_hold";
|
||||
public static final String PRIVILEGE_WITHDRAWN = "privilege_withdrawn";
|
||||
public static final String AA_COMPROMISE = "aa_compromise";
|
||||
|
||||
private final static String[] NAMES = {
|
||||
UNUSED,
|
||||
KEY_COMPROMISE,
|
||||
CA_COMPROMISE,
|
||||
AFFILIATION_CHANGED,
|
||||
SUPERSEDED,
|
||||
CESSATION_OF_OPERATION,
|
||||
CERTIFICATE_HOLD,
|
||||
PRIVILEGE_WITHDRAWN,
|
||||
AA_COMPROMISE,
|
||||
};
|
||||
|
||||
private static int name2Index(String name) throws IOException {
|
||||
for( int i=0; i<NAMES.length; i++ ) {
|
||||
if( NAMES[i].equalsIgnoreCase(name) ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
throw new IOException("Name not recognized by ReasonFlags");
|
||||
}
|
||||
|
||||
// Private data members
|
||||
private boolean[] bitString;
|
||||
|
||||
/**
|
||||
* Check if bit is set.
|
||||
*
|
||||
* @param position the position in the bit string to check.
|
||||
*/
|
||||
private boolean isSet(int position) {
|
||||
return (position < bitString.length) &&
|
||||
bitString[position];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bit at the specified position.
|
||||
*/
|
||||
private void set(int position, boolean val) {
|
||||
// enlarge bitString if necessary
|
||||
if (position >= bitString.length) {
|
||||
boolean[] tmp = new boolean[position+1];
|
||||
System.arraycopy(bitString, 0, tmp, 0, bitString.length);
|
||||
bitString = tmp;
|
||||
}
|
||||
bitString[position] = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ReasonFlags with the passed bit settings.
|
||||
*
|
||||
* @param reasons the bits to be set for the ReasonFlags.
|
||||
*/
|
||||
public ReasonFlags(byte[] reasons) {
|
||||
bitString = new BitArray(reasons.length*8, reasons).toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ReasonFlags with the passed bit settings.
|
||||
*
|
||||
* @param reasons the bits to be set for the ReasonFlags.
|
||||
*/
|
||||
public ReasonFlags(boolean[] reasons) {
|
||||
this.bitString = reasons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ReasonFlags with the passed bit settings.
|
||||
*
|
||||
* @param reasons the bits to be set for the ReasonFlags.
|
||||
*/
|
||||
public ReasonFlags(BitArray reasons) {
|
||||
this.bitString = reasons.toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from the passed DER encoded value.
|
||||
*
|
||||
* @param in the DerInputStream to read the ReasonFlags from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public ReasonFlags(DerInputStream in) throws IOException {
|
||||
DerValue derVal = in.getDerValue();
|
||||
this.bitString = derVal.getUnalignedBitString(true).toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object from the passed DER encoded value.
|
||||
*
|
||||
* @param derVal the DerValue decoded from the stream.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public ReasonFlags(DerValue derVal) throws IOException {
|
||||
this.bitString = derVal.getUnalignedBitString(true).toBooleanArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason flags as a boolean array.
|
||||
*/
|
||||
public boolean[] getFlags() {
|
||||
return bitString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (!(obj instanceof Boolean)) {
|
||||
throw new IOException("Attribute must be of type Boolean.");
|
||||
}
|
||||
boolean val = ((Boolean)obj).booleanValue();
|
||||
set(name2Index(name), val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public Object get(String name) throws IOException {
|
||||
return Boolean.valueOf(isSet(name2Index(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
set(name, Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the ReasonFlags.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("Reason Flags [\n");
|
||||
|
||||
if (isSet(0)) {
|
||||
sb.append(" Unused\n");
|
||||
}
|
||||
if (isSet(1)) {
|
||||
sb.append(" Key Compromise\n");
|
||||
}
|
||||
if (isSet(2)) {
|
||||
sb.append(" CA Compromise\n");
|
||||
}
|
||||
if (isSet(3)) {
|
||||
sb.append(" Affiliation_Changed\n");
|
||||
}
|
||||
if (isSet(4)) {
|
||||
sb.append(" Superseded\n");
|
||||
}
|
||||
if (isSet(5)) {
|
||||
sb.append(" Cessation Of Operation\n");
|
||||
}
|
||||
if (isSet(6)) {
|
||||
sb.append(" Certificate Hold\n");
|
||||
}
|
||||
if (isSet(7)) {
|
||||
sb.append(" Privilege Withdrawn\n");
|
||||
}
|
||||
if (isSet(8)) {
|
||||
sb.append(" AA Compromise\n");
|
||||
}
|
||||
sb.append("]\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putTruncatedUnalignedBitString(new BitArray(this.bitString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements () {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
for( int i=0; i<NAMES.length; i++ ) {
|
||||
elements.addElement(NAMES[i]);
|
||||
}
|
||||
return (elements.elements());
|
||||
}
|
||||
}
|
||||
123
jdkSrc/jdk8/sun/security/x509/SerialNumber.java
Normal file
123
jdkSrc/jdk8/sun/security/x509/SerialNumber.java
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the SerialNumber class used by certificates.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class SerialNumber {
|
||||
private BigInteger serialNum;
|
||||
|
||||
// Construct the class from the DerValue
|
||||
private void construct(DerValue derVal) throws IOException {
|
||||
serialNum = derVal.getBigInteger();
|
||||
if (derVal.data.available() != 0) {
|
||||
throw new IOException("Excess SerialNumber data");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class using BigInteger.
|
||||
*
|
||||
* @param num the BigInteger number used to create the serial number.
|
||||
*/
|
||||
public SerialNumber(BigInteger num) {
|
||||
serialNum = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class using int.
|
||||
*
|
||||
* @param num the BigInteger number used to create the serial number.
|
||||
*/
|
||||
public SerialNumber(int num) {
|
||||
serialNum = BigInteger.valueOf(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the SerialNumber from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public SerialNumber(DerInputStream in) throws IOException {
|
||||
DerValue derVal = in.getDerValue();
|
||||
construct(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DerValue.
|
||||
*
|
||||
* @param val the DerValue to read the SerialNumber from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public SerialNumber(DerValue val) throws IOException {
|
||||
construct(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed stream.
|
||||
*
|
||||
* @param in the InputStream to read the SerialNumber from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public SerialNumber(InputStream in) throws IOException {
|
||||
DerValue derVal = new DerValue(in);
|
||||
construct(derVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SerialNumber as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("SerialNumber: [" + Debug.toHexString(serialNum) + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the SerialNumber in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putInteger(serialNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the serial number.
|
||||
*/
|
||||
public BigInteger getNumber() {
|
||||
return serialNum;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This represents the Subject Alternative Name Extension.
|
||||
*
|
||||
* This extension, if present, allows the subject to specify multiple
|
||||
* alternative names.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
* <p>
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* SubjectAltName ::= GeneralNames
|
||||
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
* </pre>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class SubjectAlternativeNameExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.SubjectAlternativeName";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "SubjectAlternativeName";
|
||||
public static final String SUBJECT_NAME = "subject_name";
|
||||
|
||||
// private data members
|
||||
GeneralNames names = null;
|
||||
|
||||
// Encode this extension
|
||||
private void encodeThis() throws IOException {
|
||||
if (names == null || names.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
names.encode(os);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SubjectAlternativeNameExtension with the passed GeneralNames.
|
||||
* The extension is marked non-critical.
|
||||
*
|
||||
* @param names the GeneralNames for the subject.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public SubjectAlternativeNameExtension(GeneralNames names)
|
||||
throws IOException {
|
||||
this(Boolean.FALSE, names);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SubjectAlternativeNameExtension with the specified
|
||||
* criticality and GeneralNames.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param names the GeneralNames for the subject.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public SubjectAlternativeNameExtension(Boolean critical, GeneralNames names)
|
||||
throws IOException {
|
||||
this.names = names;
|
||||
this.extensionId = PKIXExtensions.SubjectAlternativeName_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default SubjectAlternativeNameExtension. The extension
|
||||
* is marked non-critical.
|
||||
*/
|
||||
public SubjectAlternativeNameExtension() {
|
||||
extensionId = PKIXExtensions.SubjectAlternativeName_Id;
|
||||
critical = false;
|
||||
names = new GeneralNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public SubjectAlternativeNameExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.SubjectAlternativeName_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
if (val.data == null) {
|
||||
names = new GeneralNames();
|
||||
return;
|
||||
}
|
||||
|
||||
names = new GeneralNames(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the SubjectAlternativeName.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
String result = super.toString() + "SubjectAlternativeName [\n";
|
||||
if(names == null) {
|
||||
result += " null\n";
|
||||
} else {
|
||||
for(GeneralName name: names.names()) {
|
||||
result += " "+name+"\n";
|
||||
}
|
||||
}
|
||||
result += "]\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.SubjectAlternativeName_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(SUBJECT_NAME)) {
|
||||
if (!(obj instanceof GeneralNames)) {
|
||||
throw new IOException("Attribute value should be of " +
|
||||
"type GeneralNames.");
|
||||
}
|
||||
names = (GeneralNames)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectAlternativeName.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public GeneralNames get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(SUBJECT_NAME)) {
|
||||
return (names);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectAlternativeName.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(SUBJECT_NAME)) {
|
||||
names = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectAlternativeName.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(SUBJECT_NAME);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
247
jdkSrc/jdk8/sun/security/x509/SubjectInfoAccessExtension.java
Normal file
247
jdkSrc/jdk8/sun/security/x509/SubjectInfoAccessExtension.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.DerOutputStream;
|
||||
import sun.security.util.DerValue;
|
||||
|
||||
/**
|
||||
* The Subject Information Access Extension (OID = 1.3.6.1.5.5.7.1.11).
|
||||
* <p>
|
||||
* The subject information access extension indicates how to access
|
||||
* information and services for the subject of the certificate in which
|
||||
* the extension appears. When the subject is a CA, information and
|
||||
* services may include certificate validation services and CA policy
|
||||
* data. When the subject is an end entity, the information describes
|
||||
* the type of services offered and how to access them. In this case,
|
||||
* the contents of this extension are defined in the protocol
|
||||
* specifications for the supported services. This extension may be
|
||||
* included in end entity or CA certificates. Conforming CAs MUST mark
|
||||
* this extension as non-critical.
|
||||
* <p>
|
||||
* This extension is defined in <a href="http://tools.ietf.org/html/rfc5280">
|
||||
* Internet X.509 PKI Certificate and Certificate Revocation List
|
||||
* (CRL) Profile</a>. The profile permits
|
||||
* the extension to be included in end-entity or CA certificates,
|
||||
* and it must be marked as non-critical. Its ASN.1 definition is as follows:
|
||||
* <pre>
|
||||
* id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
|
||||
*
|
||||
* SubjectInfoAccessSyntax ::=
|
||||
* SEQUENCE SIZE (1..MAX) OF AccessDescription
|
||||
*
|
||||
* AccessDescription ::= SEQUENCE {
|
||||
* accessMethod OBJECT IDENTIFIER,
|
||||
* accessLocation GeneralName }
|
||||
* </pre>
|
||||
* <p>
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
|
||||
public class SubjectInfoAccessExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.SubjectInfoAccess";
|
||||
|
||||
/**
|
||||
* Attribute name.
|
||||
*/
|
||||
public static final String NAME = "SubjectInfoAccess";
|
||||
public static final String DESCRIPTIONS = "descriptions";
|
||||
|
||||
/**
|
||||
* The List of AccessDescription objects.
|
||||
*/
|
||||
private List<AccessDescription> accessDescriptions;
|
||||
|
||||
/**
|
||||
* Create an SubjectInfoAccessExtension from a List of
|
||||
* AccessDescription; the criticality is set to false.
|
||||
*
|
||||
* @param accessDescriptions the List of AccessDescription
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public SubjectInfoAccessExtension(
|
||||
List<AccessDescription> accessDescriptions) throws IOException {
|
||||
this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
|
||||
this.critical = false;
|
||||
this.accessDescriptions = accessDescriptions;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value of the same.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value Array of DER encoded bytes of the actual value.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public SubjectInfoAccessExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
|
||||
if (!(value instanceof byte[])) {
|
||||
throw new IOException("Illegal argument type");
|
||||
}
|
||||
|
||||
extensionValue = (byte[])value;
|
||||
DerValue val = new DerValue(extensionValue);
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new IOException("Invalid encoding for " +
|
||||
"SubjectInfoAccessExtension.");
|
||||
}
|
||||
accessDescriptions = new ArrayList<AccessDescription>();
|
||||
while (val.data.available() != 0) {
|
||||
DerValue seq = val.data.getDerValue();
|
||||
AccessDescription accessDescription = new AccessDescription(seq);
|
||||
accessDescriptions.add(accessDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of AccessDescription objects.
|
||||
*/
|
||||
public List<AccessDescription> getAccessDescriptions() {
|
||||
return accessDescriptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the DerOutputStream.
|
||||
*
|
||||
* @param out the DerOutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (this.extensionValue == null) {
|
||||
this.extensionId = PKIXExtensions.SubjectInfoAccess_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Checked with instanceof
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
if (!(obj instanceof List)) {
|
||||
throw new IOException("Attribute value should be of type List.");
|
||||
}
|
||||
accessDescriptions = (List<AccessDescription>)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:SubjectInfoAccessExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public List<AccessDescription> get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
return accessDescriptions;
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:SubjectInfoAccessExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(DESCRIPTIONS)) {
|
||||
accessDescriptions =
|
||||
Collections.<AccessDescription>emptyList();
|
||||
} else {
|
||||
throw new IOException("Attribute name [" + name +
|
||||
"] not recognized by " +
|
||||
"CertAttrSet:SubjectInfoAccessExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(DESCRIPTIONS);
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (accessDescriptions.isEmpty()) {
|
||||
this.extensionValue = null;
|
||||
} else {
|
||||
DerOutputStream ads = new DerOutputStream();
|
||||
for (AccessDescription accessDescription : accessDescriptions) {
|
||||
accessDescription.encode(ads);
|
||||
}
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, ads);
|
||||
this.extensionValue = seq.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the extension as user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + "SubjectInfoAccess [\n "
|
||||
+ accessDescriptions + "\n]\n";
|
||||
}
|
||||
|
||||
}
|
||||
198
jdkSrc/jdk8/sun/security/x509/SubjectKeyIdentifierExtension.java
Normal file
198
jdkSrc/jdk8/sun/security/x509/SubjectKeyIdentifierExtension.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Represent the Subject Key Identifier Extension.
|
||||
*
|
||||
* This extension, if present, provides a means of identifying the particular
|
||||
* public key used in an application. This extension by default is marked
|
||||
* non-critical.
|
||||
*
|
||||
* <p>Extensions are addiitonal attributes which can be inserted in a X509
|
||||
* v3 certificate. For example a "Driving License Certificate" could have
|
||||
* the driving license number as a extension.
|
||||
*
|
||||
* <p>Extensions are represented as a sequence of the extension identifier
|
||||
* (Object Identifier), a boolean flag stating whether the extension is to
|
||||
* be treated as being critical and the extension value itself (this is again
|
||||
* a DER encoding of the extension value).
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see Extension
|
||||
* @see CertAttrSet
|
||||
*/
|
||||
public class SubjectKeyIdentifierExtension extends Extension
|
||||
implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT =
|
||||
"x509.info.extensions.SubjectKeyIdentifier";
|
||||
/**
|
||||
* Attribute names.
|
||||
*/
|
||||
public static final String NAME = "SubjectKeyIdentifier";
|
||||
public static final String KEY_ID = "key_id";
|
||||
|
||||
// Private data member
|
||||
private KeyIdentifier id = null;
|
||||
|
||||
// Encode this extension value
|
||||
private void encodeThis() throws IOException {
|
||||
if (id == null) {
|
||||
this.extensionValue = null;
|
||||
return;
|
||||
}
|
||||
DerOutputStream os = new DerOutputStream();
|
||||
id.encode(os);
|
||||
this.extensionValue = os.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a SubjectKeyIdentifierExtension with the passed octet string.
|
||||
* The criticality is set to False.
|
||||
* @param octetString the octet string identifying the key identifier.
|
||||
*/
|
||||
public SubjectKeyIdentifierExtension(byte[] octetString)
|
||||
throws IOException {
|
||||
id = new KeyIdentifier(octetString);
|
||||
|
||||
this.extensionId = PKIXExtensions.SubjectKey_Id;
|
||||
this.critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the extension from the passed DER encoded value.
|
||||
*
|
||||
* @param critical true if the extension is to be treated as critical.
|
||||
* @param value an array of DER encoded bytes of the actual value.
|
||||
* @exception ClassCastException if value is not an array of bytes
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public SubjectKeyIdentifierExtension(Boolean critical, Object value)
|
||||
throws IOException {
|
||||
this.extensionId = PKIXExtensions.SubjectKey_Id;
|
||||
this.critical = critical.booleanValue();
|
||||
this.extensionValue = (byte[]) value;
|
||||
DerValue val = new DerValue(this.extensionValue);
|
||||
this.id = new KeyIdentifier(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation.
|
||||
*/
|
||||
public String toString() {
|
||||
return super.toString() + "SubjectKeyIdentifier [\n"
|
||||
+ String.valueOf(id) + "]\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the extension to the OutputStream.
|
||||
*
|
||||
* @param out the OutputStream to write the extension to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(OutputStream out) throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
if (extensionValue == null) {
|
||||
extensionId = PKIXExtensions.SubjectKey_Id;
|
||||
critical = false;
|
||||
encodeThis();
|
||||
}
|
||||
super.encode(tmp);
|
||||
out.write(tmp.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the attribute value.
|
||||
*/
|
||||
public void set(String name, Object obj) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
if (!(obj instanceof KeyIdentifier)) {
|
||||
throw new IOException("Attribute value should be of" +
|
||||
" type KeyIdentifier.");
|
||||
}
|
||||
id = (KeyIdentifier)obj;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectKeyIdentifierExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribute value.
|
||||
*/
|
||||
public KeyIdentifier get(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
return (id);
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectKeyIdentifierExtension.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the attribute value.
|
||||
*/
|
||||
public void delete(String name) throws IOException {
|
||||
if (name.equalsIgnoreCase(KEY_ID)) {
|
||||
id = null;
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized by " +
|
||||
"CertAttrSet:SubjectKeyIdentifierExtension.");
|
||||
}
|
||||
encodeThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(KEY_ID);
|
||||
|
||||
return (elements.elements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return (NAME);
|
||||
}
|
||||
}
|
||||
392
jdkSrc/jdk8/sun/security/x509/URIName.java
Normal file
392
jdkSrc/jdk8/sun/security/x509/URIName.java
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class implements the URIName as required by the GeneralNames
|
||||
* ASN.1 object.
|
||||
* <p>
|
||||
* [RFC5280] When the subjectAltName extension contains a URI, the name MUST be
|
||||
* stored in the uniformResourceIdentifier (an IA5String). The name MUST
|
||||
* be a non-relative URL, and MUST follow the URL syntax and encoding
|
||||
* rules specified in [RFC 3986]. The name must include both a scheme
|
||||
* (e.g., "http" or "ftp") and a scheme-specific-part. The scheme-
|
||||
* specific-part must include a fully qualified domain name or IP
|
||||
* address as the host.
|
||||
* <p>
|
||||
* As specified in [RFC 3986], the scheme name is not case-sensitive
|
||||
* (e.g., "http" is equivalent to "HTTP"). The host part is also not
|
||||
* case-sensitive, but other components of the scheme-specific-part may
|
||||
* be case-sensitive. When comparing URIs, conforming implementations
|
||||
* MUST compare the scheme and host without regard to case, but assume
|
||||
* the remainder of the scheme-specific-part is case sensitive.
|
||||
* <p>
|
||||
* [RFC1738] In general, URLs are written as follows:
|
||||
* <pre>
|
||||
* <scheme>:<scheme-specific-part>
|
||||
* </pre>
|
||||
* A URL contains the name of the scheme being used (<scheme>) followed
|
||||
* by a colon and then a string (the <scheme-specific-part>) whose
|
||||
* interpretation depends on the scheme.
|
||||
* <p>
|
||||
* While the syntax for the rest of the URL may vary depending on the
|
||||
* particular scheme selected, URL schemes that involve the direct use
|
||||
* of an IP-based protocol to a specified host on the Internet use a
|
||||
* common syntax for the scheme-specific data:
|
||||
* <pre>
|
||||
* //<user>:<password>@<host>:<port>/<url-path>
|
||||
* </pre>
|
||||
* [RFC2732] specifies that an IPv6 address contained inside a URL
|
||||
* must be enclosed in square brackets (to allow distinguishing the
|
||||
* colons that separate IPv6 components from the colons that separate
|
||||
* scheme-specific data.
|
||||
* <p>
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @author Sean Mullan
|
||||
* @author Steve Hanna
|
||||
* @see GeneralName
|
||||
* @see GeneralNames
|
||||
* @see GeneralNameInterface
|
||||
*/
|
||||
public class URIName implements GeneralNameInterface {
|
||||
|
||||
// private attributes
|
||||
private URI uri;
|
||||
private String host;
|
||||
private DNSName hostDNS;
|
||||
private IPAddressName hostIP;
|
||||
|
||||
/**
|
||||
* Create the URIName object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER URIName.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public URIName(DerValue derValue) throws IOException {
|
||||
this(derValue.getIA5String());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the URIName object with the specified name.
|
||||
*
|
||||
* @param name the URIName.
|
||||
* @throws IOException if name is not a proper URIName
|
||||
*/
|
||||
public URIName(String name) throws IOException {
|
||||
try {
|
||||
uri = new URI(name);
|
||||
} catch (URISyntaxException use) {
|
||||
throw new IOException("invalid URI name:" + name, use);
|
||||
}
|
||||
if (uri.getScheme() == null) {
|
||||
throw new IOException("URI name must include scheme:" + name);
|
||||
}
|
||||
|
||||
host = uri.getHost();
|
||||
// RFC 5280 says that the host should be non-null, but we allow it to
|
||||
// be null because some widely deployed certificates contain CDP
|
||||
// extensions with URIs that have no hostname (see bugs 4802236 and
|
||||
// 5107944).
|
||||
if (host != null) {
|
||||
if (host.charAt(0) == '[') {
|
||||
// Verify host is a valid IPv6 address name
|
||||
String ipV6Host = host.substring(1, host.length()-1);
|
||||
try {
|
||||
hostIP = new IPAddressName(ipV6Host);
|
||||
} catch (IOException ioe) {
|
||||
throw new IOException("invalid URI name (host " +
|
||||
"portion is not a valid IPv6 address):" + name);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
hostDNS = new DNSName(host);
|
||||
} catch (IOException ioe) {
|
||||
// Not a valid DNSName; see if it is a valid IPv4
|
||||
// IPAddressName
|
||||
try {
|
||||
hostIP = new IPAddressName(host);
|
||||
} catch (Exception ioe2) {
|
||||
throw new IOException("invalid URI name (host " +
|
||||
"portion is not a valid DNSName, IPv4 address," +
|
||||
" or IPv6 address):" + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the URIName object with the specified name constraint. URI
|
||||
* name constraints syntax is different than SubjectAltNames, etc. See
|
||||
* 4.2.1.10 of RFC 5280.
|
||||
*
|
||||
* @param value the URI name constraint
|
||||
* @throws IOException if name is not a proper URI name constraint
|
||||
*/
|
||||
public static URIName nameConstraint(DerValue value) throws IOException {
|
||||
URI uri;
|
||||
String name = value.getIA5String();
|
||||
try {
|
||||
uri = new URI(name);
|
||||
} catch (URISyntaxException use) {
|
||||
throw new IOException("invalid URI name constraint:" + name, use);
|
||||
}
|
||||
if (uri.getScheme() == null) {
|
||||
String host = uri.getSchemeSpecificPart();
|
||||
try {
|
||||
DNSName hostDNS;
|
||||
if (host.startsWith(".")) {
|
||||
hostDNS = new DNSName(host.substring(1));
|
||||
} else {
|
||||
hostDNS = new DNSName(host);
|
||||
}
|
||||
return new URIName(uri, host, hostDNS);
|
||||
} catch (IOException ioe) {
|
||||
throw new IOException("invalid URI name constraint:" + name, ioe);
|
||||
}
|
||||
} else {
|
||||
throw new IOException("invalid URI name constraint (should not " +
|
||||
"include scheme):" + name);
|
||||
}
|
||||
}
|
||||
|
||||
URIName(URI uri, String host, DNSName hostDNS) {
|
||||
this.uri = uri;
|
||||
this.host = host;
|
||||
this.hostDNS = hostDNS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return GeneralNameInterface.NAME_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the URI name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the URIName to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
out.putIA5String(uri.toASCIIString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the name into user readable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return "URIName: " + uri.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this name with another, for equality.
|
||||
*
|
||||
* @return true iff the names are equivalent according to RFC2459.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof URIName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
URIName other = (URIName) obj;
|
||||
|
||||
return uri.equals(other.getURI());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URIName as a java.net.URI object
|
||||
*/
|
||||
public URI getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this URI name.
|
||||
*/
|
||||
public String getName() {
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scheme name portion of a URIName
|
||||
*
|
||||
* @returns scheme portion of full name
|
||||
*/
|
||||
public String getScheme() {
|
||||
return uri.getScheme();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host name or IP address portion of the URIName
|
||||
*
|
||||
* @returns host name or IP address portion of full name
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host object type; if host name is a
|
||||
* DNSName, then this host object does not include any
|
||||
* initial "." on the name.
|
||||
*
|
||||
* @returns host name as DNSName or IPAddressName
|
||||
*/
|
||||
public Object getHostObject() {
|
||||
if (hostIP != null) {
|
||||
return hostIP;
|
||||
} else {
|
||||
return hostDNS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this object.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return uri.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name
|
||||
* (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming
|
||||
* subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming
|
||||
* subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but
|
||||
* is same type.
|
||||
* </ul>.
|
||||
* These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
* <p>
|
||||
* RFC5280: For URIs, the constraint applies to the host part of the name.
|
||||
* The constraint may specify a host or a domain. Examples would be
|
||||
* "foo.bar.com"; and ".xyz.com". When the the constraint begins with
|
||||
* a period, it may be expanded with one or more subdomains. That is,
|
||||
* the constraint ".xyz.com" is satisfied by both abc.xyz.com and
|
||||
* abc.def.xyz.com. However, the constraint ".xyz.com" is not satisfied
|
||||
* by "xyz.com". When the constraint does not begin with a period, it
|
||||
* specifies a host.
|
||||
* <p>
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is not exact match, but
|
||||
* narrowing and widening are not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName)
|
||||
throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null) {
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
} else if (inputName.getType() != NAME_URI) {
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
} else {
|
||||
// Assuming from here on that one or both of these is
|
||||
// actually a URI name constraint (not a URI), so we
|
||||
// only need to compare the host portion of the name
|
||||
|
||||
String otherHost = ((URIName)inputName).getHost();
|
||||
|
||||
// Quick check for equality
|
||||
if (otherHost.equalsIgnoreCase(host)) {
|
||||
constraintType = NAME_MATCH;
|
||||
} else {
|
||||
Object otherHostObject = ((URIName)inputName).getHostObject();
|
||||
|
||||
if ((hostDNS == null) ||
|
||||
!(otherHostObject instanceof DNSName)) {
|
||||
// If one (or both) is an IP address, only same type
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
} else {
|
||||
// Both host portions are DNSNames. Are they domains?
|
||||
boolean thisDomain = (host.charAt(0) == '.');
|
||||
boolean otherDomain = (otherHost.charAt(0) == '.');
|
||||
DNSName otherDNS = (DNSName) otherHostObject;
|
||||
|
||||
// Run DNSName.constrains.
|
||||
constraintType = hostDNS.constrains(otherDNS);
|
||||
// If neither one is a domain, then they can't
|
||||
// widen or narrow. That's just SAME_TYPE.
|
||||
if ((!thisDomain && !otherDomain) &&
|
||||
((constraintType == NAME_WIDENS) ||
|
||||
(constraintType == NAME_NARROWS))) {
|
||||
constraintType = NAME_SAME_TYPE;
|
||||
}
|
||||
|
||||
// If one is a domain and the other isn't,
|
||||
// then they can't match. The one that's a
|
||||
// domain doesn't include the one that's
|
||||
// not a domain.
|
||||
if ((thisDomain != otherDomain) &&
|
||||
(constraintType == NAME_MATCH)) {
|
||||
if (thisDomain) {
|
||||
constraintType = NAME_WIDENS;
|
||||
} else {
|
||||
constraintType = NAME_NARROWS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
DNSName dnsName = null;
|
||||
try {
|
||||
dnsName = new DNSName(host);
|
||||
} catch (IOException ioe) {
|
||||
throw new UnsupportedOperationException(ioe.getMessage());
|
||||
}
|
||||
return dnsName.subtreeDepth();
|
||||
}
|
||||
}
|
||||
116
jdkSrc/jdk8/sun/security/x509/UniqueIdentity.java
Normal file
116
jdkSrc/jdk8/sun/security/x509/UniqueIdentity.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* This class defines the UniqueIdentity class used by certificates.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class UniqueIdentity {
|
||||
// Private data members
|
||||
private BitArray id;
|
||||
|
||||
/**
|
||||
* The default constructor for this class.
|
||||
*
|
||||
* @param id the byte array containing the unique identifier.
|
||||
*/
|
||||
public UniqueIdentity(BitArray id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default constructor for this class.
|
||||
*
|
||||
* @param id the byte array containing the unique identifier.
|
||||
*/
|
||||
public UniqueIdentity(byte[] id) {
|
||||
this.id = new BitArray(id.length*8, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param in the DerInputStream to read the UniqueIdentity from.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public UniqueIdentity(DerInputStream in) throws IOException {
|
||||
DerValue derVal = in.getDerValue();
|
||||
id = derVal.getUnalignedBitString(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the object, decoding the values from the passed DER stream.
|
||||
*
|
||||
* @param derVal the DerValue decoded from the stream.
|
||||
* @param tag the tag the value is encoded under.
|
||||
* @exception IOException on decoding errors.
|
||||
*/
|
||||
public UniqueIdentity(DerValue derVal) throws IOException {
|
||||
id = derVal.getUnalignedBitString(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the UniqueIdentity as a printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("UniqueIdentity:" + id.toString() + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the UniqueIdentity in DER form to the stream.
|
||||
*
|
||||
* @param out the DerOutputStream to marshal the contents to.
|
||||
* @param tag enocode it under the following tag.
|
||||
* @exception IOException on errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out, byte tag) throws IOException {
|
||||
byte[] bytes = id.toByteArray();
|
||||
int excessBits = bytes.length*8 - id.length();
|
||||
|
||||
out.write(tag);
|
||||
out.putLength(bytes.length + 1);
|
||||
|
||||
out.write(excessBits);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unique id.
|
||||
*/
|
||||
public boolean[] getId() {
|
||||
if (id == null) return null;
|
||||
|
||||
return id.toBooleanArray();
|
||||
}
|
||||
}
|
||||
423
jdkSrc/jdk8/sun/security/x509/X400Address.java
Normal file
423
jdkSrc/jdk8/sun/security/x509/X400Address.java
Normal file
@@ -0,0 +1,423 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import sun.security.util.DerValue;
|
||||
import sun.security.util.DerOutputStream;
|
||||
|
||||
/**
|
||||
* This class defines the X400Address of the GeneralName choice.
|
||||
* <p>
|
||||
* The ASN.1 syntax for this is:
|
||||
* <pre>
|
||||
* ORAddress ::= SEQUENCE {
|
||||
* built-in-standard-attributes BuiltInStandardAttributes,
|
||||
* built-in-domain-defined-attributes
|
||||
* BuiltInDomainDefinedAttributes OPTIONAL,
|
||||
* -- see also teletex-domain-defined-attributes
|
||||
* extension-attributes ExtensionAttributes OPTIONAL }
|
||||
* -- The OR-address is semantically absent from the OR-name if the
|
||||
* -- built-in-standard-attribute sequence is empty and the
|
||||
* -- built-in-domain-defined-attributes and extension-attributes are
|
||||
* -- both omitted.
|
||||
*
|
||||
* -- Built-in Standard Attributes
|
||||
*
|
||||
* BuiltInStandardAttributes ::= SEQUENCE {
|
||||
* country-name CountryName OPTIONAL,
|
||||
* administration-domain-name AdministrationDomainName OPTIONAL,
|
||||
* network-address [0] NetworkAddress OPTIONAL,
|
||||
* -- see also extended-network-address
|
||||
* terminal-identifier [1] TerminalIdentifier OPTIONAL,
|
||||
* private-domain-name [2] PrivateDomainName OPTIONAL,
|
||||
* organization-name [3] OrganizationName OPTIONAL,
|
||||
* -- see also teletex-organization-name
|
||||
* numeric-user-identifier [4] NumericUserIdentifier OPTIONAL,
|
||||
* personal-name [5] PersonalName OPTIONAL,
|
||||
* -- see also teletex-personal-name
|
||||
* organizational-unit-names [6] OrganizationalUnitNames OPTIONAL
|
||||
* -- see also teletex-organizational-unit-names -- }
|
||||
*
|
||||
* CountryName ::= [APPLICATION 1] CHOICE {
|
||||
* x121-dcc-code NumericString
|
||||
* (SIZE (ub-country-name-numeric-length)),
|
||||
* iso-3166-alpha2-code PrintableString
|
||||
* (SIZE (ub-country-name-alpha-length)) }
|
||||
*
|
||||
* AdministrationDomainName ::= [APPLICATION 2] CHOICE {
|
||||
* numeric NumericString (SIZE (0..ub-domain-name-length)),
|
||||
* printable PrintableString (SIZE (0..ub-domain-name-length)) }
|
||||
*
|
||||
* NetworkAddress ::= X121Address -- see also extended-network-address
|
||||
*
|
||||
* X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
|
||||
*
|
||||
* TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))
|
||||
*
|
||||
* PrivateDomainName ::= CHOICE {
|
||||
* numeric NumericString (SIZE (1..ub-domain-name-length)),
|
||||
* printable PrintableString (SIZE (1..ub-domain-name-length)) }
|
||||
*
|
||||
* OrganizationName ::= PrintableString
|
||||
* (SIZE (1..ub-organization-name-length))
|
||||
* -- see also teletex-organization-name
|
||||
*
|
||||
* NumericUserIdentifier ::= NumericString
|
||||
* (SIZE (1..ub-numeric-user-id-length))
|
||||
*
|
||||
* PersonalName ::= SET {
|
||||
* surname [0] PrintableString (SIZE (1..ub-surname-length)),
|
||||
* given-name [1] PrintableString
|
||||
* (SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||
* initials [2] PrintableString (SIZE (1..ub-initials-length)) OPTIONAL,
|
||||
* generation-qualifier [3] PrintableString
|
||||
* (SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
|
||||
* -- see also teletex-personal-name
|
||||
*
|
||||
* OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
|
||||
* OF OrganizationalUnitName
|
||||
* -- see also teletex-organizational-unit-names
|
||||
*
|
||||
* OrganizationalUnitName ::= PrintableString (SIZE
|
||||
* (1..ub-organizational-unit-name-length))
|
||||
*
|
||||
* -- Built-in Domain-defined Attributes
|
||||
*
|
||||
* BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||
* (1..ub-domain-defined-attributes) OF
|
||||
* BuiltInDomainDefinedAttribute
|
||||
*
|
||||
* BuiltInDomainDefinedAttribute ::= SEQUENCE {
|
||||
* type PrintableString (SIZE
|
||||
* (1..ub-domain-defined-attribute-type-length)),
|
||||
* value PrintableString (SIZE
|
||||
* (1..ub-domain-defined-attribute-value-length))}
|
||||
*
|
||||
* -- Extension Attributes
|
||||
*
|
||||
* ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
|
||||
* ExtensionAttribute
|
||||
*
|
||||
* ExtensionAttribute ::= SEQUENCE {
|
||||
* extension-attribute-type [0] INTEGER (0..ub-extension-attributes),
|
||||
* extension-attribute-value [1]
|
||||
* ANY DEFINED BY extension-attribute-type }
|
||||
*
|
||||
* -- Extension types and attribute values
|
||||
* --
|
||||
*
|
||||
* common-name INTEGER ::= 1
|
||||
*
|
||||
* CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
|
||||
*
|
||||
* teletex-common-name INTEGER ::= 2
|
||||
*
|
||||
* TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
|
||||
*
|
||||
* teletex-organization-name INTEGER ::= 3
|
||||
*
|
||||
* TeletexOrganizationName ::=
|
||||
* TeletexString (SIZE (1..ub-organization-name-length))
|
||||
*
|
||||
* teletex-personal-name INTEGER ::= 4
|
||||
*
|
||||
* TeletexPersonalName ::= SET {
|
||||
* surname [0] TeletexString (SIZE (1..ub-surname-length)),
|
||||
* given-name [1] TeletexString
|
||||
* (SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||
* initials [2] TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
|
||||
* generation-qualifier [3] TeletexString (SIZE
|
||||
* (1..ub-generation-qualifier-length)) OPTIONAL }
|
||||
*
|
||||
* teletex-organizational-unit-names INTEGER ::= 5
|
||||
*
|
||||
* TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
|
||||
* (1..ub-organizational-units) OF TeletexOrganizationalUnitName
|
||||
*
|
||||
* TeletexOrganizationalUnitName ::= TeletexString
|
||||
* (SIZE (1..ub-organizational-unit-name-length))
|
||||
*
|
||||
* pds-name INTEGER ::= 7
|
||||
*
|
||||
* PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
|
||||
*
|
||||
* physical-delivery-country-name INTEGER ::= 8
|
||||
*
|
||||
* PhysicalDeliveryCountryName ::= CHOICE {
|
||||
* x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
|
||||
* iso-3166-alpha2-code PrintableString
|
||||
* (SIZE (ub-country-name-alpha-length)) }
|
||||
*
|
||||
* postal-code INTEGER ::= 9
|
||||
*
|
||||
* PostalCode ::= CHOICE {
|
||||
* numeric-code NumericString (SIZE (1..ub-postal-code-length)),
|
||||
* printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
|
||||
*
|
||||
* physical-delivery-office-name INTEGER ::= 10
|
||||
*
|
||||
* PhysicalDeliveryOfficeName ::= PDSParameter
|
||||
*
|
||||
* physical-delivery-office-number INTEGER ::= 11
|
||||
*
|
||||
* PhysicalDeliveryOfficeNumber ::= PDSParameter
|
||||
*
|
||||
* extension-OR-address-components INTEGER ::= 12
|
||||
*
|
||||
* ExtensionORAddressComponents ::= PDSParameter
|
||||
*
|
||||
* physical-delivery-personal-name INTEGER ::= 13
|
||||
*
|
||||
* PhysicalDeliveryPersonalName ::= PDSParameter
|
||||
*
|
||||
* physical-delivery-organization-name INTEGER ::= 14
|
||||
*
|
||||
* PhysicalDeliveryOrganizationName ::= PDSParameter
|
||||
*
|
||||
* extension-physical-delivery-address-components INTEGER ::= 15
|
||||
*
|
||||
* ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
|
||||
*
|
||||
* unformatted-postal-address INTEGER ::= 16
|
||||
*
|
||||
* UnformattedPostalAddress ::= SET {
|
||||
* printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
|
||||
* PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
|
||||
* teletex-string TeletexString
|
||||
* (SIZE (1..ub-unformatted-address-length)) OPTIONAL }
|
||||
*
|
||||
* street-address INTEGER ::= 17
|
||||
*
|
||||
* StreetAddress ::= PDSParameter
|
||||
*
|
||||
* post-office-box-address INTEGER ::= 18
|
||||
*
|
||||
* PostOfficeBoxAddress ::= PDSParameter
|
||||
*
|
||||
* poste-restante-address INTEGER ::= 19
|
||||
*
|
||||
* PosteRestanteAddress ::= PDSParameter
|
||||
*
|
||||
* unique-postal-name INTEGER ::= 20
|
||||
*
|
||||
* UniquePostalName ::= PDSParameter
|
||||
*
|
||||
* local-postal-attributes INTEGER ::= 21
|
||||
*
|
||||
* LocalPostalAttributes ::= PDSParameter
|
||||
*
|
||||
* PDSParameter ::= SET {
|
||||
* printable-string PrintableString
|
||||
* (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
|
||||
* teletex-string TeletexString
|
||||
* (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
|
||||
*
|
||||
* extended-network-address INTEGER ::= 22
|
||||
*
|
||||
* ExtendedNetworkAddress ::= CHOICE {
|
||||
* e163-4-address SEQUENCE {
|
||||
* number [0] NumericString (SIZE (1..ub-e163-4-number-length)),
|
||||
* sub-address [1] NumericString
|
||||
* (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL },
|
||||
* psap-address [0] PresentationAddress }
|
||||
*
|
||||
* PresentationAddress ::= SEQUENCE {
|
||||
* pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
|
||||
* sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
|
||||
* tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
|
||||
* nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
|
||||
*
|
||||
* terminal-type INTEGER ::= 23
|
||||
*
|
||||
* TerminalType ::= INTEGER {
|
||||
* telex (3),
|
||||
* teletex (4),
|
||||
* g3-facsimile (5),
|
||||
* g4-facsimile (6),
|
||||
* ia5-terminal (7),
|
||||
* videotex (8) } (0..ub-integer-options)
|
||||
*
|
||||
* -- Extension Domain-defined Attributes
|
||||
*
|
||||
* teletex-domain-defined-attributes INTEGER ::= 6
|
||||
*
|
||||
* TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||
* (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
|
||||
*
|
||||
* TeletexDomainDefinedAttribute ::= SEQUENCE {
|
||||
* type TeletexString
|
||||
* (SIZE (1..ub-domain-defined-attribute-type-length)),
|
||||
* value TeletexString
|
||||
* (SIZE (1..ub-domain-defined-attribute-value-length)) }
|
||||
*
|
||||
* -- specifications of Upper Bounds shall be regarded as mandatory
|
||||
* -- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
|
||||
* -- Upper Bounds
|
||||
*
|
||||
* -- Upper Bounds
|
||||
* ub-name INTEGER ::= 32768
|
||||
* ub-common-name INTEGER ::= 64
|
||||
* ub-locality-name INTEGER ::= 128
|
||||
* ub-state-name INTEGER ::= 128
|
||||
* ub-organization-name INTEGER ::= 64
|
||||
* ub-organizational-unit-name INTEGER ::= 64
|
||||
* ub-title INTEGER ::= 64
|
||||
* ub-match INTEGER ::= 128
|
||||
*
|
||||
* ub-emailaddress-length INTEGER ::= 128
|
||||
*
|
||||
* ub-common-name-length INTEGER ::= 64
|
||||
* ub-country-name-alpha-length INTEGER ::= 2
|
||||
* ub-country-name-numeric-length INTEGER ::= 3
|
||||
* ub-domain-defined-attributes INTEGER ::= 4
|
||||
* ub-domain-defined-attribute-type-length INTEGER ::= 8
|
||||
* ub-domain-defined-attribute-value-length INTEGER ::= 128
|
||||
* ub-domain-name-length INTEGER ::= 16
|
||||
* ub-extension-attributes INTEGER ::= 256
|
||||
* ub-e163-4-number-length INTEGER ::= 15
|
||||
* ub-e163-4-sub-address-length INTEGER ::= 40
|
||||
* ub-generation-qualifier-length INTEGER ::= 3
|
||||
* ub-given-name-length INTEGER ::= 16
|
||||
* ub-initials-length INTEGER ::= 5
|
||||
* ub-integer-options INTEGER ::= 256
|
||||
* ub-numeric-user-id-length INTEGER ::= 32
|
||||
* ub-organization-name-length INTEGER ::= 64
|
||||
* ub-organizational-unit-name-length INTEGER ::= 32
|
||||
* ub-organizational-units INTEGER ::= 4
|
||||
* ub-pds-name-length INTEGER ::= 16
|
||||
* ub-pds-parameter-length INTEGER ::= 30
|
||||
* ub-pds-physical-address-lines INTEGER ::= 6
|
||||
* ub-postal-code-length INTEGER ::= 16
|
||||
* ub-surname-length INTEGER ::= 40
|
||||
* ub-terminal-id-length INTEGER ::= 24
|
||||
* ub-unformatted-address-length INTEGER ::= 180
|
||||
* ub-x121-address-length INTEGER ::= 16
|
||||
*
|
||||
* -- Note - upper bounds on string types, such as TeletexString, are
|
||||
* -- measured in characters. Excepting PrintableString or IA5String, a
|
||||
* -- significantly greater number of octets will be required to hold
|
||||
* -- such a value. As a minimum, 16 octets, or twice the specified upper
|
||||
* -- bound, whichever is the larger, should be allowed for TeletexString.
|
||||
* -- For UTF8String or UniversalString at least four times the upper
|
||||
* -- bound should be allowed.
|
||||
* </pre>
|
||||
*
|
||||
* @author Anne Anderson
|
||||
* @since 1.4
|
||||
* @see GeneralName
|
||||
* @see GeneralNames
|
||||
* @see GeneralNameInterface
|
||||
*/
|
||||
public class X400Address implements GeneralNameInterface {
|
||||
|
||||
// Private data members
|
||||
byte[] nameValue = null;
|
||||
|
||||
/**
|
||||
* Create the X400Address object from the specified byte array
|
||||
*
|
||||
* @param nameValue value of the name as a byte array
|
||||
*/
|
||||
public X400Address(byte[] value) {
|
||||
nameValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the X400Address object from the passed encoded Der value.
|
||||
*
|
||||
* @param derValue the encoded DER X400Address.
|
||||
* @exception IOException on error.
|
||||
*/
|
||||
public X400Address(DerValue derValue) throws IOException {
|
||||
nameValue = derValue.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the GeneralName.
|
||||
*/
|
||||
public int getType() {
|
||||
return (GeneralNameInterface.NAME_X400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the X400 name into the DerOutputStream.
|
||||
*
|
||||
* @param out the DER stream to encode the X400Address to.
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream out) throws IOException {
|
||||
DerValue derValue = new DerValue(nameValue);
|
||||
out.putDerValue(derValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the printable string.
|
||||
*/
|
||||
public String toString() {
|
||||
return ("X400Address: <DER-encoded value>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of constraint inputName places on this name:<ul>
|
||||
* <li>NAME_DIFF_TYPE = -1: input name is different type from name (i.e. does not constrain).
|
||||
* <li>NAME_MATCH = 0: input name matches name.
|
||||
* <li>NAME_NARROWS = 1: input name narrows name (is lower in the naming subtree)
|
||||
* <li>NAME_WIDENS = 2: input name widens name (is higher in the naming subtree)
|
||||
* <li>NAME_SAME_TYPE = 3: input name does not match or narrow name, but is same type.
|
||||
* </ul>. These results are used in checking NameConstraints during
|
||||
* certification path verification.
|
||||
*
|
||||
* @param inputName to be checked for being constrained
|
||||
* @returns constraint type above
|
||||
* @throws UnsupportedOperationException if name is same type, but comparison operations are
|
||||
* not supported for this name type.
|
||||
*/
|
||||
public int constrains(GeneralNameInterface inputName) throws UnsupportedOperationException {
|
||||
int constraintType;
|
||||
if (inputName == null)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else if (inputName.getType() != NAME_X400)
|
||||
constraintType = NAME_DIFF_TYPE;
|
||||
else
|
||||
//Narrowing, widening, and match constraints not defined in rfc2459 for X400Address
|
||||
throw new UnsupportedOperationException("Narrowing, widening, and match are not supported for X400Address.");
|
||||
return constraintType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return subtree depth of this name for purposes of determining
|
||||
* NameConstraints minimum and maximum bounds and for calculating
|
||||
* path lengths in name subtrees.
|
||||
*
|
||||
* @returns distance of name from root
|
||||
* @throws UnsupportedOperationException if not supported for this name type
|
||||
*/
|
||||
public int subtreeDepth() throws UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException("subtreeDepth not supported for X400Address");
|
||||
}
|
||||
|
||||
}
|
||||
1414
jdkSrc/jdk8/sun/security/x509/X500Name.java
Normal file
1414
jdkSrc/jdk8/sun/security/x509/X500Name.java
Normal file
File diff suppressed because it is too large
Load Diff
71
jdkSrc/jdk8/sun/security/x509/X509AttributeName.java
Normal file
71
jdkSrc/jdk8/sun/security/x509/X509AttributeName.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
/**
|
||||
* This class is used to parse attribute names like "x509.info.extensions".
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
public class X509AttributeName {
|
||||
// Public members
|
||||
private static final char SEPARATOR = '.';
|
||||
|
||||
// Private data members
|
||||
private String prefix = null;
|
||||
private String suffix = null;
|
||||
|
||||
/**
|
||||
* Default constructor for the class. Name is of the form
|
||||
* "x509.info.extensions".
|
||||
*
|
||||
* @param name the attribute name.
|
||||
*/
|
||||
public X509AttributeName(String name) {
|
||||
int i = name.indexOf(SEPARATOR);
|
||||
if (i < 0) {
|
||||
prefix = name;
|
||||
} else {
|
||||
prefix = name.substring(0, i);
|
||||
suffix = name.substring(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix of the name.
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return (prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the suffix of the name.
|
||||
*/
|
||||
public String getSuffix() {
|
||||
return (suffix);
|
||||
}
|
||||
}
|
||||
536
jdkSrc/jdk8/sun/security/x509/X509CRLEntryImpl.java
Normal file
536
jdkSrc/jdk8/sun/security/x509/X509CRLEntryImpl.java
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CRLException;
|
||||
import java.security.cert.CRLReason;
|
||||
import java.security.cert.X509CRLEntry;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.misc.HexDumpEncoder;
|
||||
|
||||
/**
|
||||
* <p>Abstract class for a revoked certificate in a CRL.
|
||||
* This class is for each entry in the <code>revokedCertificates</code>,
|
||||
* so it deals with the inner <em>SEQUENCE</em>.
|
||||
* The ASN.1 definition for this is:
|
||||
* <pre>
|
||||
* revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
* userCertificate CertificateSerialNumber,
|
||||
* revocationDate ChoiceOfTime,
|
||||
* crlEntryExtensions Extensions OPTIONAL
|
||||
* -- if present, must be v2
|
||||
* } OPTIONAL
|
||||
*
|
||||
* CertificateSerialNumber ::= INTEGER
|
||||
*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnId OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING
|
||||
* -- contains a DER encoding of a value
|
||||
* -- of the type registered for use with
|
||||
* -- the extnId object identifier value
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Hemma Prafullchandra
|
||||
*/
|
||||
|
||||
public class X509CRLEntryImpl extends X509CRLEntry
|
||||
implements Comparable<X509CRLEntryImpl> {
|
||||
|
||||
private SerialNumber serialNumber = null;
|
||||
private Date revocationDate = null;
|
||||
private CRLExtensions extensions = null;
|
||||
private byte[] revokedCert = null;
|
||||
private X500Principal certIssuer;
|
||||
|
||||
private final static boolean isExplicit = false;
|
||||
|
||||
/**
|
||||
* Constructs a revoked certificate entry using the given
|
||||
* serial number and revocation date.
|
||||
*
|
||||
* @param num the serial number of the revoked certificate.
|
||||
* @param date the Date on which revocation took place.
|
||||
*/
|
||||
public X509CRLEntryImpl(BigInteger num, Date date) {
|
||||
this.serialNumber = new SerialNumber(num);
|
||||
this.revocationDate = date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a revoked certificate entry using the given
|
||||
* serial number, revocation date and the entry
|
||||
* extensions.
|
||||
*
|
||||
* @param num the serial number of the revoked certificate.
|
||||
* @param date the Date on which revocation took place.
|
||||
* @param crlEntryExts the extensions for this entry.
|
||||
*/
|
||||
public X509CRLEntryImpl(BigInteger num, Date date,
|
||||
CRLExtensions crlEntryExts) {
|
||||
this.serialNumber = new SerialNumber(num);
|
||||
this.revocationDate = date;
|
||||
this.extensions = crlEntryExts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals a revoked certificate from its encoded form.
|
||||
*
|
||||
* @param revokedCert the encoded bytes.
|
||||
* @exception CRLException on parsing errors.
|
||||
*/
|
||||
public X509CRLEntryImpl(byte[] revokedCert) throws CRLException {
|
||||
try {
|
||||
parse(new DerValue(revokedCert));
|
||||
} catch (IOException e) {
|
||||
this.revokedCert = null;
|
||||
throw new CRLException("Parsing error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals a revoked certificate from its encoded form.
|
||||
*
|
||||
* @param derVal the DER value containing the revoked certificate.
|
||||
* @exception CRLException on parsing errors.
|
||||
*/
|
||||
public X509CRLEntryImpl(DerValue derValue) throws CRLException {
|
||||
try {
|
||||
parse(derValue);
|
||||
} catch (IOException e) {
|
||||
revokedCert = null;
|
||||
throw new CRLException("Parsing error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this revoked certificate entry has
|
||||
* extensions, otherwise false.
|
||||
*
|
||||
* @return true if this CRL entry has extensions, otherwise
|
||||
* false.
|
||||
*/
|
||||
public boolean hasExtensions() {
|
||||
return (extensions != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the revoked certificate to an output stream.
|
||||
*
|
||||
* @param outStrm an output stream to which the encoded revoked
|
||||
* certificate is written.
|
||||
* @exception CRLException on encoding errors.
|
||||
*/
|
||||
public void encode(DerOutputStream outStrm) throws CRLException {
|
||||
try {
|
||||
if (revokedCert == null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
// sequence { serialNumber, revocationDate, extensions }
|
||||
serialNumber.encode(tmp);
|
||||
|
||||
if (revocationDate.getTime() < CertificateValidity.YR_2050) {
|
||||
tmp.putUTCTime(revocationDate);
|
||||
} else {
|
||||
tmp.putGeneralizedTime(revocationDate);
|
||||
}
|
||||
|
||||
if (extensions != null)
|
||||
extensions.encode(tmp, isExplicit);
|
||||
|
||||
DerOutputStream seq = new DerOutputStream();
|
||||
seq.write(DerValue.tag_Sequence, tmp);
|
||||
|
||||
revokedCert = seq.toByteArray();
|
||||
}
|
||||
outStrm.write(revokedCert);
|
||||
} catch (IOException e) {
|
||||
throw new CRLException("Encoding error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ASN.1 DER-encoded form of this CRL Entry,
|
||||
* which corresponds to the inner SEQUENCE.
|
||||
*
|
||||
* @exception CRLException if an encoding error occurs.
|
||||
*/
|
||||
public byte[] getEncoded() throws CRLException {
|
||||
return getEncoded0().clone();
|
||||
}
|
||||
|
||||
// Called internally to avoid clone
|
||||
private byte[] getEncoded0() throws CRLException {
|
||||
if (revokedCert == null)
|
||||
this.encode(new DerOutputStream());
|
||||
return revokedCert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X500Principal getCertificateIssuer() {
|
||||
return certIssuer;
|
||||
}
|
||||
|
||||
void setCertificateIssuer(X500Principal crlIssuer, X500Principal certIssuer) {
|
||||
if (crlIssuer.equals(certIssuer)) {
|
||||
this.certIssuer = null;
|
||||
} else {
|
||||
this.certIssuer = certIssuer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serial number from this X509CRLEntry,
|
||||
* i.e. the <em>userCertificate</em>.
|
||||
*
|
||||
* @return the serial number.
|
||||
*/
|
||||
public BigInteger getSerialNumber() {
|
||||
return serialNumber.getNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the revocation date from this X509CRLEntry,
|
||||
* the <em>revocationDate</em>.
|
||||
*
|
||||
* @return the revocation date.
|
||||
*/
|
||||
public Date getRevocationDate() {
|
||||
return new Date(revocationDate.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is the overridden implementation of the getRevocationReason
|
||||
* method in X509CRLEntry. It is better performance-wise since it returns
|
||||
* cached values.
|
||||
*/
|
||||
@Override
|
||||
public CRLReason getRevocationReason() {
|
||||
Extension ext = getExtension(PKIXExtensions.ReasonCode_Id);
|
||||
if (ext == null) {
|
||||
return null;
|
||||
}
|
||||
CRLReasonCodeExtension rcExt = (CRLReasonCodeExtension) ext;
|
||||
return rcExt.getReasonCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* This static method is the default implementation of the
|
||||
* getRevocationReason method in X509CRLEntry.
|
||||
*/
|
||||
public static CRLReason getRevocationReason(X509CRLEntry crlEntry) {
|
||||
try {
|
||||
byte[] ext = crlEntry.getExtensionValue("2.5.29.21");
|
||||
if (ext == null) {
|
||||
return null;
|
||||
}
|
||||
DerValue val = new DerValue(ext);
|
||||
byte[] data = val.getOctetString();
|
||||
|
||||
CRLReasonCodeExtension rcExt =
|
||||
new CRLReasonCodeExtension(Boolean.FALSE, data);
|
||||
return rcExt.getReasonCode();
|
||||
} catch (IOException ioe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get Reason Code from CRL entry.
|
||||
*
|
||||
* @returns Integer or null, if no such extension
|
||||
* @throws IOException on error
|
||||
*/
|
||||
public Integer getReasonCode() throws IOException {
|
||||
Object obj = getExtension(PKIXExtensions.ReasonCode_Id);
|
||||
if (obj == null)
|
||||
return null;
|
||||
CRLReasonCodeExtension reasonCode = (CRLReasonCodeExtension)obj;
|
||||
return reasonCode.get(CRLReasonCodeExtension.REASON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable string of this revoked certificate.
|
||||
*
|
||||
* @return value of this revoked certificate in a printable form.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append(serialNumber.toString());
|
||||
sb.append(" On: " + revocationDate.toString());
|
||||
if (certIssuer != null) {
|
||||
sb.append("\n Certificate issuer: " + certIssuer);
|
||||
}
|
||||
if (extensions != null) {
|
||||
Collection<Extension> allEntryExts = extensions.getAllExtensions();
|
||||
Extension[] exts = allEntryExts.toArray(new Extension[0]);
|
||||
|
||||
sb.append("\n CRL Entry Extensions: " + exts.length);
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
sb.append("\n [" + (i+1) + "]: ");
|
||||
Extension ext = exts[i];
|
||||
try {
|
||||
if (OIDMap.getClass(ext.getExtensionId()) == null) {
|
||||
sb.append(ext.toString());
|
||||
byte[] extValue = ext.getExtensionValue();
|
||||
if (extValue != null) {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putOctetString(extValue);
|
||||
extValue = out.toByteArray();
|
||||
HexDumpEncoder enc = new HexDumpEncoder();
|
||||
sb.append("Extension unknown: "
|
||||
+ "DER encoded OCTET string =\n"
|
||||
+ enc.encodeBuffer(extValue) + "\n");
|
||||
}
|
||||
} else
|
||||
sb.append(ext.toString()); //sub-class exists
|
||||
} catch (Exception e) {
|
||||
sb.append(", Error parsing this extension");
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append("\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a critical extension is found that is
|
||||
* not supported, otherwise return false.
|
||||
*/
|
||||
public boolean hasUnsupportedCriticalExtension() {
|
||||
if (extensions == null)
|
||||
return false;
|
||||
return extensions.hasUnsupportedCriticalExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Set of the extension(s) marked CRITICAL in this
|
||||
* X509CRLEntry. In the returned set, each extension is
|
||||
* represented by its OID string.
|
||||
*
|
||||
* @return a set of the extension oid strings in the
|
||||
* Object that are marked critical.
|
||||
*/
|
||||
public Set<String> getCriticalExtensionOIDs() {
|
||||
if (extensions == null) {
|
||||
return null;
|
||||
}
|
||||
Set<String> extSet = new TreeSet<>();
|
||||
for (Extension ex : extensions.getAllExtensions()) {
|
||||
if (ex.isCritical()) {
|
||||
extSet.add(ex.getExtensionId().toString());
|
||||
}
|
||||
}
|
||||
return extSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a Set of the extension(s) marked NON-CRITICAL in this
|
||||
* X509CRLEntry. In the returned set, each extension is
|
||||
* represented by its OID string.
|
||||
*
|
||||
* @return a set of the extension oid strings in the
|
||||
* Object that are marked critical.
|
||||
*/
|
||||
public Set<String> getNonCriticalExtensionOIDs() {
|
||||
if (extensions == null) {
|
||||
return null;
|
||||
}
|
||||
Set<String> extSet = new TreeSet<>();
|
||||
for (Extension ex : extensions.getAllExtensions()) {
|
||||
if (!ex.isCritical()) {
|
||||
extSet.add(ex.getExtensionId().toString());
|
||||
}
|
||||
}
|
||||
return extSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the DER encoded OCTET string for the extension value
|
||||
* (<em>extnValue</em>) identified by the passed in oid String.
|
||||
* The <code>oid</code> string is
|
||||
* represented by a set of positive whole number separated
|
||||
* by ".", that means,<br>
|
||||
* <positive whole number>.<positive whole number>.<positive
|
||||
* whole number>.<...>
|
||||
*
|
||||
* @param oid the Object Identifier value for the extension.
|
||||
* @return the DER encoded octet string of the extension value.
|
||||
*/
|
||||
public byte[] getExtensionValue(String oid) {
|
||||
if (extensions == null)
|
||||
return null;
|
||||
try {
|
||||
String extAlias = OIDMap.getName(new ObjectIdentifier(oid));
|
||||
Extension crlExt = null;
|
||||
|
||||
if (extAlias == null) { // may be unknown
|
||||
ObjectIdentifier findOID = new ObjectIdentifier(oid);
|
||||
Extension ex = null;
|
||||
ObjectIdentifier inCertOID;
|
||||
for (Enumeration<Extension> e = extensions.getElements();
|
||||
e.hasMoreElements();) {
|
||||
ex = e.nextElement();
|
||||
inCertOID = ex.getExtensionId();
|
||||
if (inCertOID.equals((Object)findOID)) {
|
||||
crlExt = ex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
crlExt = extensions.get(extAlias);
|
||||
if (crlExt == null)
|
||||
return null;
|
||||
byte[] extData = crlExt.getExtensionValue();
|
||||
if (extData == null)
|
||||
return null;
|
||||
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putOctetString(extData);
|
||||
return out.toByteArray();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get an extension
|
||||
*
|
||||
* @param oid ObjectIdentifier of extension desired
|
||||
* @returns Extension of type <extension> or null, if not found
|
||||
*/
|
||||
public Extension getExtension(ObjectIdentifier oid) {
|
||||
if (extensions == null)
|
||||
return null;
|
||||
|
||||
// following returns null if no such OID in map
|
||||
//XXX consider cloning this
|
||||
return extensions.get(OIDMap.getName(oid));
|
||||
}
|
||||
|
||||
private void parse(DerValue derVal)
|
||||
throws CRLException, IOException {
|
||||
|
||||
if (derVal.tag != DerValue.tag_Sequence) {
|
||||
throw new CRLException("Invalid encoded RevokedCertificate, " +
|
||||
"starting sequence tag missing.");
|
||||
}
|
||||
if (derVal.data.available() == 0)
|
||||
throw new CRLException("No data encoded for RevokedCertificates");
|
||||
|
||||
revokedCert = derVal.toByteArray();
|
||||
// serial number
|
||||
DerInputStream in = derVal.toDerInputStream();
|
||||
DerValue val = in.getDerValue();
|
||||
this.serialNumber = new SerialNumber(val);
|
||||
|
||||
// revocationDate
|
||||
int nextByte = derVal.data.peekByte();
|
||||
if ((byte)nextByte == DerValue.tag_UtcTime) {
|
||||
this.revocationDate = derVal.data.getUTCTime();
|
||||
} else if ((byte)nextByte == DerValue.tag_GeneralizedTime) {
|
||||
this.revocationDate = derVal.data.getGeneralizedTime();
|
||||
} else
|
||||
throw new CRLException("Invalid encoding for revocation date");
|
||||
|
||||
if (derVal.data.available() == 0)
|
||||
return; // no extensions
|
||||
|
||||
// crlEntryExtensions
|
||||
this.extensions = new CRLExtensions(derVal.toDerInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to convert an arbitrary instance of X509CRLEntry
|
||||
* to a X509CRLEntryImpl. Does a cast if possible, otherwise reparses
|
||||
* the encoding.
|
||||
*/
|
||||
public static X509CRLEntryImpl toImpl(X509CRLEntry entry)
|
||||
throws CRLException {
|
||||
if (entry instanceof X509CRLEntryImpl) {
|
||||
return (X509CRLEntryImpl)entry;
|
||||
} else {
|
||||
return new X509CRLEntryImpl(entry.getEncoded());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CertificateIssuerExtension
|
||||
*
|
||||
* @return the CertificateIssuerExtension, or null if it does not exist
|
||||
*/
|
||||
CertificateIssuerExtension getCertificateIssuerExtension() {
|
||||
return (CertificateIssuerExtension)
|
||||
getExtension(PKIXExtensions.CertificateIssuer_Id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all extensions for this entry in a map
|
||||
* @return the extension map, can be empty, but not null
|
||||
*/
|
||||
public Map<String, java.security.cert.Extension> getExtensions() {
|
||||
if (extensions == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Collection<Extension> exts = extensions.getAllExtensions();
|
||||
Map<String, java.security.cert.Extension> map = new TreeMap<>();
|
||||
for (Extension ext : exts) {
|
||||
map.put(ext.getId(), ext);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(X509CRLEntryImpl that) {
|
||||
int compSerial = getSerialNumber().compareTo(that.getSerialNumber());
|
||||
if (compSerial != 0) {
|
||||
return compSerial;
|
||||
}
|
||||
try {
|
||||
byte[] thisEncoded = this.getEncoded0();
|
||||
byte[] thatEncoded = that.getEncoded0();
|
||||
for (int i=0; i<thisEncoded.length && i<thatEncoded.length; i++) {
|
||||
int a = thisEncoded[i] & 0xff;
|
||||
int b = thatEncoded[i] & 0xff;
|
||||
if (a != b) return a-b;
|
||||
}
|
||||
return thisEncoded.length -thatEncoded.length;
|
||||
} catch (CRLException ce) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
1356
jdkSrc/jdk8/sun/security/x509/X509CRLImpl.java
Normal file
1356
jdkSrc/jdk8/sun/security/x509/X509CRLImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
2031
jdkSrc/jdk8/sun/security/x509/X509CertImpl.java
Normal file
2031
jdkSrc/jdk8/sun/security/x509/X509CertImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
958
jdkSrc/jdk8/sun/security/x509/X509CertInfo.java
Normal file
958
jdkSrc/jdk8/sun/security/x509/X509CertInfo.java
Normal file
@@ -0,0 +1,958 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.security.cert.*;
|
||||
import java.util.*;
|
||||
|
||||
import sun.security.util.*;
|
||||
import sun.misc.HexDumpEncoder;
|
||||
|
||||
|
||||
/**
|
||||
* The X509CertInfo class represents X.509 certificate information.
|
||||
*
|
||||
* <P>X.509 certificates have several base data elements, including:<UL>
|
||||
*
|
||||
* <LI>The <em>Subject Name</em>, an X.500 Distinguished Name for
|
||||
* the entity (subject) for which the certificate was issued.
|
||||
*
|
||||
* <LI>The <em>Subject Public Key</em>, the public key of the subject.
|
||||
* This is one of the most important parts of the certificate.
|
||||
*
|
||||
* <LI>The <em>Validity Period</em>, a time period (e.g. six months)
|
||||
* within which the certificate is valid (unless revoked).
|
||||
*
|
||||
* <LI>The <em>Issuer Name</em>, an X.500 Distinguished Name for the
|
||||
* Certificate Authority (CA) which issued the certificate.
|
||||
*
|
||||
* <LI>A <em>Serial Number</em> assigned by the CA, for use in
|
||||
* certificate revocation and other applications.
|
||||
*
|
||||
* @author Amit Kapoor
|
||||
* @author Hemma Prafullchandra
|
||||
* @see CertAttrSet
|
||||
* @see X509CertImpl
|
||||
*/
|
||||
public class X509CertInfo implements CertAttrSet<String> {
|
||||
/**
|
||||
* Identifier for this attribute, to be used with the
|
||||
* get, set, delete methods of Certificate, x509 type.
|
||||
*/
|
||||
public static final String IDENT = "x509.info";
|
||||
// Certificate attribute names
|
||||
public static final String NAME = "info";
|
||||
public static final String DN_NAME = "dname";
|
||||
public static final String VERSION = CertificateVersion.NAME;
|
||||
public static final String SERIAL_NUMBER = CertificateSerialNumber.NAME;
|
||||
public static final String ALGORITHM_ID = CertificateAlgorithmId.NAME;
|
||||
public static final String ISSUER = "issuer";
|
||||
public static final String SUBJECT = "subject";
|
||||
public static final String VALIDITY = CertificateValidity.NAME;
|
||||
public static final String KEY = CertificateX509Key.NAME;
|
||||
public static final String ISSUER_ID = "issuerID";
|
||||
public static final String SUBJECT_ID = "subjectID";
|
||||
public static final String EXTENSIONS = CertificateExtensions.NAME;
|
||||
|
||||
// X509.v1 data
|
||||
protected CertificateVersion version = new CertificateVersion();
|
||||
protected CertificateSerialNumber serialNum = null;
|
||||
protected CertificateAlgorithmId algId = null;
|
||||
protected X500Name issuer = null;
|
||||
protected X500Name subject = null;
|
||||
protected CertificateValidity interval = null;
|
||||
protected CertificateX509Key pubKey = null;
|
||||
|
||||
// X509.v2 & v3 extensions
|
||||
protected UniqueIdentity issuerUniqueId = null;
|
||||
protected UniqueIdentity subjectUniqueId = null;
|
||||
|
||||
// X509.v3 extensions
|
||||
protected CertificateExtensions extensions = null;
|
||||
|
||||
// Attribute numbers for internal manipulation
|
||||
private static final int ATTR_VERSION = 1;
|
||||
private static final int ATTR_SERIAL = 2;
|
||||
private static final int ATTR_ALGORITHM = 3;
|
||||
private static final int ATTR_ISSUER = 4;
|
||||
private static final int ATTR_VALIDITY = 5;
|
||||
private static final int ATTR_SUBJECT = 6;
|
||||
private static final int ATTR_KEY = 7;
|
||||
private static final int ATTR_ISSUER_ID = 8;
|
||||
private static final int ATTR_SUBJECT_ID = 9;
|
||||
private static final int ATTR_EXTENSIONS = 10;
|
||||
|
||||
// DER encoded CertificateInfo data
|
||||
private byte[] rawCertInfo = null;
|
||||
|
||||
// The certificate attribute name to integer mapping stored here
|
||||
private static final Map<String,Integer> map = new HashMap<String,Integer>();
|
||||
static {
|
||||
map.put(VERSION, Integer.valueOf(ATTR_VERSION));
|
||||
map.put(SERIAL_NUMBER, Integer.valueOf(ATTR_SERIAL));
|
||||
map.put(ALGORITHM_ID, Integer.valueOf(ATTR_ALGORITHM));
|
||||
map.put(ISSUER, Integer.valueOf(ATTR_ISSUER));
|
||||
map.put(VALIDITY, Integer.valueOf(ATTR_VALIDITY));
|
||||
map.put(SUBJECT, Integer.valueOf(ATTR_SUBJECT));
|
||||
map.put(KEY, Integer.valueOf(ATTR_KEY));
|
||||
map.put(ISSUER_ID, Integer.valueOf(ATTR_ISSUER_ID));
|
||||
map.put(SUBJECT_ID, Integer.valueOf(ATTR_SUBJECT_ID));
|
||||
map.put(EXTENSIONS, Integer.valueOf(ATTR_EXTENSIONS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an uninitialized X509CertInfo on which <a href="#decode">
|
||||
* decode</a> must later be called (or which may be deserialized).
|
||||
*/
|
||||
public X509CertInfo() { }
|
||||
|
||||
/**
|
||||
* Unmarshals a certificate from its encoded form, parsing the
|
||||
* encoded bytes. This form of constructor is used by agents which
|
||||
* need to examine and use certificate contents. That is, this is
|
||||
* one of the more commonly used constructors. Note that the buffer
|
||||
* must include only a certificate, and no "garbage" may be left at
|
||||
* the end. If you need to ignore data at the end of a certificate,
|
||||
* use another constructor.
|
||||
*
|
||||
* @param cert the encoded bytes, with no trailing data.
|
||||
* @exception CertificateParsingException on parsing errors.
|
||||
*/
|
||||
public X509CertInfo(byte[] cert) throws CertificateParsingException {
|
||||
try {
|
||||
DerValue in = new DerValue(cert);
|
||||
|
||||
parse(in);
|
||||
} catch (IOException e) {
|
||||
throw new CertificateParsingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshal a certificate from its encoded form, parsing a DER value.
|
||||
* This form of constructor is used by agents which need to examine
|
||||
* and use certificate contents.
|
||||
*
|
||||
* @param derVal the der value containing the encoded cert.
|
||||
* @exception CertificateParsingException on parsing errors.
|
||||
*/
|
||||
public X509CertInfo(DerValue derVal) throws CertificateParsingException {
|
||||
try {
|
||||
parse(derVal);
|
||||
} catch (IOException e) {
|
||||
throw new CertificateParsingException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the certificate to an output stream.
|
||||
*
|
||||
* @param out an output stream to which the certificate is appended.
|
||||
* @exception CertificateException on encoding errors.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
public void encode(OutputStream out)
|
||||
throws CertificateException, IOException {
|
||||
if (rawCertInfo == null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
emit(tmp);
|
||||
rawCertInfo = tmp.toByteArray();
|
||||
}
|
||||
out.write(rawCertInfo.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an enumeration of names of attributes existing within this
|
||||
* attribute.
|
||||
*/
|
||||
public Enumeration<String> getElements() {
|
||||
AttributeNameEnumeration elements = new AttributeNameEnumeration();
|
||||
elements.addElement(VERSION);
|
||||
elements.addElement(SERIAL_NUMBER);
|
||||
elements.addElement(ALGORITHM_ID);
|
||||
elements.addElement(ISSUER);
|
||||
elements.addElement(VALIDITY);
|
||||
elements.addElement(SUBJECT);
|
||||
elements.addElement(KEY);
|
||||
elements.addElement(ISSUER_ID);
|
||||
elements.addElement(SUBJECT_ID);
|
||||
elements.addElement(EXTENSIONS);
|
||||
|
||||
return elements.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this attribute.
|
||||
*/
|
||||
public String getName() {
|
||||
return(NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoded certificate info.
|
||||
*
|
||||
* @exception CertificateEncodingException on encoding information errors.
|
||||
*/
|
||||
public byte[] getEncodedInfo() throws CertificateEncodingException {
|
||||
try {
|
||||
if (rawCertInfo == null) {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
emit(tmp);
|
||||
rawCertInfo = tmp.toByteArray();
|
||||
}
|
||||
return rawCertInfo.clone();
|
||||
} catch (IOException e) {
|
||||
throw new CertificateEncodingException(e.toString());
|
||||
} catch (CertificateException e) {
|
||||
throw new CertificateEncodingException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two X509CertInfo objects. This is false if the
|
||||
* certificates are not both X.509 certs, otherwise it
|
||||
* compares them as binary data.
|
||||
*
|
||||
* @param other the object being compared with this one
|
||||
* @return true iff the certificates are equivalent
|
||||
*/
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof X509CertInfo) {
|
||||
return equals((X509CertInfo) other);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two certificates, returning false if any data
|
||||
* differs between the two.
|
||||
*
|
||||
* @param other the object being compared with this one
|
||||
* @return true iff the certificates are equivalent
|
||||
*/
|
||||
public boolean equals(X509CertInfo other) {
|
||||
if (this == other) {
|
||||
return(true);
|
||||
} else if (rawCertInfo == null || other.rawCertInfo == null) {
|
||||
return(false);
|
||||
} else if (rawCertInfo.length != other.rawCertInfo.length) {
|
||||
return(false);
|
||||
}
|
||||
for (int i = 0; i < rawCertInfo.length; i++) {
|
||||
if (rawCertInfo[i] != other.rawCertInfo[i]) {
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a hash code value for the object. Objects
|
||||
* which are equal will also have the same hashcode.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int retval = 0;
|
||||
|
||||
for (int i = 1; i < rawCertInfo.length; i++) {
|
||||
retval += rawCertInfo[i] * i;
|
||||
}
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a printable representation of the certificate.
|
||||
*/
|
||||
public String toString() {
|
||||
|
||||
if (subject == null || pubKey == null || interval == null
|
||||
|| issuer == null || algId == null || serialNum == null) {
|
||||
throw new NullPointerException("X.509 cert is incomplete");
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("[\n");
|
||||
sb.append(" " + version.toString() + "\n");
|
||||
sb.append(" Subject: " + subject.toString() + "\n");
|
||||
sb.append(" Signature Algorithm: " + algId.toString() + "\n");
|
||||
sb.append(" Key: " + pubKey.toString() + "\n");
|
||||
sb.append(" " + interval.toString() + "\n");
|
||||
sb.append(" Issuer: " + issuer.toString() + "\n");
|
||||
sb.append(" " + serialNum.toString() + "\n");
|
||||
|
||||
// optional v2, v3 extras
|
||||
if (issuerUniqueId != null) {
|
||||
sb.append(" Issuer Id:\n" + issuerUniqueId.toString() + "\n");
|
||||
}
|
||||
if (subjectUniqueId != null) {
|
||||
sb.append(" Subject Id:\n" + subjectUniqueId.toString() + "\n");
|
||||
}
|
||||
if (extensions != null) {
|
||||
Collection<Extension> allExts = extensions.getAllExtensions();
|
||||
Extension[] exts = allExts.toArray(new Extension[0]);
|
||||
sb.append("\nCertificate Extensions: " + exts.length);
|
||||
for (int i = 0; i < exts.length; i++) {
|
||||
sb.append("\n[" + (i+1) + "]: ");
|
||||
Extension ext = exts[i];
|
||||
try {
|
||||
if (OIDMap.getClass(ext.getExtensionId()) == null) {
|
||||
sb.append(ext.toString());
|
||||
byte[] extValue = ext.getExtensionValue();
|
||||
if (extValue != null) {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
out.putOctetString(extValue);
|
||||
extValue = out.toByteArray();
|
||||
HexDumpEncoder enc = new HexDumpEncoder();
|
||||
sb.append("Extension unknown: "
|
||||
+ "DER encoded OCTET string =\n"
|
||||
+ enc.encodeBuffer(extValue) + "\n");
|
||||
}
|
||||
} else
|
||||
sb.append(ext.toString()); //sub-class exists
|
||||
} catch (Exception e) {
|
||||
sb.append(", Error parsing this extension");
|
||||
}
|
||||
}
|
||||
Map<String,Extension> invalid = extensions.getUnparseableExtensions();
|
||||
if (invalid.isEmpty() == false) {
|
||||
sb.append("\nUnparseable certificate extensions: " + invalid.size());
|
||||
int i = 1;
|
||||
for (Extension ext : invalid.values()) {
|
||||
sb.append("\n[" + (i++) + "]: ");
|
||||
sb.append(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append("\n]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the certificate attribute.
|
||||
*
|
||||
* @params name the name of the Certificate attribute.
|
||||
* @params val the value of the Certificate attribute.
|
||||
* @exception CertificateException on invalid attributes.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
public void set(String name, Object val)
|
||||
throws CertificateException, IOException {
|
||||
X509AttributeName attrName = new X509AttributeName(name);
|
||||
|
||||
int attr = attributeMap(attrName.getPrefix());
|
||||
if (attr == 0) {
|
||||
throw new CertificateException("Attribute name not recognized: "
|
||||
+ name);
|
||||
}
|
||||
// set rawCertInfo to null, so that we are forced to re-encode
|
||||
rawCertInfo = null;
|
||||
String suffix = attrName.getSuffix();
|
||||
|
||||
switch (attr) {
|
||||
case ATTR_VERSION:
|
||||
if (suffix == null) {
|
||||
setVersion(val);
|
||||
} else {
|
||||
version.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_SERIAL:
|
||||
if (suffix == null) {
|
||||
setSerialNumber(val);
|
||||
} else {
|
||||
serialNum.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_ALGORITHM:
|
||||
if (suffix == null) {
|
||||
setAlgorithmId(val);
|
||||
} else {
|
||||
algId.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_ISSUER:
|
||||
setIssuer(val);
|
||||
break;
|
||||
|
||||
case ATTR_VALIDITY:
|
||||
if (suffix == null) {
|
||||
setValidity(val);
|
||||
} else {
|
||||
interval.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_SUBJECT:
|
||||
setSubject(val);
|
||||
break;
|
||||
|
||||
case ATTR_KEY:
|
||||
if (suffix == null) {
|
||||
setKey(val);
|
||||
} else {
|
||||
pubKey.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_ISSUER_ID:
|
||||
setIssuerUniqueId(val);
|
||||
break;
|
||||
|
||||
case ATTR_SUBJECT_ID:
|
||||
setSubjectUniqueId(val);
|
||||
break;
|
||||
|
||||
case ATTR_EXTENSIONS:
|
||||
if (suffix == null) {
|
||||
setExtensions(val);
|
||||
} else {
|
||||
if (extensions == null)
|
||||
extensions = new CertificateExtensions();
|
||||
extensions.set(suffix, val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the certificate attribute.
|
||||
*
|
||||
* @params name the name of the Certificate attribute.
|
||||
* @exception CertificateException on invalid attributes.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
public void delete(String name)
|
||||
throws CertificateException, IOException {
|
||||
X509AttributeName attrName = new X509AttributeName(name);
|
||||
|
||||
int attr = attributeMap(attrName.getPrefix());
|
||||
if (attr == 0) {
|
||||
throw new CertificateException("Attribute name not recognized: "
|
||||
+ name);
|
||||
}
|
||||
// set rawCertInfo to null, so that we are forced to re-encode
|
||||
rawCertInfo = null;
|
||||
String suffix = attrName.getSuffix();
|
||||
|
||||
switch (attr) {
|
||||
case ATTR_VERSION:
|
||||
if (suffix == null) {
|
||||
version = null;
|
||||
} else {
|
||||
version.delete(suffix);
|
||||
}
|
||||
break;
|
||||
case (ATTR_SERIAL):
|
||||
if (suffix == null) {
|
||||
serialNum = null;
|
||||
} else {
|
||||
serialNum.delete(suffix);
|
||||
}
|
||||
break;
|
||||
case (ATTR_ALGORITHM):
|
||||
if (suffix == null) {
|
||||
algId = null;
|
||||
} else {
|
||||
algId.delete(suffix);
|
||||
}
|
||||
break;
|
||||
case (ATTR_ISSUER):
|
||||
issuer = null;
|
||||
break;
|
||||
case (ATTR_VALIDITY):
|
||||
if (suffix == null) {
|
||||
interval = null;
|
||||
} else {
|
||||
interval.delete(suffix);
|
||||
}
|
||||
break;
|
||||
case (ATTR_SUBJECT):
|
||||
subject = null;
|
||||
break;
|
||||
case (ATTR_KEY):
|
||||
if (suffix == null) {
|
||||
pubKey = null;
|
||||
} else {
|
||||
pubKey.delete(suffix);
|
||||
}
|
||||
break;
|
||||
case (ATTR_ISSUER_ID):
|
||||
issuerUniqueId = null;
|
||||
break;
|
||||
case (ATTR_SUBJECT_ID):
|
||||
subjectUniqueId = null;
|
||||
break;
|
||||
case (ATTR_EXTENSIONS):
|
||||
if (suffix == null) {
|
||||
extensions = null;
|
||||
} else {
|
||||
if (extensions != null)
|
||||
extensions.delete(suffix);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the certificate attribute.
|
||||
*
|
||||
* @params name the name of the Certificate attribute.
|
||||
*
|
||||
* @exception CertificateException on invalid attributes.
|
||||
* @exception IOException on other errors.
|
||||
*/
|
||||
public Object get(String name)
|
||||
throws CertificateException, IOException {
|
||||
X509AttributeName attrName = new X509AttributeName(name);
|
||||
|
||||
int attr = attributeMap(attrName.getPrefix());
|
||||
if (attr == 0) {
|
||||
throw new CertificateParsingException(
|
||||
"Attribute name not recognized: " + name);
|
||||
}
|
||||
String suffix = attrName.getSuffix();
|
||||
|
||||
switch (attr) { // frequently used attributes first
|
||||
case (ATTR_EXTENSIONS):
|
||||
if (suffix == null) {
|
||||
return(extensions);
|
||||
} else {
|
||||
if (extensions == null) {
|
||||
return null;
|
||||
} else {
|
||||
return(extensions.get(suffix));
|
||||
}
|
||||
}
|
||||
case (ATTR_SUBJECT):
|
||||
if (suffix == null) {
|
||||
return(subject);
|
||||
} else {
|
||||
return(getX500Name(suffix, false));
|
||||
}
|
||||
case (ATTR_ISSUER):
|
||||
if (suffix == null) {
|
||||
return(issuer);
|
||||
} else {
|
||||
return(getX500Name(suffix, true));
|
||||
}
|
||||
case (ATTR_KEY):
|
||||
if (suffix == null) {
|
||||
return(pubKey);
|
||||
} else {
|
||||
return(pubKey.get(suffix));
|
||||
}
|
||||
case (ATTR_ALGORITHM):
|
||||
if (suffix == null) {
|
||||
return(algId);
|
||||
} else {
|
||||
return(algId.get(suffix));
|
||||
}
|
||||
case (ATTR_VALIDITY):
|
||||
if (suffix == null) {
|
||||
return(interval);
|
||||
} else {
|
||||
return(interval.get(suffix));
|
||||
}
|
||||
case (ATTR_VERSION):
|
||||
if (suffix == null) {
|
||||
return(version);
|
||||
} else {
|
||||
return(version.get(suffix));
|
||||
}
|
||||
case (ATTR_SERIAL):
|
||||
if (suffix == null) {
|
||||
return(serialNum);
|
||||
} else {
|
||||
return(serialNum.get(suffix));
|
||||
}
|
||||
case (ATTR_ISSUER_ID):
|
||||
return(issuerUniqueId);
|
||||
case (ATTR_SUBJECT_ID):
|
||||
return(subjectUniqueId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Issuer or Subject name
|
||||
*/
|
||||
private Object getX500Name(String name, boolean getIssuer)
|
||||
throws IOException {
|
||||
if (name.equalsIgnoreCase(X509CertInfo.DN_NAME)) {
|
||||
return getIssuer ? issuer : subject;
|
||||
} else if (name.equalsIgnoreCase("x500principal")) {
|
||||
return getIssuer ? issuer.asX500Principal()
|
||||
: subject.asX500Principal();
|
||||
} else {
|
||||
throw new IOException("Attribute name not recognized.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine unmarshals the certificate information.
|
||||
*/
|
||||
private void parse(DerValue val)
|
||||
throws CertificateParsingException, IOException {
|
||||
DerInputStream in;
|
||||
DerValue tmp;
|
||||
|
||||
if (val.tag != DerValue.tag_Sequence) {
|
||||
throw new CertificateParsingException("signed fields invalid");
|
||||
}
|
||||
rawCertInfo = val.toByteArray();
|
||||
|
||||
in = val.data;
|
||||
|
||||
// Version
|
||||
tmp = in.getDerValue();
|
||||
if (tmp.isContextSpecific((byte)0)) {
|
||||
version = new CertificateVersion(tmp);
|
||||
tmp = in.getDerValue();
|
||||
}
|
||||
|
||||
// Serial number ... an integer
|
||||
serialNum = new CertificateSerialNumber(tmp);
|
||||
|
||||
// Algorithm Identifier
|
||||
algId = new CertificateAlgorithmId(in);
|
||||
|
||||
// Issuer name
|
||||
issuer = new X500Name(in);
|
||||
if (issuer.isEmpty()) {
|
||||
throw new CertificateParsingException(
|
||||
"Empty issuer DN not allowed in X509Certificates");
|
||||
}
|
||||
|
||||
// validity: SEQUENCE { start date, end date }
|
||||
interval = new CertificateValidity(in);
|
||||
|
||||
// subject name
|
||||
subject = new X500Name(in);
|
||||
if ((version.compare(CertificateVersion.V1) == 0) &&
|
||||
subject.isEmpty()) {
|
||||
throw new CertificateParsingException(
|
||||
"Empty subject DN not allowed in v1 certificate");
|
||||
}
|
||||
|
||||
// public key
|
||||
pubKey = new CertificateX509Key(in);
|
||||
|
||||
// If more data available, make sure version is not v1.
|
||||
if (in.available() != 0) {
|
||||
if (version.compare(CertificateVersion.V1) == 0) {
|
||||
throw new CertificateParsingException(
|
||||
"no more data allowed for version 1 certificate");
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the issuerUniqueId if present
|
||||
tmp = in.getDerValue();
|
||||
if (tmp.isContextSpecific((byte)1)) {
|
||||
issuerUniqueId = new UniqueIdentity(tmp);
|
||||
if (in.available() == 0)
|
||||
return;
|
||||
tmp = in.getDerValue();
|
||||
}
|
||||
|
||||
// Get the subjectUniqueId if present.
|
||||
if (tmp.isContextSpecific((byte)2)) {
|
||||
subjectUniqueId = new UniqueIdentity(tmp);
|
||||
if (in.available() == 0)
|
||||
return;
|
||||
tmp = in.getDerValue();
|
||||
}
|
||||
|
||||
// Get the extensions.
|
||||
if (version.compare(CertificateVersion.V3) != 0) {
|
||||
throw new CertificateParsingException(
|
||||
"Extensions not allowed in v2 certificate");
|
||||
}
|
||||
if (tmp.isConstructed() && tmp.isContextSpecific((byte)3)) {
|
||||
extensions = new CertificateExtensions(tmp.data);
|
||||
}
|
||||
|
||||
// verify X.509 V3 Certificate
|
||||
verifyCert(subject, extensions);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if X.509 V3 Certificate is compliant with RFC 5280.
|
||||
*/
|
||||
private void verifyCert(X500Name subject,
|
||||
CertificateExtensions extensions)
|
||||
throws CertificateParsingException, IOException {
|
||||
|
||||
// if SubjectName is empty, check for SubjectAlternativeNameExtension
|
||||
if (subject.isEmpty()) {
|
||||
if (extensions == null) {
|
||||
throw new CertificateParsingException("X.509 Certificate is " +
|
||||
"incomplete: subject field is empty, and certificate " +
|
||||
"has no extensions");
|
||||
}
|
||||
SubjectAlternativeNameExtension subjectAltNameExt = null;
|
||||
SubjectAlternativeNameExtension extValue = null;
|
||||
GeneralNames names = null;
|
||||
try {
|
||||
subjectAltNameExt = (SubjectAlternativeNameExtension)
|
||||
extensions.get(SubjectAlternativeNameExtension.NAME);
|
||||
names = subjectAltNameExt.get(
|
||||
SubjectAlternativeNameExtension.SUBJECT_NAME);
|
||||
} catch (IOException e) {
|
||||
throw new CertificateParsingException("X.509 Certificate is " +
|
||||
"incomplete: subject field is empty, and " +
|
||||
"SubjectAlternativeName extension is absent");
|
||||
}
|
||||
|
||||
// SubjectAlternativeName extension is empty or not marked critical
|
||||
if (names == null || names.isEmpty()) {
|
||||
throw new CertificateParsingException("X.509 Certificate is " +
|
||||
"incomplete: subject field is empty, and " +
|
||||
"SubjectAlternativeName extension is empty");
|
||||
} else if (subjectAltNameExt.isCritical() == false) {
|
||||
throw new CertificateParsingException("X.509 Certificate is " +
|
||||
"incomplete: SubjectAlternativeName extension MUST " +
|
||||
"be marked critical when subject field is empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Marshal the contents of a "raw" certificate into a DER sequence.
|
||||
*/
|
||||
private void emit(DerOutputStream out)
|
||||
throws CertificateException, IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
|
||||
// version number, iff not V1
|
||||
version.encode(tmp);
|
||||
|
||||
// Encode serial number, issuer signing algorithm, issuer name
|
||||
// and validity
|
||||
serialNum.encode(tmp);
|
||||
algId.encode(tmp);
|
||||
|
||||
if ((version.compare(CertificateVersion.V1) == 0) &&
|
||||
(issuer.toString() == null))
|
||||
throw new CertificateParsingException(
|
||||
"Null issuer DN not allowed in v1 certificate");
|
||||
|
||||
issuer.encode(tmp);
|
||||
interval.encode(tmp);
|
||||
|
||||
// Encode subject (principal) and associated key
|
||||
if ((version.compare(CertificateVersion.V1) == 0) &&
|
||||
(subject.toString() == null))
|
||||
throw new CertificateParsingException(
|
||||
"Null subject DN not allowed in v1 certificate");
|
||||
subject.encode(tmp);
|
||||
pubKey.encode(tmp);
|
||||
|
||||
// Encode issuerUniqueId & subjectUniqueId.
|
||||
if (issuerUniqueId != null) {
|
||||
issuerUniqueId.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false,(byte)1));
|
||||
}
|
||||
if (subjectUniqueId != null) {
|
||||
subjectUniqueId.encode(tmp, DerValue.createTag(DerValue.TAG_CONTEXT,
|
||||
false,(byte)2));
|
||||
}
|
||||
|
||||
// Write all the extensions.
|
||||
if (extensions != null) {
|
||||
extensions.encode(tmp);
|
||||
}
|
||||
|
||||
// Wrap the data; encoding of the "raw" cert is now complete.
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the integer attribute number for the passed attribute name.
|
||||
*/
|
||||
private int attributeMap(String name) {
|
||||
Integer num = map.get(name);
|
||||
if (num == null) {
|
||||
return 0;
|
||||
}
|
||||
return num.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the version number of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the Extensions
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setVersion(Object val) throws CertificateException {
|
||||
if (!(val instanceof CertificateVersion)) {
|
||||
throw new CertificateException("Version class type invalid.");
|
||||
}
|
||||
version = (CertificateVersion)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the serial number of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the CertificateSerialNumber
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setSerialNumber(Object val) throws CertificateException {
|
||||
if (!(val instanceof CertificateSerialNumber)) {
|
||||
throw new CertificateException("SerialNumber class type invalid.");
|
||||
}
|
||||
serialNum = (CertificateSerialNumber)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the algorithm id of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the AlgorithmId
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setAlgorithmId(Object val) throws CertificateException {
|
||||
if (!(val instanceof CertificateAlgorithmId)) {
|
||||
throw new CertificateException(
|
||||
"AlgorithmId class type invalid.");
|
||||
}
|
||||
algId = (CertificateAlgorithmId)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the issuer name of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the issuer
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setIssuer(Object val) throws CertificateException {
|
||||
if (!(val instanceof X500Name)) {
|
||||
throw new CertificateException(
|
||||
"Issuer class type invalid.");
|
||||
}
|
||||
issuer = (X500Name)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the validity interval of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the CertificateValidity
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setValidity(Object val) throws CertificateException {
|
||||
if (!(val instanceof CertificateValidity)) {
|
||||
throw new CertificateException(
|
||||
"CertificateValidity class type invalid.");
|
||||
}
|
||||
interval = (CertificateValidity)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subject name of the certificate.
|
||||
*
|
||||
* @params val the Object class value for the Subject
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setSubject(Object val) throws CertificateException {
|
||||
if (!(val instanceof X500Name)) {
|
||||
throw new CertificateException(
|
||||
"Subject class type invalid.");
|
||||
}
|
||||
subject = (X500Name)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the public key in the certificate.
|
||||
*
|
||||
* @params val the Object class value for the PublicKey
|
||||
* @exception CertificateException on invalid data.
|
||||
*/
|
||||
private void setKey(Object val) throws CertificateException {
|
||||
if (!(val instanceof CertificateX509Key)) {
|
||||
throw new CertificateException(
|
||||
"Key class type invalid.");
|
||||
}
|
||||
pubKey = (CertificateX509Key)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Issuer Unique Identity in the certificate.
|
||||
*
|
||||
* @params val the Object class value for the IssuerUniqueId
|
||||
* @exception CertificateException
|
||||
*/
|
||||
private void setIssuerUniqueId(Object val) throws CertificateException {
|
||||
if (version.compare(CertificateVersion.V2) < 0) {
|
||||
throw new CertificateException("Invalid version");
|
||||
}
|
||||
if (!(val instanceof UniqueIdentity)) {
|
||||
throw new CertificateException(
|
||||
"IssuerUniqueId class type invalid.");
|
||||
}
|
||||
issuerUniqueId = (UniqueIdentity)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Subject Unique Identity in the certificate.
|
||||
*
|
||||
* @params val the Object class value for the SubjectUniqueId
|
||||
* @exception CertificateException
|
||||
*/
|
||||
private void setSubjectUniqueId(Object val) throws CertificateException {
|
||||
if (version.compare(CertificateVersion.V2) < 0) {
|
||||
throw new CertificateException("Invalid version");
|
||||
}
|
||||
if (!(val instanceof UniqueIdentity)) {
|
||||
throw new CertificateException(
|
||||
"SubjectUniqueId class type invalid.");
|
||||
}
|
||||
subjectUniqueId = (UniqueIdentity)val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extensions in the certificate.
|
||||
*
|
||||
* @params val the Object class value for the Extensions
|
||||
* @exception CertificateException
|
||||
*/
|
||||
private void setExtensions(Object val) throws CertificateException {
|
||||
if (version.compare(CertificateVersion.V3) < 0) {
|
||||
throw new CertificateException("Invalid version");
|
||||
}
|
||||
if (!(val instanceof CertificateExtensions)) {
|
||||
throw new CertificateException(
|
||||
"Extensions class type invalid.");
|
||||
}
|
||||
extensions = (CertificateExtensions)val;
|
||||
}
|
||||
}
|
||||
476
jdkSrc/jdk8/sun/security/x509/X509Key.java
Normal file
476
jdkSrc/jdk8/sun/security/x509/X509Key.java
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package sun.security.x509;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.security.Key;
|
||||
import java.security.PublicKey;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.Security;
|
||||
import java.security.Provider;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
* Holds an X.509 key, for example a public key found in an X.509
|
||||
* certificate. Includes a description of the algorithm to be used
|
||||
* with the key; these keys normally are used as
|
||||
* "SubjectPublicKeyInfo".
|
||||
*
|
||||
* <P>While this class can represent any kind of X.509 key, it may be
|
||||
* desirable to provide subclasses which understand how to parse keying
|
||||
* data. For example, RSA public keys have two members, one for the
|
||||
* public modulus and one for the prime exponent. If such a class is
|
||||
* provided, it is used when parsing X.509 keys. If one is not provided,
|
||||
* the key still parses correctly.
|
||||
*
|
||||
* @author David Brownell
|
||||
*/
|
||||
public class X509Key implements PublicKey {
|
||||
|
||||
/** use serialVersionUID from JDK 1.1. for interoperability */
|
||||
private static final long serialVersionUID = -5359250853002055002L;
|
||||
|
||||
/* The algorithm information (name, parameters, etc). */
|
||||
protected AlgorithmId algid;
|
||||
|
||||
/**
|
||||
* The key bytes, without the algorithm information.
|
||||
* @deprecated Use the BitArray form which does not require keys to
|
||||
* be byte aligned.
|
||||
* @see sun.security.x509.X509Key#setKey(BitArray)
|
||||
* @see sun.security.x509.X509Key#getKey()
|
||||
*/
|
||||
@Deprecated
|
||||
protected byte[] key = null;
|
||||
|
||||
/*
|
||||
* The number of bits unused in the last byte of the key.
|
||||
* Added to keep the byte[] key form consistent with the BitArray
|
||||
* form. Can de deleted when byte[] key is deleted.
|
||||
*/
|
||||
@Deprecated
|
||||
private int unusedBits = 0;
|
||||
|
||||
/* BitArray form of key */
|
||||
private BitArray bitStringKey = null;
|
||||
|
||||
/* The encoding for the key. */
|
||||
protected byte[] encodedKey;
|
||||
|
||||
/**
|
||||
* Default constructor. The key constructed must have its key
|
||||
* and algorithm initialized before it may be used, for example
|
||||
* by using <code>decode</code>.
|
||||
*/
|
||||
public X509Key() { }
|
||||
|
||||
/*
|
||||
* Build and initialize as a "default" key. All X.509 key
|
||||
* data is stored and transmitted losslessly, but no knowledge
|
||||
* about this particular algorithm is available.
|
||||
*/
|
||||
private X509Key(AlgorithmId algid, BitArray key)
|
||||
throws InvalidKeyException {
|
||||
this.algid = algid;
|
||||
setKey(key);
|
||||
encode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key in the BitArray form.
|
||||
*/
|
||||
protected void setKey(BitArray key) {
|
||||
this.bitStringKey = (BitArray)key.clone();
|
||||
|
||||
/*
|
||||
* Do this to keep the byte array form consistent with
|
||||
* this. Can delete when byte[] key is deleted.
|
||||
*/
|
||||
this.key = key.toByteArray();
|
||||
int remaining = key.length() % 8;
|
||||
this.unusedBits =
|
||||
((remaining == 0) ? 0 : 8 - remaining);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key. The key may or may not be byte aligned.
|
||||
* @return a BitArray containing the key.
|
||||
*/
|
||||
protected BitArray getKey() {
|
||||
/*
|
||||
* Do this for consistency in case a subclass
|
||||
* modifies byte[] key directly. Remove when
|
||||
* byte[] key is deleted.
|
||||
* Note: the consistency checks fail when the subclass
|
||||
* modifies a non byte-aligned key (into a byte-aligned key)
|
||||
* using the deprecated byte[] key field.
|
||||
*/
|
||||
this.bitStringKey = new BitArray(
|
||||
this.key.length * 8 - this.unusedBits,
|
||||
this.key);
|
||||
|
||||
return (BitArray)bitStringKey.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct X.509 subject public key from a DER value. If
|
||||
* the runtime environment is configured with a specific class for
|
||||
* this kind of key, a subclass is returned. Otherwise, a generic
|
||||
* X509Key object is returned.
|
||||
*
|
||||
* <P>This mechanism gurantees that keys (and algorithms) may be
|
||||
* freely manipulated and transferred, without risk of losing
|
||||
* information. Also, when a key (or algorithm) needs some special
|
||||
* handling, that specific need can be accomodated.
|
||||
*
|
||||
* @param in the DER-encoded SubjectPublicKeyInfo value
|
||||
* @exception IOException on data format errors
|
||||
*/
|
||||
public static PublicKey parse(DerValue in) throws IOException
|
||||
{
|
||||
AlgorithmId algorithm;
|
||||
PublicKey subjectKey;
|
||||
|
||||
if (in.tag != DerValue.tag_Sequence)
|
||||
throw new IOException("corrupt subject key");
|
||||
|
||||
algorithm = AlgorithmId.parse(in.data.getDerValue());
|
||||
try {
|
||||
subjectKey = buildX509Key(algorithm,
|
||||
in.data.getUnalignedBitString());
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new IOException("subject key, " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (in.data.available() != 0)
|
||||
throw new IOException("excess subject key");
|
||||
return subjectKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the key bits. This may be redefined by subclasses to take
|
||||
* advantage of structure within the key. For example, RSA public
|
||||
* keys encapsulate two unsigned integers (modulus and exponent) as
|
||||
* DER values within the <code>key</code> bits; Diffie-Hellman and
|
||||
* DSS/DSA keys encapsulate a single unsigned integer.
|
||||
*
|
||||
* <P>This function is called when creating X.509 SubjectPublicKeyInfo
|
||||
* values using the X509Key member functions, such as <code>parse</code>
|
||||
* and <code>decode</code>.
|
||||
*
|
||||
* @exception IOException on parsing errors.
|
||||
* @exception InvalidKeyException on invalid key encodings.
|
||||
*/
|
||||
protected void parseKeyBits() throws IOException, InvalidKeyException {
|
||||
encode();
|
||||
}
|
||||
|
||||
/*
|
||||
* Factory interface, building the kind of key associated with this
|
||||
* specific algorithm ID or else returning this generic base class.
|
||||
* See the description above.
|
||||
*/
|
||||
static PublicKey buildX509Key(AlgorithmId algid, BitArray key)
|
||||
throws IOException, InvalidKeyException
|
||||
{
|
||||
/*
|
||||
* Use the algid and key parameters to produce the ASN.1 encoding
|
||||
* of the key, which will then be used as the input to the
|
||||
* key factory.
|
||||
*/
|
||||
DerOutputStream x509EncodedKeyStream = new DerOutputStream();
|
||||
encode(x509EncodedKeyStream, algid, key);
|
||||
X509EncodedKeySpec x509KeySpec
|
||||
= new X509EncodedKeySpec(x509EncodedKeyStream.toByteArray());
|
||||
|
||||
try {
|
||||
// Instantiate the key factory of the appropriate algorithm
|
||||
KeyFactory keyFac = KeyFactory.getInstance(algid.getName());
|
||||
|
||||
// Generate the public key
|
||||
return keyFac.generatePublic(x509KeySpec);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// Return generic X509Key with opaque key data (see below)
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new InvalidKeyException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try again using JDK1.1-style for backwards compatibility.
|
||||
*/
|
||||
String classname = "";
|
||||
try {
|
||||
Properties props;
|
||||
String keytype;
|
||||
Provider sunProvider;
|
||||
|
||||
sunProvider = Security.getProvider("SUN");
|
||||
if (sunProvider == null)
|
||||
throw new InstantiationException();
|
||||
classname = sunProvider.getProperty("PublicKey.X.509." +
|
||||
algid.getName());
|
||||
if (classname == null) {
|
||||
throw new InstantiationException();
|
||||
}
|
||||
|
||||
Class<?> keyClass = null;
|
||||
try {
|
||||
keyClass = Class.forName(classname);
|
||||
} catch (ClassNotFoundException e) {
|
||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||
if (cl != null) {
|
||||
keyClass = cl.loadClass(classname);
|
||||
}
|
||||
}
|
||||
|
||||
Object inst = null;
|
||||
X509Key result;
|
||||
|
||||
if (keyClass != null)
|
||||
inst = keyClass.newInstance();
|
||||
if (inst instanceof X509Key) {
|
||||
result = (X509Key) inst;
|
||||
result.algid = algid;
|
||||
result.setKey(key);
|
||||
result.parseKeyBits();
|
||||
return result;
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
} catch (InstantiationException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
// this should not happen.
|
||||
throw new IOException (classname + " [internal error]");
|
||||
}
|
||||
|
||||
X509Key result = new X509Key(algid, key);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm to be used with this key.
|
||||
*/
|
||||
public String getAlgorithm() {
|
||||
return algid.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the algorithm ID to be used with this key.
|
||||
*/
|
||||
public AlgorithmId getAlgorithmId() { return algid; }
|
||||
|
||||
/**
|
||||
* Encode SubjectPublicKeyInfo sequence on the DER output stream.
|
||||
*
|
||||
* @exception IOException on encoding errors.
|
||||
*/
|
||||
public final void encode(DerOutputStream out) throws IOException
|
||||
{
|
||||
encode(out, this.algid, getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DER-encoded form of the key as a byte array.
|
||||
*/
|
||||
public byte[] getEncoded() {
|
||||
try {
|
||||
return getEncodedInternal().clone();
|
||||
} catch (InvalidKeyException e) {
|
||||
// XXX
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] getEncodedInternal() throws InvalidKeyException {
|
||||
byte[] encoded = encodedKey;
|
||||
if (encoded == null) {
|
||||
try {
|
||||
DerOutputStream out = new DerOutputStream();
|
||||
encode(out);
|
||||
encoded = out.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new InvalidKeyException("IOException : " +
|
||||
e.getMessage());
|
||||
}
|
||||
encodedKey = encoded;
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the format for this key: "X.509"
|
||||
*/
|
||||
public String getFormat() {
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DER-encoded form of the key as a byte array.
|
||||
*
|
||||
* @exception InvalidKeyException on encoding errors.
|
||||
*/
|
||||
public byte[] encode() throws InvalidKeyException {
|
||||
return getEncodedInternal().clone();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a printable representation of the key
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
HexDumpEncoder encoder = new HexDumpEncoder();
|
||||
|
||||
return "algorithm = " + algid.toString()
|
||||
+ ", unparsed keybits = \n" + encoder.encodeBuffer(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an X509Key object from an input stream. The data on that
|
||||
* input stream must be encoded using DER, obeying the X.509
|
||||
* <code>SubjectPublicKeyInfo</code> format. That is, the data is a
|
||||
* sequence consisting of an algorithm ID and a bit string which holds
|
||||
* the key. (That bit string is often used to encapsulate another DER
|
||||
* encoded sequence.)
|
||||
*
|
||||
* <P>Subclasses should not normally redefine this method; they should
|
||||
* instead provide a <code>parseKeyBits</code> method to parse any
|
||||
* fields inside the <code>key</code> member.
|
||||
*
|
||||
* <P>The exception to this rule is that since private keys need not
|
||||
* be encoded using the X.509 <code>SubjectPublicKeyInfo</code> format,
|
||||
* private keys may override this method, <code>encode</code>, and
|
||||
* of course <code>getFormat</code>.
|
||||
*
|
||||
* @param in an input stream with a DER-encoded X.509
|
||||
* SubjectPublicKeyInfo value
|
||||
* @exception InvalidKeyException on parsing errors.
|
||||
*/
|
||||
public void decode(InputStream in)
|
||||
throws InvalidKeyException
|
||||
{
|
||||
DerValue val;
|
||||
|
||||
try {
|
||||
val = new DerValue(in);
|
||||
if (val.tag != DerValue.tag_Sequence)
|
||||
throw new InvalidKeyException("invalid key format");
|
||||
|
||||
algid = AlgorithmId.parse(val.data.getDerValue());
|
||||
setKey(val.data.getUnalignedBitString());
|
||||
parseKeyBits();
|
||||
if (val.data.available() != 0)
|
||||
throw new InvalidKeyException ("excess key data");
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new InvalidKeyException("IOException: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void decode(byte[] encodedKey) throws InvalidKeyException {
|
||||
decode(new ByteArrayInputStream(encodedKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization write ... X.509 keys serialize as
|
||||
* themselves, and they're parsed when they get read back.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException {
|
||||
stream.write(getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialization read ... X.509 keys serialize as
|
||||
* themselves, and they're parsed when they get read back.
|
||||
*/
|
||||
private void readObject(ObjectInputStream stream) throws IOException {
|
||||
try {
|
||||
decode(stream);
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
throw new IOException("deserialized key is invalid: " +
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof Key == false) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
byte[] thisEncoded = this.getEncodedInternal();
|
||||
byte[] otherEncoded;
|
||||
if (obj instanceof X509Key) {
|
||||
otherEncoded = ((X509Key)obj).getEncodedInternal();
|
||||
} else {
|
||||
otherEncoded = ((Key)obj).getEncoded();
|
||||
}
|
||||
return Arrays.equals(thisEncoded, otherEncoded);
|
||||
} catch (InvalidKeyException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a hash code value for the object. Objects
|
||||
* which are equal will also have the same hashcode.
|
||||
*/
|
||||
public int hashCode() {
|
||||
try {
|
||||
byte[] b1 = getEncodedInternal();
|
||||
int r = b1.length;
|
||||
for (int i = 0; i < b1.length; i++) {
|
||||
r += (b1[i] & 0xff) * 37;
|
||||
}
|
||||
return r;
|
||||
} catch (InvalidKeyException e) {
|
||||
// should not happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Produce SubjectPublicKey encoding from algorithm id and key material.
|
||||
*/
|
||||
static void encode(DerOutputStream out, AlgorithmId algid, BitArray key)
|
||||
throws IOException {
|
||||
DerOutputStream tmp = new DerOutputStream();
|
||||
algid.encode(tmp);
|
||||
tmp.putUnalignedBitString(key);
|
||||
out.write(DerValue.tag_Sequence, tmp);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user