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)
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
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
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
;
69 import javax
.security
.auth
.x500
.X500Principal
;
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
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)
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
))
114 case uniformResourceIdentifier
:
115 nameBytes
= name
.getBytes("ASCII");
119 InetAddress addr
= InetAddress
.getByName(name
);
120 nameBytes
= addr
.getAddress();
124 OID oid
= new OID(name
);
125 nameBytes
= oid
.getDER();
129 X500Principal xname
= new X500Principal(name
);
130 nameBytes
= xname
.getEncoded();
136 throw new IOException("cannot decode string representation of "
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
;
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
212 * The name is a GeneralName structure, which has the ASN.1 format:
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 }
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
)
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
253 public void addSubjectAlternativeName(int id
, String name
)
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
279 * @return The authority key identifier.
281 public byte[] getAuthorityKeyIdentifier()
283 if (authKeyId
!= null)
284 return (byte[]) authKeyId
.clone();
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
303 * @return The certificate.
305 public X509Certificate
getCertificate()
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();
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
329 * @return The set of key purpose OIDs (strings).
331 public Set
<String
> getExtendedKeyUsage()
333 if (keyPurposeSet
!= null)
334 return Collections
.unmodifiableSet(keyPurposeSet
);
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
348 return issuer
.getEncoded();
354 * Returns the issuer criterion as a string, or <code>null</code> if this
357 * @return The issuer.
359 public String
getIssuerAsString()
362 return issuer
.getName();
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();
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
398 * @return The name constraints.
400 public byte[] getNameConstraints()
402 if (nameConstraints
!= null)
403 return (byte[]) nameConstraints
.clone();
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());
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
;
437 Set
<String
> strings
= new HashSet
<String
>(p
.size());
440 strings
.add(o
.toString());
448 * This method, and its related X.509 certificate extension — the
449 * private key usage period — 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>.
459 public Date
getPrivateKeyValid()
465 * Returns the serial number criterion, or <code>null</code> if this
468 * @return The serial number.
470 public BigInteger
getSerialNumber()
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());
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
510 return subject
.getEncoded();
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()
524 return subject
.getName();
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
534 * @return The subject key identifier.
536 public byte[] getSubjectKeyIdentifier()
538 if (subjectKeyId
!= null)
539 return (byte[]) subjectKeyId
.clone();
545 * Returns the subject public key criterion, or <code>null</code> if this
548 * @return The subject public key.
550 public PublicKey
getSubjectPublicKey()
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
))
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
))
588 catch (CertificateEncodingException cee
)
593 if (serialNo
!= null)
595 if (!serialNo
.equals(cert
.getSerialNumber()))
598 if (certValid
!= null)
602 cert
.checkValidity(certValid
);
604 catch (CertificateException ce
)
611 if (!issuer
.equals(cert
.getIssuerX500Principal()))
616 if (!subject
.equals(cert
.getSubjectX500Principal()))
621 if (!sigId
.toString().equals(cert
.getSigAlgOID()))
624 if (subjectKeyId
!= null)
626 byte[] b
= cert
.getExtensionValue(SUBJECT_KEY_ID
);
627 if (!Arrays
.equals(b
, subjectKeyId
))
630 if (authKeyId
!= null)
632 byte[] b
= cert
.getExtensionValue(AUTH_KEY_ID
);
633 if (!Arrays
.equals(b
, authKeyId
))
636 if (keyUsage
!= null)
638 boolean[] b
= cert
.getKeyUsage();
639 if (!Arrays
.equals(b
, keyUsage
))
642 if (basicConstraints
>= 0)
644 if (cert
.getBasicConstraints() != basicConstraints
)
647 if (keyPurposeSet
!= null)
652 kp
= cert
.getExtendedKeyUsage();
654 catch (CertificateParsingException cpe
)
660 for (Iterator it
= keyPurposeSet
.iterator(); it
.hasNext(); )
662 if (!kp
.contains(it
.next()))
666 if (altNames
!= null)
668 Collection
<List
<?
>> an
= null;
671 an
= cert
.getSubjectAlternativeNames();
673 catch (CertificateParsingException cpe
)
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
),
706 if (match
== 0 || (matchAllNames
&& match
< altNames
.size()))
710 if (nameConstraints
!= null)
712 byte[] nc
= cert
.getExtensionValue(NAME_CONSTRAINTS_ID
);
713 if (!Arrays
.equals(nameConstraints
, nc
))
719 CertificatePolicies policies
= null;
720 if (cert
instanceof GnuPKIExtension
)
722 policies
= (CertificatePolicies
)
723 ((GnuPKIExtension
) cert
).getExtension(CertificatePolicies
.ID
).getValue();
728 cert
.getExtensionValue(CertificatePolicies
.ID
.toString());
731 policies
= new CertificatePolicies(policiesDer
);
733 catch (IOException ioe
)
739 if (policies
== null)
741 if (!policies
.getPolicies().containsAll(policy
))
745 if (pathToNames
!= null)
747 NameConstraints nc
= null;
748 if (cert
instanceof GnuPKIExtension
)
751 ((GnuPKIExtension
) cert
).getExtension(NameConstraints
.ID
);
753 nc
= (NameConstraints
) e
.getValue();
757 byte[] b
= cert
.getExtensionValue(NameConstraints
.ID
.toString());
762 nc
= new NameConstraints(b
);
764 catch (IOException ioe
)
774 for (GeneralName name
: pathToNames
)
776 for (GeneralSubtree subtree
: nc
.permittedSubtrees())
778 if (name
.equals(subtree
.base()))
782 if (match
== 0 || (matchAllNames
&& match
< pathToNames
.size()))
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
)
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;
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();
859 throw new IOException("malformed OID: " + o
);
861 catch (IllegalArgumentException iae
)
863 IOException ioe
= new IOException("malformed OID: " + o
);
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
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
885 issuer
= new X500Principal(name
);
887 catch (IllegalArgumentException iae
)
889 throw new IOException(iae
.getMessage());
897 * Sets the issuer, specified as a string representation of the issuer's
898 * distinguished name. Only certificates issued by this issuer will
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
910 issuer
= new X500Principal(name
);
912 catch (IllegalArgumentException iae
)
914 throw new IOException(iae
.getMessage());
922 * Sets the public key usage criterion. Specify <code>null</code> to clear
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
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
954 public void setNameConstraints(byte[] nameConstraints
)
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}
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)
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
);
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
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();
1022 throw new IOException("invalid OID");
1025 catch (IOException ioe
)
1031 IOException ioe
= new IOException("invalid OID");
1043 * This method, and its related X.509 certificate extension — the
1044 * private key usage period — 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
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
1082 subject
= new X500Principal(name
);
1084 catch (IllegalArgumentException iae
)
1086 throw new IOException(iae
.getMessage());
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
1107 subject
= new X500Principal(name
);
1109 catch (IllegalArgumentException iae
)
1111 throw new IOException(iae
.getMessage());
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
)
1131 if (altNames
== null || altNames
.isEmpty())
1133 this.altNames
= null;
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
);
1147 throw new IOException("invalid name type: " + value
.getClass().getName());
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() :
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
1177 subjectKeySpec
= null;
1182 subjectKeySpec
= new X509EncodedKeySpec(key
);
1183 KeyFactory enc
= KeyFactory
.getInstance("X.509");
1184 subjectKey
= enc
.generatePublic(subjectKeySpec
);
1189 subjectKeySpec
= null;
1190 IOException ioe
= new IOException(x
.getMessage());
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
;
1207 subjectKeySpec
= null;
1212 KeyFactory enc
= KeyFactory
.getInstance("X.509");
1213 subjectKeySpec
= (X509EncodedKeySpec
)
1214 enc
.getKeySpec(key
, X509EncodedKeySpec
.class);
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
1236 OID oid
= new OID(sigId
);
1237 int[] comp
= oid
.getIDs();
1238 if (!checkOid(comp
))
1239 throw new IOException("malformed OID: " + sigId
);
1242 catch (IllegalArgumentException iae
)
1244 IOException ioe
= new IOException("malformed OID: " + sigId
);
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
);
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
);
1268 str
.append(" issuer = ").append(issuer
).append(eol
);
1269 if (subject
!= null)
1270 str
.append(" subject = ").append(subject
).append(eol
);
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)
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)
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');
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
);
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();