1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.x509; 27 28 import java.io.IOException; 29 import java.io.OutputStream; 30 import java.security.cert.CRLReason; 31 import java.util.Enumeration; 32 33 import sun.security.util.*; 34 35 /** 36 * The reasonCode is a non-critical CRL entry extension that identifies 37 * the reason for the certificate revocation. 38 * @author Hemma Prafullchandra 39 * @see java.security.cert.CRLReason 40 * @see Extension 41 * @see CertAttrSet 42 */ 43 public class CRLReasonCodeExtension extends Extension 44 implements CertAttrSet<String> { 45 46 /** 47 * Attribute name 48 */ 49 public static final String NAME = "CRLReasonCode"; 50 public static final String REASON = "reason"; 51 52 private static CRLReason[] values = CRLReason.values(); 53 54 private int reasonCode = 0; 55 encodeThis()56 private void encodeThis() throws IOException { 57 if (reasonCode == 0) { 58 this.extensionValue = null; 59 return; 60 } 61 DerOutputStream dos = new DerOutputStream(); 62 dos.putEnumerated(reasonCode); 63 this.extensionValue = dos.toByteArray(); 64 } 65 66 /** 67 * Create a CRLReasonCodeExtension with the passed in reason. 68 * Criticality automatically set to false. 69 * 70 * @param reason the enumerated value for the reason code. 71 */ CRLReasonCodeExtension(int reason)72 public CRLReasonCodeExtension(int reason) throws IOException { 73 this(false, reason); 74 } 75 76 /** 77 * Create a CRLReasonCodeExtension with the passed in reason. 78 * 79 * @param critical true if the extension is to be treated as critical. 80 * @param reason the enumerated value for the reason code. 81 */ CRLReasonCodeExtension(boolean critical, int reason)82 public CRLReasonCodeExtension(boolean critical, int reason) 83 throws IOException { 84 this.extensionId = PKIXExtensions.ReasonCode_Id; 85 this.critical = critical; 86 this.reasonCode = reason; 87 encodeThis(); 88 } 89 90 /** 91 * Create the extension from the passed DER encoded value of the same. 92 * 93 * @param critical true if the extension is to be treated as critical. 94 * @param value an array of DER encoded bytes of the actual value. 95 * @exception ClassCastException if value is not an array of bytes 96 * @exception IOException on error. 97 */ CRLReasonCodeExtension(Boolean critical, Object value)98 public CRLReasonCodeExtension(Boolean critical, Object value) 99 throws IOException { 100 this.extensionId = PKIXExtensions.ReasonCode_Id; 101 this.critical = critical.booleanValue(); 102 this.extensionValue = (byte[]) value; 103 DerValue val = new DerValue(this.extensionValue); 104 this.reasonCode = val.getEnumerated(); 105 } 106 107 /** 108 * Set the attribute value. 109 */ set(String name, Object obj)110 public void set(String name, Object obj) throws IOException { 111 if (!(obj instanceof Integer)) { 112 throw new IOException("Attribute must be of type Integer."); 113 } 114 if (name.equalsIgnoreCase(REASON)) { 115 reasonCode = ((Integer)obj).intValue(); 116 } else { 117 throw new IOException 118 ("Name not supported by CRLReasonCodeExtension"); 119 } 120 encodeThis(); 121 } 122 123 /** 124 * Get the attribute value. 125 */ get(String name)126 public Integer get(String name) throws IOException { 127 if (name.equalsIgnoreCase(REASON)) { 128 return new Integer(reasonCode); 129 } else { 130 throw new IOException 131 ("Name not supported by CRLReasonCodeExtension"); 132 } 133 } 134 135 /** 136 * Delete the attribute value. 137 */ delete(String name)138 public void delete(String name) throws IOException { 139 if (name.equalsIgnoreCase(REASON)) { 140 reasonCode = 0; 141 } else { 142 throw new IOException 143 ("Name not supported by CRLReasonCodeExtension"); 144 } 145 encodeThis(); 146 } 147 148 /** 149 * Returns a printable representation of the Reason code. 150 */ toString()151 public String toString() { 152 return super.toString() + " Reason Code: " + getReasonCode(); 153 } 154 155 /** 156 * Write the extension to the DerOutputStream. 157 * 158 * @param out the DerOutputStream to write the extension to. 159 * @exception IOException on encoding errors. 160 */ encode(OutputStream out)161 public void encode(OutputStream out) throws IOException { 162 DerOutputStream tmp = new DerOutputStream(); 163 164 if (this.extensionValue == null) { 165 this.extensionId = PKIXExtensions.ReasonCode_Id; 166 this.critical = false; 167 encodeThis(); 168 } 169 super.encode(tmp); 170 out.write(tmp.toByteArray()); 171 } 172 173 /** 174 * Return an enumeration of names of attributes existing within this 175 * attribute. 176 */ getElements()177 public Enumeration<String> getElements() { 178 AttributeNameEnumeration elements = new AttributeNameEnumeration(); 179 elements.addElement(REASON); 180 181 return elements.elements(); 182 } 183 184 /** 185 * Return the name of this attribute. 186 */ getName()187 public String getName() { 188 return NAME; 189 } 190 191 /** 192 * Return the reason as a CRLReason enum. 193 */ getReasonCode()194 public CRLReason getReasonCode() { 195 // if out-of-range, return UNSPECIFIED 196 if (reasonCode > 0 && reasonCode < values.length) { 197 return values[reasonCode]; 198 } else { 199 return CRLReason.UNSPECIFIED; 200 } 201 } 202 } 203