1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /** 19 * @author Vladimir N. Molotkov, Alexander Y. Kleymenov 20 * @version $Revision$ 21 */ 22 23 package org.apache.harmony.security.x509; 24 25 import org.apache.harmony.security.asn1.ASN1Implicit; 26 import org.apache.harmony.security.asn1.ASN1Integer; 27 import org.apache.harmony.security.asn1.ASN1Sequence; 28 import org.apache.harmony.security.asn1.ASN1Type; 29 import org.apache.harmony.security.asn1.BerInputStream; 30 31 /** 32 * The class encapsulates the ASN.1 DER encoding/decoding work 33 * with the GeneralSubtree structure which is a part of X.509 certificate: 34 * (as specified in RFC 3280 - 35 * Internet X.509 Public Key Infrastructure. 36 * Certificate and Certificate Revocation List (CRL) Profile. 37 * http://www.ietf.org/rfc/rfc3280.txt): 38 * 39 * <pre> 40 * 41 * GeneralSubtree ::= SEQUENCE { 42 * base GeneralName, 43 * minimum [0] BaseDistance DEFAULT 0, 44 * maximum [1] BaseDistance OPTIONAL } 45 * 46 * BaseDistance ::= INTEGER (0..MAX) 47 * 48 * </pre> 49 * 50 * @see org.apache.harmony.security.x509.NameConstraints 51 * @see org.apache.harmony.security.x509.GeneralName 52 */ 53 public final class GeneralSubtree { 54 /** the value of base field of the structure */ 55 private final GeneralName base; 56 /** the value of minimum field of the structure */ 57 private final int minimum; 58 /** the value of maximum field of the structure */ 59 private final int maximum; 60 /** the ASN.1 encoded form of GeneralSubtree */ 61 private byte[] encoding; 62 63 public GeneralSubtree(GeneralName base, int minimum, int maximum) { 64 this.base = base; 65 this.minimum = minimum; 66 this.maximum = maximum; 67 } 68 69 /** 70 * Returns the value of base field of the structure. 71 */ 72 public GeneralName getBase() { 73 return base; 74 } 75 76 /** 77 * Returns ASN.1 encoded form of this X.509 GeneralSubtree value. 78 */ 79 public byte[] getEncoded() { 80 if (encoding == null) { 81 encoding = ASN1.encode(this); 82 } 83 return encoding; 84 } 85 86 public void dumpValue(StringBuilder sb, String prefix) { 87 sb.append(prefix).append("General Subtree: [\n"); 88 sb.append(prefix).append(" base: ").append(base).append('\n'); 89 sb.append(prefix).append(" minimum: ").append(minimum).append('\n'); 90 if (maximum >= 0) { 91 sb.append(prefix).append(" maximum: ").append(maximum).append('\n'); 92 } 93 sb.append(prefix).append("]\n"); 94 } 95 96 /** 97 * ASN.1 DER X.509 GeneralSubtree encoder/decoder class. 98 */ 99 public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] { 100 GeneralName.ASN1, 101 new ASN1Implicit(0, ASN1Integer.getInstance()), 102 new ASN1Implicit(1, ASN1Integer.getInstance()) }) { 103 { 104 setDefault(new byte[] {0}, 1); // minimum 0 105 setOptional(2); // maximum optional 106 } 107 108 @Override protected Object getDecodedObject(BerInputStream in) { 109 Object[] values = (Object[]) in.content; 110 int maximum = -1; // is optional maximum missing? 111 if (values[2] != null) { 112 maximum = ASN1Integer.toIntValue(values[2]); // no! 113 } 114 return new GeneralSubtree((GeneralName) values[0], 115 ASN1Integer.toIntValue(values[1]), 116 maximum); 117 } 118 119 @Override protected void getValues(Object object, Object[] values) { 120 GeneralSubtree gs = (GeneralSubtree) object; 121 values[0] = gs.base; 122 values[1] = ASN1Integer.fromIntValue(gs.minimum); 123 if (gs.maximum > -1) { 124 values[2] = ASN1Integer.fromIntValue(gs.maximum); 125 } 126 } 127 }; 128 } 129