libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / java / security / cert / X509CertSelector.java
blob4115fffacfa560cd5c4a7e9575affdc75bc84e88
1 /* X509CertSelector.java -- selects X.509 certificates by criteria.
2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.security.cert;
41 import gnu.classpath.SystemProperties;
42 import gnu.java.lang.CPStringBuilder;
43 import gnu.java.security.OID;
44 import gnu.java.security.x509.GnuPKIExtension;
45 import gnu.java.security.x509.ext.CertificatePolicies;
46 import gnu.java.security.x509.ext.Extension;
47 import gnu.java.security.x509.ext.GeneralName;
48 import gnu.java.security.x509.ext.GeneralSubtree;
49 import gnu.java.security.x509.ext.NameConstraints;
50 import gnu.java.security.x509.ext.GeneralName.Kind;
52 import java.io.IOException;
53 import java.math.BigInteger;
54 import java.net.InetAddress;
55 import java.security.KeyFactory;
56 import java.security.PublicKey;
57 import java.security.spec.X509EncodedKeySpec;
58 import java.util.ArrayList;
59 import java.util.Arrays;
60 import java.util.Collection;
61 import java.util.Collections;
62 import java.util.Date;
63 import java.util.HashSet;
64 import java.util.Iterator;
65 import java.util.LinkedList;
66 import java.util.List;
67 import java.util.Set;
69 import javax.security.auth.x500.X500Principal;
71 /**
72 * A concrete implementation of {@link CertSelector} for X.509 certificates,
73 * which allows a number of criteria to be set when accepting certificates,
74 * from validity dates, to issuer and subject distinguished names, to some
75 * of the various X.509 extensions.
77 * <p>Use of this class requires extensive knowledge of the Internet
78 * Engineering Task Force's Public Key Infrastructure (X.509). The primary
79 * document describing this standard is <a
80 * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
81 * Public Key Infrastructure Certificate and Certificate Revocation List
82 * (CRL) Profile</a>.
84 * <p>Note that this class is not thread-safe. If multiple threads will
85 * use or modify this class then they need to synchronize on the object.
87 * @author Casey Marshall (csm@gnu.org)
88 * @since 1.4
90 public class X509CertSelector implements CertSelector, Cloneable
93 // Constants and fields.
94 // -------------------------------------------------------------------------
96 private static final String AUTH_KEY_ID = "2.5.29.35";
97 private static final String SUBJECT_KEY_ID = "2.5.29.14";
98 private static final String NAME_CONSTRAINTS_ID = "2.5.29.30";
100 private static boolean checkOid(int[] oid)
102 return (oid != null && oid.length > 2 &&
103 (oid[0] >= 0 && oid[0] <= 2) && (oid[1] >= 0 && oid[1] <= 39));
106 private static GeneralName makeName(int id, String name) throws IOException
108 byte[] nameBytes = null;
109 GeneralName.Kind kind = GeneralName.Kind.forTag(id);
110 switch (Kind.forTag(id))
112 case dNSName:
113 case rfc822Name:
114 case uniformResourceIdentifier:
115 nameBytes = name.getBytes("ASCII");
116 break;
118 case iPAddress:
119 InetAddress addr = InetAddress.getByName(name);
120 nameBytes = addr.getAddress();
121 break;
123 case registeredId:
124 OID oid = new OID(name);
125 nameBytes = oid.getDER();
126 break;
128 case directoryName:
129 X500Principal xname = new X500Principal(name);
130 nameBytes = xname.getEncoded();
131 break;
133 case ediPartyName:
134 case x400Address:
135 case otherName:
136 throw new IOException("cannot decode string representation of "
137 + kind);
139 return new GeneralName(kind, nameBytes);
142 private int basicConstraints;
143 private X509Certificate cert;
144 private BigInteger serialNo;
145 private X500Principal issuer;
146 private X500Principal subject;
147 private byte[] subjectKeyId;
148 private byte[] authKeyId;
149 private boolean[] keyUsage;
150 private Date certValid;
151 private OID sigId;
152 private PublicKey subjectKey;
153 private X509EncodedKeySpec subjectKeySpec;
154 private Set<String> keyPurposeSet;
155 private List<GeneralName> altNames;
156 private boolean matchAllNames;
157 private byte[] nameConstraints;
158 private Set<OID> policy;
159 private List<GeneralName> pathToNames;
162 * Creates a new X.509 certificate selector. The new selector will be
163 * empty, and will accept any certificate (provided that it is an
164 * {@link X509Certificate}).
166 public X509CertSelector()
168 basicConstraints = -1;
172 * Add a name to match in the NameConstraints extension. The argument is
173 * the DER-encoded bytes of a GeneralName structure.
175 * See the method {@link #addSubjectAlternativeName(int, byte[])} for the
176 * format of the GeneralName structure.
178 * @param id The name identifier. Must be between 0 and 8.
179 * @param name The DER-encoded bytes of the name to match.
180 * @throws IOException If the name DER is malformed.
182 public void addPathToName(int id, byte[] name) throws IOException
184 GeneralName generalName = new GeneralName(GeneralName.Kind.forTag(id), name);
185 if (pathToNames == null)
186 pathToNames = new LinkedList<GeneralName>();
187 pathToNames.add(generalName);
191 * Add a name to match in the NameConstraints extension. This method will
192 * only recognize certain types of name that have convenient string
193 * encodings. For robustness, you should use the {@link
194 * #addPathToName(int, byte[])} method whenever possible.
196 * @param id The name identifier. Must be between 0 and 8.
197 * @param name The name.
198 * @throws IOException If the name cannot be decoded.
200 public void addPathToName(int id, String name) throws IOException
202 GeneralName generalName = makeName(id, name);
203 if (pathToNames == null)
204 pathToNames = new LinkedList<GeneralName>();
205 pathToNames.add(generalName);
209 * Add a name, as DER-encoded bytes, to the subject alternative names
210 * criterion.
212 * The name is a GeneralName structure, which has the ASN.1 format:
214 * <pre>
215 GeneralName ::= CHOICE {
216 otherName [0] OtherName,
217 rfc822Name [1] IA5String,
218 dNSName [2] IA5String,
219 x400Address [3] ORAddress,
220 directoryName [4] Name,
221 ediPartyName [5] EDIPartyName,
222 uniformResourceIdentifier [6] IA5String,
223 iPAddress [7] OCTET STRING,
224 registeredID [8] OBJECT IDENTIFIER }
225 </pre>
227 * @param id The type of name this is.
228 * @param name The DER-encoded name.
229 * @throws IOException If the name is not a valid DER sequence.
231 public void addSubjectAlternativeName(int id, byte[] name)
232 throws IOException
234 GeneralName generalName = new GeneralName(GeneralName.Kind.forTag(id), name);
235 if (altNames == null)
236 altNames = new LinkedList<GeneralName>();
237 altNames.add(generalName);
241 * Add a name to the subject alternative names criterion. This method will
242 * only recognize certain types of name that have convenient string
243 * encodings. For robustness, you should use the {@link
244 * #addSubjectAlternativeName(int, byte[])} method whenever possible.
246 * This method can only decode certain name kinds of names as strings.
248 * @param id The type of name this is. Must be in the range [0,8].
249 * @param name The name.
250 * @throws IOException If the id is out of range, or if the name
251 * is null.
253 public void addSubjectAlternativeName(int id, String name)
254 throws IOException
256 GeneralName generalName = makeName(id, name);
257 if (altNames == null)
258 altNames = new LinkedList<GeneralName>();
259 altNames.add(generalName);
262 public Object clone()
266 return super.clone();
268 catch (CloneNotSupportedException shouldNotHappen)
270 throw new Error(shouldNotHappen);
275 * Returns the authority key identifier criterion, or <code>null</code> if
276 * this value was not set. Note that the byte array is cloned to prevent
277 * modification.
279 * @return The authority key identifier.
281 public byte[] getAuthorityKeyIdentifier()
283 if (authKeyId != null)
284 return (byte[]) authKeyId.clone();
285 else
286 return null;
290 * Returns the basic constraints criterion, or -1 if this value is not set.
292 * @return The basic constraints.
294 public int getBasicConstraints()
296 return basicConstraints;
300 * Returns the certificate criterion, or <code>null</code> if this value
301 * was not set.
303 * @return The certificate.
305 public X509Certificate getCertificate()
307 return cert;
311 * Returns the date at which certificates must be valid, or <code>null</code>
312 * if this criterion was not set.
314 * @return The target certificate valitity date.
316 public Date getCertificateValid()
318 if (certValid != null)
319 return (Date) certValid.clone();
320 else
321 return null;
325 * Returns the set of extended key purpose IDs, as an unmodifiable set
326 * of OID strings. Returns <code>null</code> if this criterion is not
327 * set.
329 * @return The set of key purpose OIDs (strings).
331 public Set<String> getExtendedKeyUsage()
333 if (keyPurposeSet != null)
334 return Collections.unmodifiableSet(keyPurposeSet);
335 else
336 return null;
340 * Returns the issuer criterion as a sequence of DER bytes, or
341 * <code>null</code> if this value was not set.
343 * @return The issuer.
345 public byte[] getIssuerAsBytes() throws IOException
347 if (issuer != null)
348 return issuer.getEncoded();
349 else
350 return null;
354 * Returns the issuer criterion as a string, or <code>null</code> if this
355 * value was not set.
357 * @return The issuer.
359 public String getIssuerAsString()
361 if (issuer != null)
362 return issuer.getName();
363 else
364 return null;
368 * Returns the public key usage criterion, or <code>null</code> if this
369 * value is not set. Note that the array is cloned to prevent modification.
371 * @return The public key usage.
373 public boolean[] getKeyUsage()
375 if (keyUsage != null)
376 return (boolean[]) keyUsage.clone();
377 else
378 return null;
382 * Returns whether or not all specified alternative names must match.
383 * If false, a certificate is considered a match if <em>one</em> of the
384 * specified alternative names matches.
386 * @return true if all names must match.
388 public boolean getMatchAllSubjectAltNames()
390 return matchAllNames;
394 * Returns the name constraints criterion, or <code>null</code> if this
395 * value is not set. Note that the byte array is cloned to prevent
396 * modification.
398 * @return The name constraints.
400 public byte[] getNameConstraints()
402 if (nameConstraints != null)
403 return (byte[]) nameConstraints.clone();
404 else
405 return null;
408 public Collection<List<?>> getPathToNames()
410 if (pathToNames != null)
412 List<List<?>> names = new ArrayList<List<?>>(pathToNames.size());
413 for (GeneralName name : pathToNames)
415 List<Object> n = new ArrayList<Object>(2);
416 n.add(name.kind().tag());
417 n.add(name.name());
418 names.add(n);
421 return names;
423 return null;
427 * Returns the certificate policy extension that will be matched by this
428 * selector, or null if the certificate policy will not be matched.
430 * @return The policy to be matched, or null.
432 public Set<String> getPolicy()
434 Set<OID> p = this.policy;
435 if (p != null)
437 Set<String> strings = new HashSet<String>(p.size());
438 for (OID o : p)
440 strings.add(o.toString());
442 return strings;
444 return null;
448 * This method, and its related X.509 certificate extension &mdash; the
449 * private key usage period &mdash; is not supported under the Internet
450 * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
451 * method is not supported either.
453 * <p>Do not use this method. It is not deprecated, as it is not deprecated
454 * in the Java standard, but it is basically a no-operation and simply
455 * returns <code>null</code>.
457 * @return Null.
459 public Date getPrivateKeyValid()
461 return null;
465 * Returns the serial number criterion, or <code>null</code> if this
466 * value was not set.
468 * @return The serial number.
470 public BigInteger getSerialNumber()
472 return serialNo;
476 * Get the subject alternative names criterion. The collection returned
477 * is a collection of pairs: the first element is an {@link Integer}
478 * containing the name type, and the second is a byte array containing
479 * the DER-encoded name bytes.
481 * @return The subject alternative names criterion. Returns null if this
482 * criterion is not set.
484 public Collection<List<?>> getSubjectAlternativeNames()
486 if (altNames != null)
488 List<List<?>> names = new ArrayList<List<?>>(altNames.size());
489 for (GeneralName name : altNames)
491 List<Object> n = new ArrayList<Object>(2);
492 n.add(name.kind().tag());
493 n.add(name.name());
494 names.add(n);
496 return names;
498 return null;
502 * Returns the subject criterion as a sequence of DER bytes, or
503 * <code>null</code> if this value is not set.
505 * @return The subject.
507 public byte[] getSubjectAsBytes() throws IOException
509 if (subject != null)
510 return subject.getEncoded();
511 else
512 return null;
516 * Returns the subject criterion as a string, of <code>null</code> if
517 * this value was not set.
519 * @return The subject.
521 public String getSubjectAsString()
523 if (subject != null)
524 return subject.getName();
525 else
526 return null;
530 * Returns the subject key identifier criterion, or <code>null</code> if
531 * this value was not set. Note that the byte array is cloned to prevent
532 * modification.
534 * @return The subject key identifier.
536 public byte[] getSubjectKeyIdentifier()
538 if (subjectKeyId != null)
539 return (byte[]) subjectKeyId.clone();
540 else
541 return null;
545 * Returns the subject public key criterion, or <code>null</code> if this
546 * value is not set.
548 * @return The subject public key.
550 public PublicKey getSubjectPublicKey()
552 return subjectKey;
556 * Returns the public key algorithm ID that matching certificates must have,
557 * or <code>null</code> if this criterion was not set.
559 * @return The public key algorithm ID.
561 public String getSubjectPublicKeyAlgID()
563 return String.valueOf(sigId);
567 * Match a certificate. This method will check the given certificate
568 * against all the enabled criteria of this selector, and will return
569 * <code>true</code> if the given certificate matches.
571 * @param certificate The certificate to check.
572 * @return true if the certificate matches all criteria.
574 public boolean match(Certificate certificate)
576 if (!(certificate instanceof X509Certificate))
577 return false;
578 X509Certificate cert = (X509Certificate) certificate;
579 if (this.cert != null)
583 byte[] e1 = this.cert.getEncoded();
584 byte[] e2 = cert.getEncoded();
585 if (!Arrays.equals(e1, e2))
586 return false;
588 catch (CertificateEncodingException cee)
590 return false;
593 if (serialNo != null)
595 if (!serialNo.equals(cert.getSerialNumber()))
596 return false;
598 if (certValid != null)
602 cert.checkValidity(certValid);
604 catch (CertificateException ce)
606 return false;
609 if (issuer != null)
611 if (!issuer.equals(cert.getIssuerX500Principal()))
612 return false;
614 if (subject != null)
616 if (!subject.equals(cert.getSubjectX500Principal()))
617 return false;
619 if (sigId != null)
621 if (!sigId.toString().equals(cert.getSigAlgOID()))
622 return false;
624 if (subjectKeyId != null)
626 byte[] b = cert.getExtensionValue(SUBJECT_KEY_ID);
627 if (!Arrays.equals(b, subjectKeyId))
628 return false;
630 if (authKeyId != null)
632 byte[] b = cert.getExtensionValue(AUTH_KEY_ID);
633 if (!Arrays.equals(b, authKeyId))
634 return false;
636 if (keyUsage != null)
638 boolean[] b = cert.getKeyUsage();
639 if (!Arrays.equals(b, keyUsage))
640 return false;
642 if (basicConstraints >= 0)
644 if (cert.getBasicConstraints() != basicConstraints)
645 return false;
647 if (keyPurposeSet != null)
649 List kp = null;
652 kp = cert.getExtendedKeyUsage();
654 catch (CertificateParsingException cpe)
656 return false;
658 if (kp == null)
659 return false;
660 for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
662 if (!kp.contains(it.next()))
663 return false;
666 if (altNames != null)
668 Collection<List<?>> an = null;
671 an = cert.getSubjectAlternativeNames();
673 catch (CertificateParsingException cpe)
675 return false;
677 if (an == null)
678 return false;
679 int match = 0;
680 for (GeneralName name : altNames)
682 for (List<?> list : an)
686 Integer id = (Integer) list.get(0);
687 Object val = list.get(1);
688 GeneralName n = null;
689 if (val instanceof String)
690 n = makeName(id, (String) val);
691 else if (val instanceof byte[])
693 n = new GeneralName(GeneralName.Kind.forTag(id),
694 (byte[]) val);
696 else
697 continue;
698 if (name.equals(n))
699 match++;
701 catch (Exception e)
703 continue;
706 if (match == 0 || (matchAllNames && match < altNames.size()))
707 return false;
710 if (nameConstraints != null)
712 byte[] nc = cert.getExtensionValue(NAME_CONSTRAINTS_ID);
713 if (!Arrays.equals(nameConstraints, nc))
714 return false;
717 if (policy != null)
719 CertificatePolicies policies = null;
720 if (cert instanceof GnuPKIExtension)
722 policies = (CertificatePolicies)
723 ((GnuPKIExtension) cert).getExtension(CertificatePolicies.ID).getValue();
725 else
727 byte[] policiesDer =
728 cert.getExtensionValue(CertificatePolicies.ID.toString());
731 policies = new CertificatePolicies(policiesDer);
733 catch (IOException ioe)
735 // ignored
739 if (policies == null)
740 return false;
741 if (!policies.getPolicies().containsAll(policy))
742 return false;
745 if (pathToNames != null)
747 NameConstraints nc = null;
748 if (cert instanceof GnuPKIExtension)
750 Extension e =
751 ((GnuPKIExtension) cert).getExtension(NameConstraints.ID);
752 if (e != null)
753 nc = (NameConstraints) e.getValue();
755 else
757 byte[] b = cert.getExtensionValue(NameConstraints.ID.toString());
758 if (b != null)
762 nc = new NameConstraints(b);
764 catch (IOException ioe)
770 if (nc == null)
771 return false;
773 int match = 0;
774 for (GeneralName name : pathToNames)
776 for (GeneralSubtree subtree : nc.permittedSubtrees())
778 if (name.equals(subtree.base()))
779 match++;
782 if (match == 0 || (matchAllNames && match < pathToNames.size()))
783 return false;
786 return true;
790 * Sets the authority key identifier criterion, or <code>null</code> to clear
791 * this criterion. Note that the byte array is cloned to prevent modification.
793 * @param authKeyId The authority key identifier.
795 public void setAuthorityKeyIdentifier(byte[] authKeyId)
797 this.authKeyId = authKeyId != null ? (byte[]) authKeyId.clone() : null;
801 * Sets the basic constraints criterion. Specify -1 to clear this parameter.
803 * @param basicConstraints The new basic constraints value.
805 public void setBasicConstraints(int basicConstraints)
807 if (basicConstraints < -1)
808 basicConstraints = -1;
809 this.basicConstraints = basicConstraints;
813 * Sets the certificate criterion. If set, only certificates that are
814 * equal to the certificate passed here will be accepted.
816 * @param cert The certificate.
818 public void setCertificate(X509Certificate cert)
820 this.cert = cert;
824 * Sets the date at which certificates must be valid. Specify
825 * <code>null</code> to clear this criterion.
827 * @param certValid The certificate validity date.
829 public void setCertificateValid(Date certValid)
831 this.certValid = certValid != null ? (Date) certValid.clone() : null;
835 * Sets the extended key usage criterion, as a set of OID strings. Specify
836 * <code>null</code> to clear this value.
838 * @param keyPurposeSet The set of key purpose OIDs.
839 * @throws IOException If any element of the set is not a valid OID string.
841 public void setExtendedKeyUsage(Set<String> keyPurposeSet) throws IOException
843 if (keyPurposeSet == null)
845 this.keyPurposeSet = null;
846 return;
848 Set<String> s = new HashSet<String>();
849 for (Iterator it = keyPurposeSet.iterator(); it.hasNext(); )
851 Object o = it.next();
852 if (!(o instanceof String))
853 throw new IOException("not a string: " + o);
856 OID oid = new OID((String) o);
857 int[] comp = oid.getIDs();
858 if (!checkOid(comp))
859 throw new IOException("malformed OID: " + o);
861 catch (IllegalArgumentException iae)
863 IOException ioe = new IOException("malformed OID: " + o);
864 ioe.initCause(iae);
865 throw ioe;
868 this.keyPurposeSet = s;
872 * Sets the issuer, specified as the DER encoding of the issuer's
873 * distinguished name. Only certificates issued by this issuer will
874 * be accepted.
876 * @param name The DER encoding of the issuer's distinguished name.
877 * @throws IOException If the given name is incorrectly formatted.
879 public void setIssuer(byte[] name) throws IOException
881 if (name != null)
885 issuer = new X500Principal(name);
887 catch (IllegalArgumentException iae)
889 throw new IOException(iae.getMessage());
892 else
893 issuer = null;
897 * Sets the issuer, specified as a string representation of the issuer's
898 * distinguished name. Only certificates issued by this issuer will
899 * be accepted.
901 * @param name The string representation of the issuer's distinguished name.
902 * @throws IOException If the given name is incorrectly formatted.
904 public void setIssuer(String name) throws IOException
906 if (name != null)
910 issuer = new X500Principal(name);
912 catch (IllegalArgumentException iae)
914 throw new IOException(iae.getMessage());
917 else
918 issuer = null;
922 * Sets the public key usage criterion. Specify <code>null</code> to clear
923 * this value.
925 * @param keyUsage The public key usage.
927 public void setKeyUsage(boolean[] keyUsage)
929 this.keyUsage = keyUsage != null ? (boolean[]) keyUsage.clone() : null;
933 * Sets whether or not all subject alternative names must be matched.
934 * If false, then a certificate will be considered a match if one
935 * alternative name matches.
937 * @param matchAllNames Whether or not all alternative names must be
938 * matched.
940 public void setMatchAllSubjectAltNames(boolean matchAllNames)
942 this.matchAllNames = matchAllNames;
946 * Sets the name constraints criterion; specify <code>null</code> to
947 * clear this criterion. Note that if non-null, the argument will be
948 * cloned to prevent modification.
950 * @param nameConstraints The new name constraints.
951 * @throws IOException If the argument is not a valid DER-encoded
952 * name constraints.
954 public void setNameConstraints(byte[] nameConstraints)
955 throws IOException
957 // Check if the input is well-formed...
958 new NameConstraints(nameConstraints);
960 // But we just compare raw byte arrays.
961 this.nameConstraints = nameConstraints != null
962 ? (byte[]) nameConstraints.clone() : null;
966 * Sets the pathToNames criterion. The argument is a collection of
967 * pairs, the first element of which is an {@link Integer} giving
968 * the ID of the name, and the second element is either a {@link String}
969 * or a byte array.
971 * See {@link #addPathToName(int, byte[])} and {@link #addPathToName(int, String)}
972 * for how these arguments are handled.
974 * @param names The names.
975 * @throws IOException If any argument is malformed.
977 public void setPathToNames(Collection<List<?>> names) throws IOException
979 if (names == null || names.size() == 0)
981 pathToNames = null;
983 else
985 pathToNames = new ArrayList<GeneralName>(names.size());
986 for (List<?> name : names)
988 Integer id = (Integer) name.get(0);
989 Object name2 = name.get(1);
990 if (name2 instanceof String)
991 addPathToName(id, (String) name2);
992 else if (name2 instanceof byte[])
993 addPathToName(id, (byte[]) name2);
994 else
995 throw new IOException("invalid name type: "
996 + name2.getClass().getName());
1002 * Sets the certificate policy to match, or null if this criterion should
1003 * not be checked. Each element if the set must be a dotted-decimal form
1004 * of certificate policy object identifier.
1006 * @param policy The policy to match.
1007 * @throws IOException If some element of the policy is not a valid
1008 * policy extenison OID.
1010 public void setPolicy(Set<String> policy) throws IOException
1012 if (policy != null)
1014 HashSet<OID> p = new HashSet<OID>(policy.size());
1015 for (String s : policy)
1019 OID oid = new OID(s);
1020 int[] i = oid.getIDs();
1021 if (!checkOid(i))
1022 throw new IOException("invalid OID");
1023 p.add(oid);
1025 catch (IOException ioe)
1027 throw ioe;
1029 catch (Exception x)
1031 IOException ioe = new IOException("invalid OID");
1032 ioe.initCause(x);
1033 throw ioe;
1036 this.policy = p;
1038 else
1039 this.policy = null;
1043 * This method, and its related X.509 certificate extension &mdash; the
1044 * private key usage period &mdash; is not supported under the Internet
1045 * PKI for X.509 certificates (PKIX), described in RFC 3280. As such, this
1046 * method is not supported either.
1048 * <p>Do not use this method. It is not deprecated, as it is not deprecated
1049 * in the Java standard, but it is basically a no-operation.
1051 * @param UNUSED Is silently ignored.
1053 public void setPrivateKeyValid(Date UNUSED)
1058 * Sets the serial number of the desired certificate. Only certificates that
1059 * contain this serial number are accepted.
1061 * @param serialNo The serial number.
1063 public void setSerialNumber(BigInteger serialNo)
1065 this.serialNo = serialNo;
1069 * Sets the subject, specified as the DER encoding of the subject's
1070 * distinguished name. Only certificates with the given subject will
1071 * be accepted.
1073 * @param name The DER encoding of the subject's distinguished name.
1074 * @throws IOException If the given name is incorrectly formatted.
1076 public void setSubject(byte[] name) throws IOException
1078 if (name != null)
1082 subject = new X500Principal(name);
1084 catch (IllegalArgumentException iae)
1086 throw new IOException(iae.getMessage());
1089 else
1090 subject = null;
1094 * Sets the subject, specified as a string representation of the
1095 * subject's distinguished name. Only certificates with the given
1096 * subject will be accepted.
1098 * @param name The string representation of the subject's distinguished name.
1099 * @throws IOException If the given name is incorrectly formatted.
1101 public void setSubject(String name) throws IOException
1103 if (name != null)
1107 subject = new X500Principal(name);
1109 catch (IllegalArgumentException iae)
1111 throw new IOException(iae.getMessage());
1114 else
1115 subject = null;
1119 * Sets the subject alternative names critertion. Each element of the
1120 * argument must be a {@link java.util.List} that contains exactly two
1121 * elements: the first an {@link Integer}, representing the type of
1122 * name, and the second either a {@link String} or a byte array,
1123 * representing the name itself.
1125 * @param altNames The alternative names.
1126 * @throws IOException If any element of the argument is invalid.
1128 public void setSubjectAlternativeNames(Collection<List<?>> altNames)
1129 throws IOException
1131 if (altNames == null || altNames.isEmpty())
1133 this.altNames = null;
1134 return;
1136 List<GeneralName> l = new ArrayList<GeneralName>(altNames.size());
1137 for (List<?> list : altNames)
1139 Integer id = (Integer) list.get(0);
1140 Object value = list.get(1);
1141 GeneralName name = null;
1142 if (value instanceof String)
1143 name = makeName(id, (String) value);
1144 else if (value instanceof byte[])
1145 name = new GeneralName(GeneralName.Kind.forTag(id), (byte[]) value);
1146 else
1147 throw new IOException("invalid name type: " + value.getClass().getName());
1148 l.add(name);
1150 this.altNames = l;
1154 * Sets the subject key identifier criterion, or <code>null</code> to clear
1155 * this criterion. Note that the byte array is cloned to prevent modification.
1157 * @param subjectKeyId The subject key identifier.
1159 public void setSubjectKeyIdentifier(byte[] subjectKeyId)
1161 this.subjectKeyId = subjectKeyId != null ? (byte[]) subjectKeyId.clone() :
1162 null;
1166 * Sets the subject public key criterion as a DER-encoded key. Specify
1167 * <code>null</code> to clear this value.
1169 * @param key The DER-encoded key bytes.
1170 * @throws IOException If the argument is not a valid DER-encoded key.
1172 public void setSubjectPublicKey(byte[] key) throws IOException
1174 if (key == null)
1176 subjectKey = null;
1177 subjectKeySpec = null;
1178 return;
1182 subjectKeySpec = new X509EncodedKeySpec(key);
1183 KeyFactory enc = KeyFactory.getInstance("X.509");
1184 subjectKey = enc.generatePublic(subjectKeySpec);
1186 catch (Exception x)
1188 subjectKey = null;
1189 subjectKeySpec = null;
1190 IOException ioe = new IOException(x.getMessage());
1191 ioe.initCause(x);
1192 throw ioe;
1197 * Sets the subject public key criterion as an opaque representation.
1198 * Specify <code>null</code> to clear this criterion.
1200 * @param key The public key.
1202 public void setSubjectPublicKey(PublicKey key)
1204 this.subjectKey = key;
1205 if (key == null)
1207 subjectKeySpec = null;
1208 return;
1212 KeyFactory enc = KeyFactory.getInstance("X.509");
1213 subjectKeySpec = (X509EncodedKeySpec)
1214 enc.getKeySpec(key, X509EncodedKeySpec.class);
1216 catch (Exception x)
1218 subjectKey = null;
1219 subjectKeySpec = null;
1224 * Sets the public key algorithm ID that matching certificates must have.
1225 * Specify <code>null</code> to clear this criterion.
1227 * @param sigId The public key ID.
1228 * @throws IOException If the specified ID is not a valid object identifier.
1230 public void setSubjectPublicKeyAlgID(String sigId) throws IOException
1232 if (sigId != null)
1236 OID oid = new OID(sigId);
1237 int[] comp = oid.getIDs();
1238 if (!checkOid(comp))
1239 throw new IOException("malformed OID: " + sigId);
1240 this.sigId = oid;
1242 catch (IllegalArgumentException iae)
1244 IOException ioe = new IOException("malformed OID: " + sigId);
1245 ioe.initCause(iae);
1246 throw ioe;
1249 else
1250 this.sigId = null;
1253 public String toString()
1255 CPStringBuilder str = new CPStringBuilder(X509CertSelector.class.getName());
1256 String nl = SystemProperties.getProperty("line.separator");
1257 String eol = ";" + nl;
1258 str.append(" {").append(nl);
1259 if (cert != null)
1260 str.append(" certificate = ").append(cert).append(eol);
1261 if (basicConstraints >= 0)
1262 str.append(" basic constraints = ").append(basicConstraints).append(eol);
1263 if (serialNo != null)
1264 str.append(" serial number = ").append(serialNo).append(eol);
1265 if (certValid != null)
1266 str.append(" valid date = ").append(certValid).append(eol);
1267 if (issuer != null)
1268 str.append(" issuer = ").append(issuer).append(eol);
1269 if (subject != null)
1270 str.append(" subject = ").append(subject).append(eol);
1271 if (sigId != null)
1272 str.append(" signature OID = ").append(sigId).append(eol);
1273 if (subjectKey != null)
1274 str.append(" subject public key = ").append(subjectKey).append(eol);
1275 if (subjectKeyId != null)
1277 str.append(" subject key ID = ");
1278 for (int i = 0; i < subjectKeyId.length; i++)
1280 str.append(Character.forDigit((subjectKeyId[i] & 0xF0) >>> 8, 16));
1281 str.append(Character.forDigit((subjectKeyId[i] & 0x0F), 16));
1282 if (i < subjectKeyId.length - 1)
1283 str.append(':');
1285 str.append(eol);
1287 if (authKeyId != null)
1289 str.append(" authority key ID = ");
1290 for (int i = 0; i < authKeyId.length; i++)
1292 str.append(Character.forDigit((authKeyId[i] & 0xF0) >>> 8, 16));
1293 str.append(Character.forDigit((authKeyId[i] & 0x0F), 16));
1294 if (i < authKeyId.length - 1)
1295 str.append(':');
1297 str.append(eol);
1299 if (keyUsage != null)
1301 str.append(" key usage = ");
1302 for (int i = 0; i < keyUsage.length; i++)
1303 str.append(keyUsage[i] ? '1' : '0');
1304 str.append(eol);
1306 if (keyPurposeSet != null)
1307 str.append(" key purpose = ").append(keyPurposeSet).append(eol);
1308 if (altNames != null)
1309 str.append(" alternative names = ").append(altNames).append(eol);
1310 if (nameConstraints != null)
1311 str.append(" name constraints = <blob of data>").append(eol);
1312 if (policy != null)
1313 str.append(" policy = ").append(policy).append(eol);
1314 if (pathToNames != null)
1315 str.append(" pathToNames = ").append(pathToNames).append(eol);
1316 str.append("}").append(nl);
1317 return str.toString();