View Javadoc
1 package jsdsi; 2 3 import java.security.InvalidKeyException; 4 import java.security.NoSuchAlgorithmException; 5 import java.security.NoSuchProviderException; 6 import java.security.PublicKey; 7 import java.security.SignatureException; 8 import java.security.cert.CertificateException; 9 import java.util.ArrayList; 10 import java.util.Arrays; 11 import java.util.Iterator; 12 import java.util.List; 13 14 /*** 15 * A Cert along with its validators (verification path, signature, and 16 * online test results). Whereas a Cert is simply an unauthenticated 17 * statement, a Certificate is self-validating and thus can be 18 * considered authentic if verify() succeeds. A Certificate is 19 * serialized as a SPKI/SDSI Sequence. 20 * 21 * @see Cert 22 * @see Signature 23 * @see Sequence 24 * 25 * @author Sameer Ajmani 26 * @author Sean Radford 27 * @version $Revision: 1.3.2.1 $ $Date: 2005/11/08 03:12:52 $ 28 */ 29 public class Certificate extends java.security.cert.Certificate { 30 31 private static final long serialVersionUID = -2449865619310582192L; 32 33 /*** 34 * Issuer of this <code>Certificate</code>. 35 */ 36 private transient PublicKey issuer; // if null, cert.getIssuer() is a key 37 38 /*** 39 * <code>Cert</code> of this certificate. 40 */ 41 private transient Cert cert; 42 43 // TODO: VerificationPath ... 44 45 /*** 46 * <code>Signature</code> of this <code>Certificate</code>. 47 */ 48 private transient Signature sig; 49 50 // TODO: OnlineTestResult[] ... 51 52 /*** 53 * Creates a new <code>Certificate</code> from a given public key, 54 * <code>Cert</code>, and signature. 55 * 56 * @param k public key of the issuer (principal). 57 * @param c <code>Cert</code> of this <code>Certificate</code>. 58 * @param s <code>Signature</code> of this <code>Certificate</code>. 59 * @throws CertificateException if <code>k</code> is <code>null</code> or 60 * not a <code>PublicKey</code>. 61 */ 62 public Certificate(PublicKey k, Cert c, Signature s) 63 throws CertificateException { 64 super("SPKI"); 65 assert(c != null) : "null cert"; 66 assert(s != null) : "null signature"; 67 issuer = k; 68 cert = c; 69 sig = s; 70 if ((issuer == null) && !(c.getIssuer() instanceof PublicKey)) { 71 throw new CertificateException("issuer must be a PublicKey"); 72 } 73 } 74 75 /*** 76 * Creates a new <code>Certificate</code> from a given <code>Cert</code> 77 * and <code>Signature</code>. 78 * 79 * @param c <code>Cert</code> to create a new <code>Certificate</code> 80 * from. 81 * @param s <code>Signature</code> to create a new 82 * <code>Certificate</code> from. 83 * @throws CertificateException 84 */ 85 public Certificate(Cert c, Signature s) throws CertificateException { 86 this(null, c, s); 87 } 88 89 /*** 90 * @see java.security.cert.Certificate#getPublicKey() 91 */ 92 public java.security.PublicKey getPublicKey() { 93 if (issuer == null) { 94 return (PublicKey) cert.getIssuer(); 95 } else { 96 return issuer; 97 } 98 } 99 100 /*** 101 * @see java.security.cert.Certificate#verify(PublicKey) 102 */ 103 public void verify(java.security.PublicKey key) 104 throws CertificateException, 105 NoSuchAlgorithmException, 106 InvalidKeyException, 107 NoSuchProviderException, 108 SignatureException { 109 verify(key, null); 110 } 111 112 /*** 113 * @see java.security.cert.Certificate#verify(PublicKey, String) 114 */ 115 public void verify(java.security.PublicKey key, String sigProvider) 116 throws CertificateException, 117 NoSuchAlgorithmException, 118 InvalidKeyException, 119 NoSuchProviderException, 120 SignatureException { 121 assert(key != null) : "null key"; 122 if (!cert.getIssuer().samePrincipalAs(sig.getSigner())) { 123 throw new CertificateException("issuer does not match signer"); 124 } 125 if (!(key instanceof Principal) 126 || !cert.getIssuer().samePrincipalAs((Principal) key)) { 127 throw new CertificateException( 128 "verification key does not match issuer"); 129 } 130 if (!sig.verify(key, cert, sigProvider)) { 131 throw new SignatureException("signature verification failed"); 132 } 133 // TODO: check verification path, online test results, etc. 134 } 135 136 /*** 137 * @return the <code>Cert</code> of this <code>Certificate</code>. 138 */ 139 public Cert getCert() { 140 return cert; 141 } 142 143 /*** 144 * Checks if a given <code>Iterator</code> has more elements. 145 * 146 * @param elems <code>Iterator</code> to check for if it has more 147 * elements. 148 * @throws CertificateException if <code>elems</code> does not have 149 * any more elements. 150 */ 151 private static void check(Iterator elems) throws CertificateException { 152 if (!elems.hasNext()) { 153 throw new CertificateException("Not enough elements in sequence"); 154 } 155 } 156 157 /*** 158 * Factory method for creating a new <code>Certificate</code> from an 159 * iterator that holds a <code>Cert</code> and a <code>Signature</code>. 160 * 161 * @param elems <code>Iterator</code> holding a <code>Cert</code> and a 162 * <code>Signature</code> (in this order). 163 * @return the certificate created from the <code>Cert</code> and the 164 * <code>Signature</code> in <code>elems</code>. 165 * @throws CertificateException if <code>elems</code> does not contain 166 * the expected values. 167 */ 168 public static Certificate fromElements(Iterator elems) 169 throws CertificateException { 170 PublicKey issuer = null; 171 check(elems); 172 Element e = (Element) elems.next(); 173 if (e instanceof PublicKey) { 174 issuer = (PublicKey) e; 175 check(elems); 176 e = (Element) elems.next(); 177 } 178 if (!(e instanceof Cert)) { 179 throw new CertificateException("Expected cert"); 180 } 181 Cert cert = (Cert) e; 182 check(elems); 183 e = (Element) elems.next(); 184 if (!(e instanceof Signature)) { 185 throw new CertificateException("Expected signature"); 186 } 187 Signature sig = (Signature) e; 188 // TODO: include verification path, online test results, etc. 189 return new Certificate(issuer, cert, sig); 190 } 191 192 /*** 193 * Adds the issuer (if not <code>null</code>), the <code>Cert</code>, 194 * and the <code>Signture</code> of this <code>Certificate</code> to 195 * the given List. 196 * 197 * @param elems <code>List</code> to add the issuer (if not 198 * <code>null</code>), the <code>Cert</code>, and the 199 * <code>Signture</code> of this <code>Certificate</code> to. 200 */ 201 public void toElements(List elems) { 202 if (issuer != null) { 203 elems.add(issuer); 204 // TODO: if key is hashed in cert or sig, include hash ops 205 } 206 elems.add(cert); 207 elems.add(sig); 208 // TODO: include verification path, online test results, etc. 209 } 210 211 /*** 212 * Factory method that creates a new <code>Certificate</code> from a 213 * given <code>Sequence</code> that contains a <code>Cert</code> and 214 * a <code>Signature</code> (in this order). 215 * 216 * @param seq <code>Sequence</code> holding the <code>Cert</code> and the 217 * <code>Signature</code> to create the <code>Certificate</code> 218 * from. 219 * @return the new <code>Certificate</code>. 220 * @throws CertificateException if the creation of the 221 * <code>Certificate</code> failed. 222 */ 223 public static Certificate fromSequence(Sequence seq) 224 throws CertificateException { 225 return fromElements(Arrays.asList(seq.getElements()).iterator()); 226 } 227 228 /*** 229 * Returns a <code>Sequence</code> containing the issuer (if not 230 * <code>null</code>), the <code>Cert</code>, and the 231 * <code>Signature</code> of this <code>Certificate</code>. 232 * @return Sequence 233 */ 234 public Sequence toSequence() { 235 ArrayList elems = new ArrayList(); 236 toElements(elems); 237 return new Sequence((Element[]) elems.toArray(new Element[0])); 238 } 239 240 /*** 241 * @see java.lang.Object#toString() 242 */ 243 public String toString() { 244 return toSequence().toString(); 245 } 246 247 /*** 248 * @see java.security.cert.Certificate#getEncoded() 249 */ 250 public byte[] getEncoded() { 251 return toSequence().toByteArray(); 252 } 253 254 /*** 255 * Returns the format of this <code>Certificate</code>, namely 256 * <code>"SEXP"</code>. 257 * 258 * @return the format of this <code>Certificate</code> 259 * (<code>"SEXP"</code>). 260 */ 261 public String getFormat() { 262 return "SEXP"; 263 } 264 }

This page was automatically generated by Maven