Source code: jsdsi/FProver.java
1 /*
2 * Copyright 2002 Massachusetts Institute of Technology
3 *
4 * Permission to use, copy, modify, and distribute this program for any
5 * purpose and without fee is hereby granted, provided that this
6 * copyright and permission notice appear on all copies and supporting
7 * documentation, the name of M.I.T. not be used in advertising or
8 * publicity pertaining to distribution of the program without specific
9 * prior permission, and notice be given in supporting documentation that
10 * copying and distribution is by permission of M.I.T. M.I.T. makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 */
14 package jsdsi;
15
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.Set;
19
20 /**
21 * A prover that searches issuer-to-subject. Will only access the
22 * <code>CertStore</code> using <code>AuthCertSelector</code>s and
23 * <code>NameCertSelector</code>s.
24 *
25 * @see CertStore
26 * @see AuthCertSelector
27 * @see NameCertSelector
28 *
29 * @author Sameer Ajmani
30 * @version $Revision: 1.5 $ $Date: 2003/11/24 19:05:56 $
31 */
32 class FProver extends Prover {
33 /**
34 * Certificates for all issuers.
35 */
36 Set loadedIssuer = new HashSet();
37
38 /**
39 * Certificates for issuers->name-string.
40 */
41 Set loadedValue = new HashSet();
42
43 /**
44 * @see jsdsi.Prover#Prover(Cert, CertStore)
45 */
46 FProver(Cert c, java.security.cert.CertStore s) {
47 super(c, s);
48 }
49
50 /**
51 * @see jsdsi.Prover#makeProof()
52 */
53 Proof makeProof() {
54 try {
55 if (provee instanceof NameCert) {
56 loadValue(((NameCert) provee).getFullName());
57 } else {
58 loadIssuer(provee.getIssuer());
59 }
60 } catch (ProofFoundException e) {
61 return e.getProof();
62 }
63 return null;
64 }
65
66 /**
67 * Loads all certificates for a given issuer from the cert store to this
68 * <code>FProver</code>'s stored certificates.
69 *
70 * @param i issuer to add the certificates from.
71 * @return a set of this <code>FProver</code>'s certificates plus the
72 * certificates added.
73 * @throws ProofFoundException if a <i>proof is found</i>.
74 */
75 Set loadIssuer(Principal i) throws ProofFoundException {
76 CertSelector sel = new AuthCertSelector(i);
77 return load(loadedIssuer, i, sel, issuer);
78 }
79
80 /**
81 * Loads all certificates for the issuer of a given name and a name-string
82 * from the cert store to this <code>FProver</code>'s stored certificates.
83 *
84 * @param n name to add the certificates for <code>n</code>'s issuer and
85 * name-string bindings.
86 * @return a set with the used certificates plus the certificates added.
87 * @throws ProofFoundException if a <i>proof is found</i>.
88 */
89 Set loadValue(Name n) throws ProofFoundException {
90 CertSelector sel = new NameCertSelector(n.getIssuer(), n.getNames()[0]);
91 return load(loadedValue, n, sel, value);
92 }
93
94 /**
95 * @see jsdsi.Prover#insert(Proof)
96 */
97 void insert(Proof p) throws ProofFoundException {
98 //System.out.println("INSERT("+p.hashCode()+"): "+p);
99 if (p.getCert().implies(provee)) {
100 //System.out.println("INSERT("+p.hashCode()+"): found proof!");
101 throw new ProofFoundException(p);
102 }
103 if (!check.get(p.getCert()).isEmpty()) {
104 //System.out.println("INSERT("+p.hashCode()+"): already inserted");
105 return; // already have this proof
106 }
107 check.put(p.getCert(), p);
108
109 try {
110 if (p.getCert().getSubject() instanceof Name) {
111 Name key = ((Name) p.getCert().getSubject()).prefix();
112 compatible.put(key, p);
113 // look up compatible certs, and compose
114 Set values = loadValue(key);
115 //System.out.println("INSERT("+p.hashCode()
116 //+"): inserting right-composed "+values.size());
117 Iterator i = values.iterator();
118 while (i.hasNext()) {
119 try {
120 insert(p.compose((Proof) i.next()));
121 } catch (Proof.IncompatibleException e) {
122 throw new Error(e);
123 }
124 }
125 return;
126 }
127
128 if (p.getCert() instanceof NameCert) {
129 Name key = ((NameCert) p.getCert()).getFullName();
130 value.put(key, p);
131 // look up compatible certs, and compose
132 Set compats = compatible.get(key);
133 //System.out.println("INSERT("+p.hashCode()
134 //+"): inserting left-composed "+compats.size());
135 Iterator i = compats.iterator();
136 while (i.hasNext()) {
137 try {
138 insert(((Proof) i.next()).compose(p));
139 } catch (Proof.IncompatibleException e) {
140 throw new Error(e);
141 }
142 }
143 return;
144 }
145
146 if (p.getCert() instanceof AuthCert) {
147 issuer.put(p.getCert().getIssuer(), p);
148 reverse.put(p.getCert().getSubject(), p);
149
150 // TODO: optimize for provee:
151 // check whether p.tag implies provee.tag
152
153 if (((AuthCert) p.getCert()).getPropagate()
154 && (p.getCert().getSubject() instanceof Principal)) {
155 // search forwards locally to find auth chains
156 Set issuers = issuer.get(p.getCert().getSubject());
157 Iterator i = issuers.iterator();
158 while (i.hasNext()) {
159 try {
160 insert(p.compose((Proof) i.next()));
161 } catch (Proof.IncompatibleException e) {
162 throw new Error(e);
163 }
164 }
165 }
166
167 // search backwards locally to find auth chains
168 Set reverses = reverse.get(p.getCert().getIssuer());
169 Iterator i = reverses.iterator();
170 while (i.hasNext()) {
171 try {
172 Proof pf = (Proof) i.next();
173 if ((pf.getCert() instanceof AuthCert)
174 && ((AuthCert) pf.getCert()).getPropagate()
175 && (pf.getCert().getSubject() instanceof Principal)) {
176 insert(pf.compose(p));
177 }
178 } catch (Proof.IncompatibleException e) {
179 throw new Error(e);
180 }
181 }
182
183 if (((AuthCert) p.getCert()).getPropagate()
184 && (p.getCert().getSubject() instanceof Principal)) {
185 // search forwards to find new auths
186 Subject s = p.getCert().getSubject();
187 //System.out.println("INSERT("+p.hashCode()
188 //+"): fetching issuer for "+s.hashCode());
189 loadIssuer((Principal) s);
190 }
191 return;
192 }
193
194 throw new Error(
195 "unhandled case: " + p.getCert().getClass().getName());
196 } catch (ProofFoundException e) {
197 // invalidate cache
198 check.remove(p.getCert(), p);
199 throw e;
200 }
201 }
202 }