Home | History | Annotate | Download | only in x509
      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 Alexander Y. Kleymenov
     20 * @version $Revision$
     21 */
     22 
     23 package org.apache.harmony.security.x509;
     24 
     25 import java.io.IOException;
     26 import org.apache.harmony.security.asn1.ASN1Explicit;
     27 import org.apache.harmony.security.asn1.ASN1Implicit;
     28 import org.apache.harmony.security.asn1.ASN1Sequence;
     29 import org.apache.harmony.security.asn1.ASN1Type;
     30 import org.apache.harmony.security.asn1.BerInputStream;
     31 
     32 /**
     33  * The class encapsulates the ASN.1 DER encoding/decoding work
     34  * with the DistributionPoint structure which is the part of X.509 CRL
     35  * (as specified in RFC 3280 -
     36  *  Internet X.509 Public Key Infrastructure.
     37  *  Certificate and Certificate Revocation List (CRL) Profile.
     38  *  http://www.ietf.org/rfc/rfc3280.txt):
     39  *
     40  * <pre>
     41  *  CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
     42  *
     43  *  DistributionPoint ::= SEQUENCE {
     44  *        distributionPoint       [0]     DistributionPointName OPTIONAL,
     45  *        reasons                 [1]     ReasonFlags OPTIONAL,
     46  *        cRLIssuer               [2]     GeneralNames OPTIONAL
     47  *  }
     48  *
     49  *  DistributionPointName ::= CHOICE {
     50  *        fullName                [0]     GeneralNames,
     51  *        nameRelativeToCRLIssuer [1]     RelativeDistinguishedName
     52  *  }
     53  *
     54  *  ReasonFlags ::= BIT STRING {
     55  *        unused                  (0),
     56  *        keyCompromise           (1),
     57  *        cACompromise            (2),
     58  *        affiliationChanged      (3),
     59  *        superseded              (4),
     60  *        cessationOfOperation    (5),
     61  *        certificateHold         (6),
     62  *        privilegeWithdrawn      (7),
     63  *        aACompromise            (8)
     64  *  }
     65  * </pre>
     66  */
     67 public final class DistributionPoint {
     68     private final DistributionPointName distributionPoint;
     69     private final ReasonFlags reasons;
     70     private final GeneralNames cRLIssuer;
     71 
     72     public DistributionPoint(DistributionPointName distributionPoint,
     73             ReasonFlags reasons, GeneralNames cRLIssuer) {
     74         if ((reasons != null) && (distributionPoint == null) && (cRLIssuer == null)) {
     75             throw new IllegalArgumentException("DistributionPoint MUST NOT consist of only the reasons field");
     76         }
     77         this.distributionPoint = distributionPoint;
     78         this.reasons = reasons;
     79         this.cRLIssuer = cRLIssuer;
     80     }
     81 
     82     public void dumpValue(StringBuilder sb, String prefix) {
     83         sb.append(prefix);
     84         sb.append("Distribution Point: [\n");
     85         if (distributionPoint != null) {
     86             distributionPoint.dumpValue(sb, prefix + "  ");
     87         }
     88         if (reasons != null) {
     89             reasons.dumpValue(sb, prefix + "  ");
     90         }
     91         if (cRLIssuer != null) {
     92             sb.append(prefix);
     93             sb.append("  CRL Issuer: [\n");
     94             cRLIssuer.dumpValue(sb, prefix + "    ");
     95             sb.append(prefix);
     96             sb.append("  ]\n");
     97         }
     98         sb.append(prefix);
     99         sb.append("]\n");
    100     }
    101 
    102     /**
    103      * Custom X.509 decoder.
    104      */
    105     public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] {
    106                 new ASN1Explicit(0, DistributionPointName.ASN1),
    107                 new ASN1Implicit(1, ReasonFlags.ASN1),
    108                 new ASN1Implicit(2, GeneralNames.ASN1)
    109             }) {
    110         {
    111             setOptional(0);
    112             setOptional(1);
    113             setOptional(2);
    114         }
    115 
    116         @Override protected Object getDecodedObject(BerInputStream in) throws IOException {
    117             Object[] values = (Object[]) in.content;
    118             return new DistributionPoint((DistributionPointName) values[0],
    119                     (ReasonFlags) values[1], (GeneralNames) values[2]);
    120         }
    121 
    122         @Override protected void getValues(Object object, Object[] values) {
    123             DistributionPoint dp = (DistributionPoint) object;
    124             values[0] = dp.distributionPoint;
    125             values[1] = dp.reasons;
    126             values[2] = dp.cRLIssuer;
    127         }
    128     };
    129 }
    130