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
23package org.apache.harmony.security.x509;
24
25import java.io.IOException;
26import java.util.Iterator;
27import java.util.Collection;
28import java.util.List;
29
30import org.apache.harmony.security.asn1.ASN1SequenceOf;
31import org.apache.harmony.security.asn1.ASN1Type;
32import org.apache.harmony.security.asn1.BerInputStream;
33import org.apache.harmony.security.internal.nls.Messages;
34
35/**
36 * The class encapsulates the ASN.1 DER encoding/decoding work
37 * with the CRL Distribution Points which is the part of X.509 Certificate
38 * (as specified in RFC 3280 -
39 *  Internet X.509 Public Key Infrastructure.
40 *  Certificate and Certificate Revocation List (CRL) Profile.
41 *  http://www.ietf.org/rfc/rfc3280.txt):
42 *
43 * <pre>
44 *  CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
45 *
46 *  DistributionPoint ::= SEQUENCE {
47 *        distributionPoint       [0]     DistributionPointName OPTIONAL,
48 *        reasons                 [1]     ReasonFlags OPTIONAL,
49 *        cRLIssuer               [2]     GeneralNames OPTIONAL
50 *  }
51 *
52 *  DistributionPointName ::= CHOICE {
53 *        fullName                [0]     GeneralNames,
54 *        nameRelativeToCRLIssuer [1]     RelativeDistinguishedName
55 *  }
56 *
57 *  ReasonFlags ::= BIT STRING {
58 *        unused                  (0),
59 *        keyCompromise           (1),
60 *        cACompromise            (2),
61 *        affiliationChanged      (3),
62 *        superseded              (4),
63 *        cessationOfOperation    (5),
64 *        certificateHold         (6),
65 *        privilegeWithdrawn      (7),
66 *        aACompromise            (8)
67 *  }
68 * </pre>
69 */
70public class CRLDistributionPoints extends ExtensionValue {
71
72    private List distributionPoints;
73    private byte[] encoding;
74
75    public CRLDistributionPoints(List distributionPoints) {
76        if ((distributionPoints == null)
77                || (distributionPoints.size() == 0)) {
78            throw new IllegalArgumentException(Messages.getString("security.17D")); //$NON-NLS-1$
79        }
80        this.distributionPoints = distributionPoints;
81    }
82
83    public CRLDistributionPoints(List distributionPoints, byte[] encoding) {
84        if ((distributionPoints == null)
85                || (distributionPoints.size() == 0)) {
86            throw new IllegalArgumentException(Messages.getString("security.17D")); //$NON-NLS-1$
87        }
88        this.distributionPoints = distributionPoints;
89        this.encoding = encoding;
90    }
91
92    public byte[] getEncoded() {
93        if (encoding == null) {
94            encoding = ASN1.encode(this);
95        }
96        return encoding;
97    }
98
99    public static CRLDistributionPoints decode(byte[] encoding)
100            throws IOException {
101        CRLDistributionPoints cdp = (CRLDistributionPoints) ASN1.decode(encoding);
102        return cdp;
103    }
104
105    /**
106     * Places the string representation of extension value
107     * into the StringBuffer object.
108     */
109    public void dumpValue(StringBuffer buffer, String prefix) {
110        buffer.append(prefix).append("CRL Distribution Points: [\n"); //$NON-NLS-1$
111        int number = 0;
112        for (Iterator it=distributionPoints.iterator();
113                it.hasNext();) {
114            buffer.append(prefix).append("  [").append(++number).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
115            ((DistributionPoint) it.next()).dumpValue(buffer, prefix + "  "); //$NON-NLS-1$
116        }
117        buffer.append(prefix).append("]\n"); //$NON-NLS-1$
118    }
119
120    /**
121     * Custom X.509 decoder.
122     */
123    public static final ASN1Type ASN1 =
124        new ASN1SequenceOf(DistributionPoint.ASN1) {
125
126        public Object getDecodedObject(BerInputStream in) {
127            return new CRLDistributionPoints((List)in.content,
128                    in.getEncoded());
129        }
130
131        public Collection getValues(Object object) {
132            CRLDistributionPoints dps = (CRLDistributionPoints) object;
133            return dps.distributionPoints;
134        }
135    };
136}
137
138