1/*
2 * Copyright (c) 2000, 2012, 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
26package sun.security.provider.certpath;
27
28import java.io.IOException;
29import java.security.cert.CertificateException;
30import java.security.cert.X509Certificate;
31
32import sun.security.util.Debug;
33import sun.security.x509.AuthorityKeyIdentifierExtension;
34import sun.security.x509.KeyIdentifier;
35import sun.security.x509.SubjectKeyIdentifierExtension;
36import sun.security.x509.X509CertImpl;
37
38/*
39 * This class represents a vertex in the adjacency list. A
40 * vertex in the builder's view is just a distinguished name
41 * in the directory.  The Vertex contains a certificate
42 * along an attempted certification path, along with a pointer
43 * to a list of certificates that followed this one in various
44 * attempted certification paths.
45 *
46 * @author      Sean Mullan
47 * @since       1.4
48 */
49public class Vertex {
50
51    private static final Debug debug = Debug.getInstance("certpath");
52    private X509Certificate cert;
53    private int index;
54    private Throwable throwable;
55
56    /**
57     * Constructor; creates vertex with index of -1
58     * Use setIndex method to set another index.
59     *
60     * @param cert X509Certificate associated with vertex
61     */
62    Vertex(X509Certificate cert) {
63        this.cert = cert;
64        this.index = -1;
65    }
66
67    /**
68     * return the certificate for this vertex
69     *
70     * @return X509Certificate
71     */
72    public X509Certificate getCertificate() {
73        return cert;
74    }
75
76    /**
77     * get the index for this vertex, where the index is the row of the
78     * adjacency list that contains certificates that could follow this
79     * certificate.
80     *
81     * @return int index for this vertex, or -1 if no following certificates.
82     */
83    public int getIndex() {
84        return index;
85    }
86
87    /**
88     * set the index for this vertex, where the index is the row of the
89     * adjacency list that contains certificates that could follow this
90     * certificate.
91     *
92     * @param ndx int index for vertex, or -1 if no following certificates.
93     */
94    void setIndex(int ndx) {
95        index = ndx;
96    }
97
98    /**
99     * return the throwable associated with this vertex;
100     * returns null if none.
101     *
102     * @return Throwable
103     */
104    public Throwable getThrowable() {
105        return throwable;
106    }
107
108    /**
109     * set throwable associated with this vertex; default value is null.
110     *
111     * @param throwable Throwable associated with this vertex
112     *                  (or null)
113     */
114    void setThrowable(Throwable throwable) {
115        this.throwable = throwable;
116    }
117
118    /**
119     * Return full string representation of vertex
120     *
121     * @return String representation of vertex
122     */
123    @Override
124    public String toString() {
125        return certToString() + throwableToString() + indexToString();
126    }
127
128    /**
129     * Return string representation of this vertex's
130     * certificate information.
131     *
132     * @return String representation of certificate info
133     */
134    public String certToString() {
135        StringBuilder sb = new StringBuilder();
136
137        X509CertImpl x509Cert = null;
138        try {
139            x509Cert = X509CertImpl.toImpl(cert);
140        } catch (CertificateException ce) {
141            if (debug != null) {
142                debug.println("Vertex.certToString() unexpected exception");
143                ce.printStackTrace();
144            }
145            return sb.toString();
146        }
147
148        sb.append("Issuer:     ").append
149                 (x509Cert.getIssuerX500Principal()).append("\n");
150        sb.append("Subject:    ").append
151                 (x509Cert.getSubjectX500Principal()).append("\n");
152        sb.append("SerialNum:  ").append
153                 (x509Cert.getSerialNumber().toString(16)).append("\n");
154        sb.append("Expires:    ").append
155                 (x509Cert.getNotAfter().toString()).append("\n");
156        boolean[] iUID = x509Cert.getIssuerUniqueID();
157        if (iUID != null) {
158            sb.append("IssuerUID:  ");
159            for (boolean b : iUID) {
160                sb.append(b ? 1 : 0);
161            }
162            sb.append("\n");
163        }
164        boolean[] sUID = x509Cert.getSubjectUniqueID();
165        if (sUID != null) {
166            sb.append("SubjectUID: ");
167            for (boolean b : sUID) {
168                sb.append(b ? 1 : 0);
169            }
170            sb.append("\n");
171        }
172        try {
173            SubjectKeyIdentifierExtension sKeyID =
174                x509Cert.getSubjectKeyIdentifierExtension();
175            if (sKeyID != null) {
176                KeyIdentifier keyID = sKeyID.get(
177                        SubjectKeyIdentifierExtension.KEY_ID);
178                sb.append("SubjKeyID:  ").append(keyID.toString());
179            }
180            AuthorityKeyIdentifierExtension aKeyID =
181                x509Cert.getAuthorityKeyIdentifierExtension();
182            if (aKeyID != null) {
183                KeyIdentifier keyID = (KeyIdentifier)aKeyID.get(
184                        AuthorityKeyIdentifierExtension.KEY_ID);
185                sb.append("AuthKeyID:  ").append(keyID.toString());
186            }
187        } catch (IOException e) {
188            if (debug != null) {
189                debug.println("Vertex.certToString() unexpected exception");
190                e.printStackTrace();
191            }
192        }
193        return sb.toString();
194    }
195
196    /**
197     * return Vertex throwable as String compatible with
198     * the way toString returns other information
199     *
200     * @return String form of exception (or "none")
201     */
202    public String throwableToString() {
203        StringBuilder sb = new StringBuilder("Exception:  ");
204        if (throwable != null)
205            sb.append(throwable.toString());
206        else
207            sb.append("null");
208        sb.append("\n");
209        return sb.toString();
210    }
211
212    /**
213     * return Vertex index as String compatible with
214     * the way other Vertex.xToString() methods display
215     * information.
216     *
217     * @return String form of index as "Last cert?  [Yes/No]
218     */
219    public String moreToString() {
220        StringBuilder sb = new StringBuilder("Last cert?  ");
221        sb.append((index == -1) ? "Yes" : "No");
222        sb.append("\n");
223        return sb.toString();
224    }
225
226    /**
227     * return Vertex index as String compatible with
228     * the way other Vertex.xToString() methods displays other information.
229     *
230     * @return String form of index as "Index:     [numeric index]"
231     */
232    public String indexToString() {
233        return "Index:      " + index + "\n";
234    }
235}
236