Path: blob/master/src/java.base/share/classes/sun/security/x509/CertificatePoliciesExtension.java
41159 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.x509;2627import java.io.IOException;28import java.io.OutputStream;29import java.util.*;3031import sun.security.util.DerValue;32import sun.security.util.DerOutputStream;3334/**35* This class defines the certificate policies extension which specifies the36* policies under which the certificate has been issued37* and the purposes for which the certificate may be used.38* <p>39* Applications with specific policy requirements are expected to have a40* list of those policies which they will accept and to compare the41* policy OIDs in the certificate to that list. If this extension is42* critical, the path validation software MUST be able to interpret this43* extension (including the optional qualifier), or MUST reject the44* certificate.45* <p>46* Optional qualifiers are not supported in this implementation, as they are47* not recommended by RFC 5280.48*49* The ASN.1 syntax for this is (IMPLICIT tagging is defined in the50* module definition):51* <pre>52* id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }53*54* certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation55*56* PolicyInformation ::= SEQUENCE {57* policyIdentifier CertPolicyId,58* policyQualifiers SEQUENCE SIZE (1..MAX) OF59* PolicyQualifierInfo OPTIONAL }60*61* CertPolicyId ::= OBJECT IDENTIFIER62* </pre>63* @author Anne Anderson64* @since 1.465* @see Extension66* @see CertAttrSet67*/68public class CertificatePoliciesExtension extends Extension69implements CertAttrSet<String> {70/**71* Identifier for this attribute, to be used with the72* get, set, delete methods of Certificate, x509 type.73*/74public static final String IDENT = "x509.info.extensions.CertificatePolicies";75/**76* Attribute names.77*/78public static final String NAME = "CertificatePolicies";79public static final String POLICIES = "policies";8081/**82* List of PolicyInformation for this object.83*/84private List<PolicyInformation> certPolicies;8586// Encode this extension value.87private void encodeThis() throws IOException {88if (certPolicies == null || certPolicies.isEmpty()) {89this.extensionValue = null;90} else {91DerOutputStream os = new DerOutputStream();92DerOutputStream tmp = new DerOutputStream();9394for (PolicyInformation info : certPolicies) {95info.encode(tmp);96}9798os.write(DerValue.tag_Sequence, tmp);99this.extensionValue = os.toByteArray();100}101}102103/**104* Create a CertificatePoliciesExtension object from105* a List of PolicyInformation; the criticality is set to false.106*107* @param certPolicies the List of PolicyInformation.108*/109public CertificatePoliciesExtension(List<PolicyInformation> certPolicies)110throws IOException {111this(Boolean.FALSE, certPolicies);112}113114/**115* Create a CertificatePoliciesExtension object from116* a List of PolicyInformation with specified criticality.117*118* @param critical true if the extension is to be treated as critical.119* @param certPolicies the List of PolicyInformation.120*/121public CertificatePoliciesExtension(Boolean critical,122List<PolicyInformation> certPolicies) throws IOException {123this.certPolicies = certPolicies;124this.extensionId = PKIXExtensions.CertificatePolicies_Id;125this.critical = critical.booleanValue();126encodeThis();127}128129/**130* Create the extension from its DER encoded value and criticality.131*132* @param critical true if the extension is to be treated as critical.133* @param value an array of DER encoded bytes of the actual value.134* @exception ClassCastException if value is not an array of bytes135* @exception IOException on error.136*/137public CertificatePoliciesExtension(Boolean critical, Object value)138throws IOException {139this.extensionId = PKIXExtensions.CertificatePolicies_Id;140this.critical = critical.booleanValue();141this.extensionValue = (byte[]) value;142DerValue val = new DerValue(this.extensionValue);143if (val.tag != DerValue.tag_Sequence) {144throw new IOException("Invalid encoding for " +145"CertificatePoliciesExtension.");146}147certPolicies = new ArrayList<PolicyInformation>();148while (val.data.available() != 0) {149DerValue seq = val.data.getDerValue();150PolicyInformation policy = new PolicyInformation(seq);151certPolicies.add(policy);152}153}154155/**156* Return the extension as user readable string.157*/158public String toString() {159if (certPolicies == null) {160return "";161}162163StringBuilder sb = new StringBuilder();164sb.append(super.toString())165.append("CertificatePolicies [\n");166for (PolicyInformation info : certPolicies) {167sb.append(info);168}169sb.append("]\n");170return sb.toString();171}172173/**174* Write the extension to the DerOutputStream.175*176* @param out the DerOutputStream to write the extension to.177* @exception IOException on encoding errors.178*/179public void encode(OutputStream out) throws IOException {180DerOutputStream tmp = new DerOutputStream();181if (extensionValue == null) {182extensionId = PKIXExtensions.CertificatePolicies_Id;183critical = false;184encodeThis();185}186super.encode(tmp);187out.write(tmp.toByteArray());188}189190/**191* Set the attribute value.192*/193@SuppressWarnings("unchecked") // Checked with an instanceof check194public void set(String name, Object obj) throws IOException {195if (name.equalsIgnoreCase(POLICIES)) {196if (!(obj instanceof List)) {197throw new IOException("Attribute value should be of type List.");198}199certPolicies = (List<PolicyInformation>)obj;200} else {201throw new IOException("Attribute name [" + name +202"] not recognized by " +203"CertAttrSet:CertificatePoliciesExtension.");204}205encodeThis();206}207208/**209* Get the attribute value.210*/211public List<PolicyInformation> get(String name) throws IOException {212if (name.equalsIgnoreCase(POLICIES)) {213//XXXX May want to consider cloning this214return certPolicies;215} else {216throw new IOException("Attribute name [" + name +217"] not recognized by " +218"CertAttrSet:CertificatePoliciesExtension.");219}220}221222/**223* Delete the attribute value.224*/225public void delete(String name) throws IOException {226if (name.equalsIgnoreCase(POLICIES)) {227certPolicies = null;228} else {229throw new IOException("Attribute name [" + name +230"] not recognized by " +231"CertAttrSet:CertificatePoliciesExtension.");232}233encodeThis();234}235236/**237* Return an enumeration of names of attributes existing within this238* attribute.239*/240public Enumeration<String> getElements() {241AttributeNameEnumeration elements = new AttributeNameEnumeration();242elements.addElement(POLICIES);243244return (elements.elements());245}246247/**248* Return the name of this attribute.249*/250public String getName() {251return (NAME);252}253}254255256