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 
26 package sun.security.provider.certpath;
27 
28 import java.io.IOException;
29 import java.security.cert.CertificateException;
30 import java.security.cert.X509Certificate;
31 
32 import sun.security.util.Debug;
33 import sun.security.x509.AuthorityKeyIdentifierExtension;
34 import sun.security.x509.KeyIdentifier;
35 import sun.security.x509.SubjectKeyIdentifierExtension;
36 import 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  */
49 public 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      */
Vertex(X509Certificate cert)62     Vertex(X509Certificate cert) {
63         this.cert = cert;
64         this.index = -1;
65     }
66 
67     /**
68      * return the certificate for this vertex
69      *
70      * @returns X509Certificate
71      */
getCertificate()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      * @returns int index for this vertex, or -1 if no following certificates.
82      */
getIndex()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      */
setIndex(int ndx)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      * @returns Throwable
103      */
getThrowable()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      */
setThrowable(Throwable throwable)114     void setThrowable(Throwable throwable) {
115         this.throwable = throwable;
116     }
117 
118     /**
119      * Return full string representation of vertex
120      *
121      * @returns String representation of vertex
122      */
123     @Override
toString()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      * @returns String representation of certificate info
133      */
certToString()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      * @returns String form of exception (or "none")
201      */
throwableToString()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      * @returns String form of index as "Last cert?  [Yes/No]
218      */
moreToString()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      * @returns String form of index as "Index:     [numeric index]"
231      */
indexToString()232     public String indexToString() {
233         return "Index:      " + index + "\n";
234     }
235 }
236