1 /* 2 * Copyright (c) 1997, 2004, 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.*; 29 30 import sun.security.util.*; 31 32 /** 33 * Represent the GeneralSubtree ASN.1 object, whose syntax is: 34 * <pre> 35 * GeneralSubtree ::= SEQUENCE { 36 * base GeneralName, 37 * minimum [0] BaseDistance DEFAULT 0, 38 * maximum [1] BaseDistance OPTIONAL 39 * } 40 * BaseDistance ::= INTEGER (0..MAX) 41 * </pre> 42 * @author Amit Kapoor 43 * @author Hemma Prafullchandra 44 */ 45 public class GeneralSubtree { 46 private static final byte TAG_MIN = 0; 47 private static final byte TAG_MAX = 1; 48 private static final int MIN_DEFAULT = 0; 49 50 private GeneralName name; 51 private int minimum = MIN_DEFAULT; 52 private int maximum = -1; 53 54 private int myhash = -1; 55 56 /** 57 * The default constructor for the class. 58 * 59 * @params name the GeneralName 60 * @params min the minimum BaseDistance 61 * @params max the maximum BaseDistance 62 */ GeneralSubtree(GeneralName name, int min, int max)63 public GeneralSubtree(GeneralName name, int min, int max) { 64 this.name = name; 65 this.minimum = min; 66 this.maximum = max; 67 } 68 69 /** 70 * Create the object from its DER encoded form. 71 * 72 * @param val the DER encoded from of the same. 73 */ GeneralSubtree(DerValue val)74 public GeneralSubtree(DerValue val) throws IOException { 75 if (val.tag != DerValue.tag_Sequence) { 76 throw new IOException("Invalid encoding for GeneralSubtree."); 77 } 78 name = new GeneralName(val.data.getDerValue(), true); 79 80 // NB. this is always encoded with the IMPLICIT tag 81 // The checks only make sense if we assume implicit tagging, 82 // with explicit tagging the form is always constructed. 83 while (val.data.available() != 0) { 84 DerValue opt = val.data.getDerValue(); 85 86 if (opt.isContextSpecific(TAG_MIN) && !opt.isConstructed()) { 87 opt.resetTag(DerValue.tag_Integer); 88 minimum = opt.getInteger(); 89 90 } else if (opt.isContextSpecific(TAG_MAX) && !opt.isConstructed()) { 91 opt.resetTag(DerValue.tag_Integer); 92 maximum = opt.getInteger(); 93 } else 94 throw new IOException("Invalid encoding of GeneralSubtree."); 95 } 96 } 97 98 /** 99 * Return the GeneralName. 100 * 101 * @return the GeneralName 102 */ getName()103 public GeneralName getName() { 104 //XXXX May want to consider cloning this 105 return name; 106 } 107 108 /** 109 * Return the minimum BaseDistance. 110 * 111 * @return the minimum BaseDistance. Default is 0 if not set. 112 */ getMinimum()113 public int getMinimum() { 114 return minimum; 115 } 116 117 /** 118 * Return the maximum BaseDistance. 119 * 120 * @return the maximum BaseDistance, or -1 if not set. 121 */ getMaximum()122 public int getMaximum() { 123 return maximum; 124 } 125 126 /** 127 * Return a printable string of the GeneralSubtree. 128 */ toString()129 public String toString() { 130 String s = "\n GeneralSubtree: [\n" + 131 " GeneralName: " + ((name == null) ? "" : name.toString()) + 132 "\n Minimum: " + minimum; 133 if (maximum == -1) { 134 s += "\t Maximum: undefined"; 135 } else 136 s += "\t Maximum: " + maximum; 137 s += " ]\n"; 138 return (s); 139 } 140 141 /** 142 * Compare this GeneralSubtree with another 143 * 144 * @param other GeneralSubtree to compare to this 145 * @returns true if match 146 */ equals(Object other)147 public boolean equals(Object other) { 148 if (!(other instanceof GeneralSubtree)) 149 return false; 150 GeneralSubtree otherGS = (GeneralSubtree)other; 151 if (this.name == null) { 152 if (otherGS.name != null) { 153 return false; 154 } 155 } else { 156 if (!((this.name).equals(otherGS.name))) 157 return false; 158 } 159 if (this.minimum != otherGS.minimum) 160 return false; 161 if (this.maximum != otherGS.maximum) 162 return false; 163 return true; 164 } 165 166 /** 167 * Returns the hash code for this GeneralSubtree. 168 * 169 * @return a hash code value. 170 */ hashCode()171 public int hashCode() { 172 if (myhash == -1) { 173 myhash = 17; 174 if (name != null) { 175 myhash = 37 * myhash + name.hashCode(); 176 } 177 if (minimum != MIN_DEFAULT) { 178 myhash = 37 * myhash + minimum; 179 } 180 if (maximum != -1) { 181 myhash = 37 * myhash + maximum; 182 } 183 } 184 return myhash; 185 } 186 187 /** 188 * Encode the GeneralSubtree. 189 * 190 * @params out the DerOutputStream to encode this object to. 191 */ encode(DerOutputStream out)192 public void encode(DerOutputStream out) throws IOException { 193 DerOutputStream seq = new DerOutputStream(); 194 195 name.encode(seq); 196 197 if (minimum != MIN_DEFAULT) { 198 DerOutputStream tmp = new DerOutputStream(); 199 tmp.putInteger(minimum); 200 seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, 201 false, TAG_MIN), tmp); 202 } 203 if (maximum != -1) { 204 DerOutputStream tmp = new DerOutputStream(); 205 tmp.putInteger(maximum); 206 seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT, 207 false, TAG_MAX), tmp); 208 } 209 out.write(DerValue.tag_Sequence, seq); 210 } 211 } 212