X509CertSelector.java revision d21d78fd49a2d798218e8c8aefbddb26a0e71bbb
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.security.cert;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.math.BigInteger;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.PublicKey;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.CertSelector;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.cert.X509Certificate;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collection;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Collections;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Date;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashSet;
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Iterator;
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List;
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Set;
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.security.auth.x500.X500Principal;
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.asn1.ASN1OctetString;
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.internal.nls.Messages;
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.AlgorithmIdentifier;
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.CertificatePolicies;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.GeneralName;
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.GeneralNames;
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.NameConstraints;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.PolicyInformation;
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.PrivateKeyUsagePeriod;
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.x509.SubjectPublicKeyInfo;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A certificate selector ({@code CertSelector} for selecting {@code
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * X509Certificate}s that match the specified criteria.
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class X509CertSelector implements CertSelector {
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // match criteria
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private X509Certificate certificateEquals;
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private BigInteger serialNumber;
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private X500Principal issuer;
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private X500Principal subject;
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] subjectKeyIdentifier;
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] authorityKeyIdentifier;
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Date certificateValid;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String subjectPublicKeyAlgID;
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Date privateKeyValid;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] subjectPublicKey;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean[] keyUsage;
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Set extendedKeyUsage;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean matchAllNames = true;
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private int pathLen = -1;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private List[] subjectAltNames;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private NameConstraints nameConstraints;
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private Set policies;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private ArrayList pathToNames;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // needed to avoid needless encoding/decoding work
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private PublicKey subjectPublicKeyImpl;
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String issuerName;
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] issuerBytes;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code X509CertSelector}.
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X509CertSelector() {}
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the certificate that a matching certificate must be equal to.
872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param certificate
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate to match, or null to not check this criteria.
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setCertificate(X509Certificate certificate) {
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        certificateEquals = certificate;
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the certificate that a matching certificate must be equal to.
972f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the certificate to match, or null if this criteria is not
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X509Certificate getCertificate() {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return certificateEquals;
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the serial number that a certificate must match.
1072f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param serialNumber
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the serial number to match, or {@code null} to not check the
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            serial number.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSerialNumber(BigInteger serialNumber) {
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.serialNumber = serialNumber;
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the serial number that a certificate must match.
1182f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the serial number to match, or {@code null} if the serial number
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         is not to be checked.
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public BigInteger getSerialNumber() {
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return serialNumber;
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the issuer that a certificate must match.
1282f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param issuer
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the issuer to match, or {@code null} if the issuer is not to
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            be checked.
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setIssuer(X500Principal issuer) {
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.issuer = issuer;
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.issuerName = null;
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.issuerBytes = null;
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the issuer that a certificate must match.
1412f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the issuer that a certificate must match, or {@code null} if the
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         issuer is not to be checked.
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal getIssuer() {
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return issuer;
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <b>Do not use</b>, use {@link #getIssuer()} or
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #getIssuerAsBytes()} instead. Sets the issuer that a certificate
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * must match.
1532f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param issuerName
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the issuer in a RFC 2253 format string, or {@code null} to not
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            check the issuer.
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if parsing the issuer fails.
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setIssuer(String issuerName) throws IOException {
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuerName == null) {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuer = null;
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerName = null;
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerBytes = null;
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuer = new X500Principal(issuerName);
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerName = issuerName;
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerBytes = null;
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalArgumentException e) {
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(e.getMessage());
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <b>Do not use</b>, use {@link #getIssuer()} or
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #getIssuerAsBytes()} instead. Returns the issuer that a
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * certificate must match in a RFC 2253 format string.
1802f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the issuer in a RFC 2253 format string, or {@code null} if the
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         issuer is not to be checked.
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getIssuerAsString() {
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuer == null) {
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuerName == null) {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            issuerName = issuer.getName();
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return issuerName;
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the issuer that a certificate must match.
1962f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param issuerDN
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the distinguished issuer name in ASN.1 DER encoded format, or
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code null} to not check the issuer.
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding the issuer fail.
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setIssuer(byte[] issuerDN) throws IOException {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuerDN == null) {
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            issuer = null;
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            issuer = new X500Principal(issuerDN);
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerName = null;
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.issuerBytes = new byte[issuerDN.length];
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(issuerDN, 0, this.issuerBytes, 0, issuerDN.length);
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalArgumentException e) {
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(e.getMessage());
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the issuer that a certificate must match.
2202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the distinguished issuer name in ASN.1 DER encoded format, or
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@code null} if the issuer is not to be checked.
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if encoding the issuer fails.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getIssuerAsBytes() throws IOException {
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuer == null) {
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (issuerBytes == null) {
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            issuerBytes = issuer.getEncoded();
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = new byte[issuerBytes.length];
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(issuerBytes, 0, result, 0, issuerBytes.length);
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Set the subject that a certificate must match.
2402f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subject
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject distinguished name or {@code null} to not check
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject.
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubject(X500Principal subject) {
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.subject = subject;
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the subject that a certificate must match.
2512f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subject distinguished name, or null if the subject is not to
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         be checked.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public X500Principal getSubject() {
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subject;
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <b>Do not use</b>, use {@link #setSubject(byte[])} or
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #setSubject(X500Principal)} instead. Returns the subject that a
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * certificate must match.
2632f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subjectDN
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject distinguished name in RFC 2253 format or {@code
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            null} to not check the subject.
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding the subject fails.
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubject(String subjectDN) throws IOException {
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectDN == null) {
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subject = null;
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subject = new X500Principal(subjectDN);
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalArgumentException e) {
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(e.getMessage());
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <b>Do not use</b>, use {@link #getSubject()} or
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #getSubjectAsBytes()} instead. Returns the subject that a
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * certificate must match.
2862f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subject distinguished name in RFC 2253 format, or {@code
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         null} if the subject is not to be checked.
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getSubjectAsString() {
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subject == null) {
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subject.getName();
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the subject that a certificate must match.
2992f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subjectDN
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject distinguished name in ASN.1 DER format, or {@code
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            null} to not check the subject.
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding the subject fails.
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubject(byte[] subjectDN) throws IOException {
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectDN == null) {
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subject = null;
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subject = new X500Principal(subjectDN);
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IllegalArgumentException e) {
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException(e.getMessage());
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the subject that a certificate must match.
3202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subject distinguished name in ASN.1 DER format, or {@code
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         null} if the subject is not to be checked.
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if encoding the subject fails.
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getSubjectAsBytes() throws IOException {
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subject == null) {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subject.getEncoded();
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the {@literal SubjectKeyIdentifier} extension.
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The {@code subjectKeyIdentifier} should be a single DER encoded value.
3372f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param subjectKeyIdentifier
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject key identifier or {@code null} to disable this
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            check.
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubjectKeyIdentifier(byte[] subjectKeyIdentifier) {
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectKeyIdentifier == null) {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.subjectKeyIdentifier = null;
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.subjectKeyIdentifier = new byte[subjectKeyIdentifier.length];
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(subjectKeyIdentifier, 0, this.subjectKeyIdentifier, 0,
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         subjectKeyIdentifier.length);
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the {@literal SubjectKeyIdentifier} extension.
3542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subject key identifier or {@code null} if it is not to be
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getSubjectKeyIdentifier() {
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectKeyIdentifier == null) {
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] res = new byte[subjectKeyIdentifier.length];
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(subjectKeyIdentifier, 0, res, 0, res.length);
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return res;
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the {@literal AuthorityKeyIdentifier} extension.
3692f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param authorityKeyIdentifier
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the authority key identifier, or {@code null} to disable this
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            check.
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setAuthorityKeyIdentifier(byte[] authorityKeyIdentifier) {
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (authorityKeyIdentifier == null) {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.authorityKeyIdentifier = null;
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.authorityKeyIdentifier = new byte[authorityKeyIdentifier.length];
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(authorityKeyIdentifier, 0,
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         this.authorityKeyIdentifier, 0,
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                         authorityKeyIdentifier.length);
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the {@literal AuthorityKeyIdentifier}
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * extension.
3882f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the authority key identifier, or {@code null} if it is not to be
390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getAuthorityKeyIdentifier() {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (authorityKeyIdentifier == null) {
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] res = new byte[authorityKeyIdentifier.length];
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(authorityKeyIdentifier, 0, res, 0, res.length);
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return res;
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the validity date of the certificate.
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The certificate must be valid at the specified date.
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param certificateValid
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the validity date or {@code null} to not check the date.
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setCertificateValid(Date certificateValid) {
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.certificateValid = (certificateValid == null)
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? null
411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : (Date) certificateValid.clone();
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the validity date of the certificate.
4162f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the validity date or {@code null} if the date is not to be
418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getCertificateValid() {
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (certificateValid == null)
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? null
423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : (Date) certificateValid.clone();
424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the validity date of the private key.
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The private key must be valid at the specified date.
4302f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param privateKeyValid
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the validity date or {@code null} to not check the date.
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPrivateKeyValid(Date privateKeyValid) {
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (privateKeyValid == null) {
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.privateKeyValid = null;
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.privateKeyValid = (Date) privateKeyValid.clone();
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the validity date of the private key.
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The private key must be valid at the specified date.
4462f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the validity date or {@code null} if the date is not to be
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Date getPrivateKeyValid() {
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (privateKeyValid != null) {
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (Date) privateKeyValid.clone();
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return null;
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private void checkOID(String oid) throws IOException {
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int beg = 0;
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int end = oid.indexOf('.', beg);
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int comp = Integer.parseInt(oid.substring(beg, end));
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            beg = end + 1;
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((comp < 0) || (comp > 2)) {
464fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                throw new IOException(Messages.getString("security.56", oid));
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            end = oid.indexOf('.', beg);
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            comp = Integer.parseInt(oid.substring(beg, end));
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((comp < 0) || (comp > 39)) {
469fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                throw new IOException(Messages.getString("security.56", oid));
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IndexOutOfBoundsException e) {
472fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            throw new IOException(Messages.getString("security.56", oid));
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (NumberFormatException e) {
474fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            throw new IOException(Messages.getString("security.56", oid));
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the subject public key signature algorithm.
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The certificate must contain a subject public key with the algorithm
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * specified.
4832f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oid
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the OID (object identifier) of the signature algorithm or
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code null} to not check the OID.
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified object identifier is invalid.
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubjectPublicKeyAlgID(String oid) throws IOException {
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (oid == null) {
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectPublicKeyAlgID = null;
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        checkOID(oid);
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectPublicKeyAlgID = oid;
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the subject public key signature algorithm.
5012f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the OID (object identifier) or the signature algorithm or {@code
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         null} if it's not to be checked.
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String getSubjectPublicKeyAlgID() {
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subjectPublicKeyAlgID;
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the subject public key.
5112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject public key or {@code null} to not check the key.
514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubjectPublicKey(PublicKey key) {
516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectPublicKey = (key == null) ? null : key.getEncoded();
517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectPublicKeyImpl = key;
518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the subject public key.
5222f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the subject public key in ASN.1 DER encoded format or {@code null} to
525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            not check the key.
526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding the the public key fails.
528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubjectPublicKey(byte[] key) throws IOException {
530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null) {
531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectPublicKey = null;
532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectPublicKeyImpl = null;
533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectPublicKey = new byte[key.length];
536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(key, 0, subjectPublicKey, 0, key.length);
537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectPublicKeyImpl =
538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ((SubjectPublicKeyInfo) SubjectPublicKeyInfo.ASN1.decode(key))
539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            .getPublicKey();
540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the subject public key.
5442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the subject public key or {@code null} if the key is not to be
546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public PublicKey getSubjectPublicKey() {
549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return subjectPublicKeyImpl;
550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the {@literal KeyUsage} extension.
5542f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keyUsage
556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the boolean array in the format as returned by
557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@link X509Certificate#getKeyUsage()}, or {@code null} to not
558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            check the key usage.
559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setKeyUsage(boolean[] keyUsage) {
561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (keyUsage == null) {
562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.keyUsage = null;
563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.keyUsage = new boolean[keyUsage.length];
566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(keyUsage, 0, this.keyUsage, 0, keyUsage.length);
567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the {@literal KeyUsage} extension.
5712f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the boolean array in the format as returned by
573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         {@link X509Certificate#getKeyUsage()}, or {@code null} if the key
574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         usage is not to be checked.
575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean[] getKeyUsage() {
577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (keyUsage == null) {
578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        boolean[] result = new boolean[keyUsage.length];
581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(keyUsage, 0, result, 0, keyUsage.length);
582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the {@literal ExtendedKeyUsage} extension.
5872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param keyUsage
589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the set of key usage OIDs, or {@code null} to not check it.
590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if one of the OIDs is invalid.
592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setExtendedKeyUsage(Set<String> keyUsage)
594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                             throws IOException {
595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        extendedKeyUsage = null;
596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((keyUsage == null) || (keyUsage.size() == 0)) {
597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        HashSet key_u = new HashSet();
600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator it = keyUsage.iterator();
601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String usage = (String) it.next();
603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkOID(usage);
604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            key_u.add(usage);
605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        extendedKeyUsage = Collections.unmodifiableSet(key_u);
607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the {@literal ExtendedKeyUsage} extension.
6112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the set of key usage OIDs, or {@code null} if it's not to be
613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         checked.
614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<String> getExtendedKeyUsage() {
616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return extendedKeyUsage;
617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the flag for the matching behavior for subject alternative names.
621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The flag indicates whether a certificate must contain all or at least one
6232f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * of the subject alternative names specified by {@link
6242f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}.
6252f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param matchAllNames
627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            {@code true} if a certificate must contain all of the
628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            specified subject alternative names, otherwise {@code false}.
629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setMatchAllSubjectAltNames(boolean matchAllNames) {
631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.matchAllNames = matchAllNames;
632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the flag for the matching behavior for subject alternative names.
636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The flag indicates whether a certificate must contain all or at least one
6382f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * of the subject alternative names specified by {@link
6392f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     * #setSubjectAlternativeNames} or {@link #addSubjectAlternativeName}.
6402f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if a certificate must contain all of the specified
642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         subject alternative names, otherwise {@code false}.
643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean getMatchAllSubjectAltNames() {
645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return matchAllNames;
646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for subject alternative names.
650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the certificate must contain all or at least one of the specified subject
652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * alternative names. The behavior is specified by
653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #getMatchAllSubjectAltNames}.
654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The specified parameter {@code names} is a collection with an entry for
656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * each name to be included in the criterion. The name is specified as a
657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code List}, the first entry must be an {@code Integer} specifying the
658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name type (0-8), the second entry must be a {@code String} or a byte
659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array specifying the name (in string or ASN.1 DER encoded form)
6602f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param names
662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the names collection or {@code null} to not perform this check.
663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the decoding of a name fails.
665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setSubjectAlternativeNames(Collection<List<?>> names)
667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    throws IOException {
668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectAltNames = null;
669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((names == null) || (names.size() == 0)) {
670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator it = names.iterator();
673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            List name = (List) it.next();
675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int tag = ((Integer) name.get(0)).intValue();
676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object value = name.get(1);
677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (value instanceof String) {
678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                addSubjectAlternativeName(tag, (String) value);
679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (value instanceof byte[]) {
680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                addSubjectAlternativeName(tag, (byte[]) value);
681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
682fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                throw new IOException(Messages.getString("security.57"));
683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Adds a subject alternative name to the respective criterion.
6892f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tag
691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the name
692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name in string format.
694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if parsing the name fails.
696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void addSubjectAlternativeName(int tag, String name)
698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                       throws IOException {
699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        GeneralName alt_name = new GeneralName(tag, name);
700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // create only if there was not any errors
701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames == null) {
702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectAltNames = new ArrayList[9];
703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames[tag] == null) {
705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectAltNames[tag] = new ArrayList();
706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectAltNames[tag].add(alt_name);
708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Adds a subject alternative name to the respective criterion.
7122f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param tag
714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the name.
715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name in ASN.1 DER encoded form.
717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the decoding of the name fails.
719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void addSubjectAlternativeName(int tag, byte[] name)
721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                            throws IOException {
722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        GeneralName alt_name = new GeneralName(tag, name);
723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // create only if there was not any errors
724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames == null) {
725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectAltNames = new ArrayList[9];
726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames[tag] == null) {
728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            subjectAltNames[tag] = new ArrayList();
729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        subjectAltNames[tag].add(alt_name);
731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for subject alternative names.
735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the certificate must contain all or at least one of the specified subject
737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * alternative names. The behavior is specified by
738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #getMatchAllSubjectAltNames}.
739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The subject alternative names is a collection with an entry for each name
741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * included in the criterion. The name is specified as a {@code List}, the
742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * first entry is an {@code Integer} specifying the name type (0-8), the
743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * second entry is byte array specifying the name in ASN.1 DER encoded form)
7442f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the names collection or {@code null} if none specified.
746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Collection<List<?>> getSubjectAlternativeNames() {
748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames == null) {
749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ArrayList result = new ArrayList();
752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int tag=0; tag<9; tag++) {
753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (subjectAltNames[tag] != null) {
754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int name=0; name<subjectAltNames[tag].size(); name++) {
755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    Object neim = subjectAltNames[tag].get(name);
756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (neim instanceof byte[]) {
757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        byte[] arr_neim = (byte[]) neim;
758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        neim = new byte[arr_neim.length];
759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        System.arraycopy(arr_neim, 0, neim, 0, arr_neim.length);
760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    List list = new ArrayList(2);
762a0a4196cb15480959f053d0ebe6b412bd23c8170Elliott Hughes                    list.add(Integer.valueOf(tag)); // android-changed
763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    list.add(neim);
764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.add(list);
765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the name constraints.
773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The certificate must constraint subject and subject alternative names
775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * that match the specified name constraints.
776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The name constraints in ASN.1:
7782f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <pre>
780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * NameConstraints ::= SEQUENCE {
781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
7832f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
7852f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * GeneralSubtree ::= SEQUENCE {
787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        base                    GeneralName,
788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        minimum         [0]     BaseDistance DEFAULT 0,
789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        maximum         [1]     BaseDistance OPTIONAL }
7902f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * BaseDistance ::= INTEGER (0..MAX)
7922f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * GeneralName ::= CHOICE {
794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        otherName                       [0]     OtherName,
795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        rfc822Name                      [1]     IA5String,
796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        dNSName                         [2]     IA5String,
797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        x400Address                     [3]     ORAddress,
798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        directoryName                   [4]     Name,
799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        ediPartyName                    [5]     EDIPartyName,
800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        uniformResourceIdentifier       [6]     IA5String,
801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        iPAddress                       [7]     OCTET STRING,
802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *        registeredID                    [8]     OBJECT IDENTIFIER}
8032f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * </pre>
8052f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param bytes
807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name constraints in ASN.1 DER encoded format, or null to
808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            not check any constraints.
809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding the name constraints fail.
811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setNameConstraints(byte[] bytes) throws IOException {
813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.nameConstraints = (bytes == null)
814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? null
815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : (NameConstraints) NameConstraints.ASN1.decode(bytes);
816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the name constraints.
8202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name constraints or {@code null} if none specified.
822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setNameConstraints
823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public byte[] getNameConstraints() {
825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return (nameConstraints == null)
826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? null
827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : nameConstraints.getEncoded();
828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the basic constraints extension.
832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A value greater than or equal to zero indicates that a certificate must
834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * include a basic constraints extension with a path length of a least that
835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value. A value of {@code -2} indicates that only end-entity certificates
836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * are accepted. A value of {@code -1} indicates that no check is done.
8372f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param pathLen
839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the value specifying the criterion.
840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code pathLen} is less than {@code -2}.
842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setBasicConstraints(int pathLen) {
844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathLen < -2) {
845fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            throw new IllegalArgumentException(Messages.getString("security.58"));
846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.pathLen = pathLen;
848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the basic constraints extension.
852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * A value greater than or equal to zero indicates that a certificate must
854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * include a basic constraints extension with a path length of a least that
855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * value. A value of {@code -2} indicates that only end-entity certificates
856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * are accepted. A value of {@code -1} indicates that no check is done.
8572f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the value of the criterion.
859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public int getBasicConstraints() {
861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return pathLen;
862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the policy constraint.
866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The certificate must have at least one of the specified certificate
868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * policy extensions. For an empty set the certificate must have at least
869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * some policies in its policy extension.
8702f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param policies
872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate policy OIDs, an empty set, or {@code null} to
873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            not perform this check.
874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if parsing the specified OIDs fails.
876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPolicy(Set<String> policies) throws IOException {
878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (policies == null) {
879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.policies = null;
880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        HashSet pols = new HashSet(policies.size());
883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator it = policies.iterator();
884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String certPolicyId = (String) it.next();
886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            checkOID(certPolicyId);
887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            pols.add(certPolicyId);
888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.policies = Collections.unmodifiableSet(pols);
890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the policy constraint.
894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The certificate must have at least one of the certificate policy
896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * extensions. For an empty set the certificate must have at least some
897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * policies in its policy extension.
8982f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
899adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the certificate policy OIDs, an empty set, or {@code null} if not
900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         to be checked.
901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Set<String> getPolicy() {
903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return policies;
904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Sets the criterion for the pathToNames constraint.
908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
909adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This allows to specify the complete set of names, a certificate's name
910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * constraints must permit.
911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The specified parameter {@code names} is a collection with an entry for
913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * each name to be included in the criterion. The name is specified as a
914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code List}, the first entry must be an {@code Integer} specifying the
915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * name type (0-8), the second entry must be a {@code String} or a byte
916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * array specifying the name (in string or ASN.1 DER encoded form)
9172f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param names
919adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the names collection or {@code null} to not perform this
920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            check.
921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding fails.
923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void setPathToNames(Collection<List<?>> names)
925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                        throws IOException {
926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pathToNames = null;
927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((names == null) || (names.size() == 0)) {
928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator it = names.iterator();
931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            List name = (List) it.next();
933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int tag = ((Integer) name.get(0)).intValue();
934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            Object value = name.get(1);
935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (value instanceof String) {
936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                addPathToName(tag, (String) value);
937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else if (value instanceof byte[]) {
938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                addPathToName(tag, (byte[]) value);
939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
940fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                throw new IOException(Messages.getString("security.57"));
941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
944adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Adds a {@literal "pathToName"} to the respective criterion.
9472f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the name.
950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name in string format.
952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if parsing fails.
954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setPathToNames
955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void addPathToName(int type, String name) throws IOException {
957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        GeneralName path_name = new GeneralName(type, name);
958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // create only if there was not any errors
959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathToNames == null) {
960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            pathToNames = new ArrayList();
961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
962adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pathToNames.add(path_name);
963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Adds a {@literal "pathToName"} to the respective criterion.
9672f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param type
969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the type of the name
970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param name
971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name in ASN.1 DER encoded form.
972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if decoding fails.
974adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @see #setPathToNames
975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void addPathToName(int type, byte[] name) throws IOException {
977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        GeneralName path_name= new GeneralName(type, name);
978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // create only if there was not any errors
979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathToNames == null) {
980adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            pathToNames = new ArrayList();
981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        pathToNames.add(path_name);
983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the criterion for the pathToNames constraint.
987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
988adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The constraint is a collection with an entry for each name to be included
989adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * in the criterion. The name is specified as a {@code List}, the first
990adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * entry is an {@code Integer} specifying the name type (0-8), the second
991adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * entry is a byte array specifying the name in ASN.1 DER encoded form.
9922f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
993adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the pathToNames constraint or {@code null} if none specified.
994adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
995adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Collection<List<?>> getPathToNames() {
996adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathToNames == null) {
997adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
998adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
999adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ArrayList result = new ArrayList();
1000adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Iterator it = pathToNames.iterator();
1001adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (it.hasNext()) {
1002adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            GeneralName name = (GeneralName) it.next();
1003adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.add(name.getAsList());
1004adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1005adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1006adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1007adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1008adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1009adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a string representation of this {@code X509CertSelector}
1010adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * instance.
10112f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
1012adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a string representation of this {@code X509CertSelector}
1013adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         instance.
1014adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1015adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
1016adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // For convenient reading of the string representation
1017adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // all of the fields named according to the rfc 3280
1018adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // (http://www.ietf.org/rfc/rfc3280.txt).
1019adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10202f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        StringBuilder result = new StringBuilder();
1021fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes        result.append("X509CertSelector: \n[");
1022adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.certificateEquals != null) {
1023fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  certificateEquals: " + certificateEquals);
1024adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1025adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.serialNumber != null) {
1026adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            //FIXME: needs DRL's BigInteger.toString implementation
1027adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            //result.append("\n  serialNumber: " + serialNumber);
1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1029adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.issuer != null) {
1030fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  issuer: " + issuer);
1031adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1032adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subject != null) {
1033fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  subject: " + subject);
1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectKeyIdentifier != null) {
1036fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  subjectKeyIdentifier: "
1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + getBytesAsString(subjectKeyIdentifier));
1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.authorityKeyIdentifier != null) {
1040fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  authorityKeyIdentifier: "
1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + getBytesAsString(authorityKeyIdentifier));
1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.certificateValid != null) {
1044fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  certificateValid: " + certificateValid);
1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectPublicKeyAlgID != null) {
1047fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  subjectPublicKeyAlgID: "
1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + subjectPublicKeyAlgID);
1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.privateKeyValid != null) {
1051fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  privateKeyValid: " + privateKeyValid);
1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectPublicKey != null) {
1054fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  subjectPublicKey: "
1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + getBytesAsString(subjectPublicKey));
1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.keyUsage != null) {
1058fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  keyUsage: \n  [");
1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String[] kuNames = new String[] {
1060fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                "digitalSignature", "nonRepudiation", "keyEncipherment",
1061fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                "dataEncipherment", "keyAgreement", "keyCertSign", "cRLSign",
1062fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                "encipherOnly", "decipherOnly"
1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            };
1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<9; i++) {
1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (keyUsage[i]) {
1066fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                    result.append("\n    " + kuNames[i]);
1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1069fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  ]");
1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.extendedKeyUsage != null) {
1072fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  extendedKeyUsage: "
1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + extendedKeyUsage.toString());
1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1075fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes        result.append("\n  matchAllNames: " + matchAllNames);
1076fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes        result.append("\n  pathLen: " + pathLen);
1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectAltNames != null) {
1078fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  subjectAltNames:  \n  [");
1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<9; i++) {
1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                List names = this.subjectAltNames[i];
1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (names != null) {
1082adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    int size = names.size();
1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int j=0; j<size; j++) {
1084fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                        result.append("\n    "
1085adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            + ((GeneralName)names.get(j)).toString());
1086adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1087adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1088adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1089fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  ]");
1090adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1091adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.nameConstraints != null) {
1092adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1093adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.policies != null) {
1094fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  policies: " + policies.toString());
1095adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1096adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.pathToNames != null) {
1097fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result.append("\n  pathToNames:  \n  [");
1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int size = pathToNames.size();
1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i = 0; i < size; i++) {
1100fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                result.append("\n    "
1101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    + ((GeneralName)pathToNames.get(i)).toString());
1102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1104fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes        result.append("\n]");
1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result.toString();
1106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private String getBytesAsString(byte[] data) {
1109fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes        String result = "";
1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        for (int i=0; i<data.length; i++) {
1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String tail = Integer.toHexString(0x00ff & data[i]);
1112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (tail.length() == 1) {
1113fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                tail = "0" + tail;
1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1115fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            result += tail + " ";
1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private byte[] getExtensionValue(X509Certificate cert, String oid) {
1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            byte[] bytes = cert.getExtensionValue(oid);
1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bytes == null) {
1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return null;
1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return (byte[]) ASN1OctetString.getInstance().decode(bytes);
1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (IOException e) {
1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return null;
1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns whether the specified certificate matches all the criteria
1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * collected in this instance.
11352f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param certificate
1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the certificate to check.
1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return {@code true} if the certificate matches all the criteria,
1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *         otherwise {@code false}.
1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public boolean match(Certificate certificate) {
1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (! (certificate instanceof X509Certificate)) {
1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        X509Certificate cert = (X509Certificate) certificate;
1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((certificateEquals != null) &&
1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !certificateEquals.equals(cert)) {
1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((serialNumber != null) &&
1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !serialNumber.equals(cert.getSerialNumber())) {
1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((issuer != null) &&
1156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !issuer.equals(cert.getIssuerX500Principal())) {
1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((subject != null) &&
1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !subject.equals(cert.getSubjectX500Principal())) {
1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((subjectKeyIdentifier != null) &&
1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !Arrays.equals(subjectKeyIdentifier,
1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Here and later all of the extension OIDs
1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // are taken from rfc 3280 (http://www.ietf.org/rfc/rfc3280.txt)
1167fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                           getExtensionValue(cert, "2.5.29.14"))) {
1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((authorityKeyIdentifier != null) &&
1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            !Arrays.equals(authorityKeyIdentifier,
1172fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                           getExtensionValue(cert, "2.5.29.35"))) {
1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return false;
1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (certificateValid != null) {
1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                cert.checkValidity(certificateValid);
1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch(CertificateExpiredException e) {
1179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch(CertificateNotYetValidException e) {
1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (privateKeyValid != null) {
1185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1186fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                byte[] bytes = getExtensionValue(cert, "2.5.29.16");
1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (bytes == null) {
1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                PrivateKeyUsagePeriod pkup = (PrivateKeyUsagePeriod)
1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                    PrivateKeyUsagePeriod.ASN1.decode(bytes);
1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Date notBefore = pkup.getNotBefore();
1193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Date notAfter = pkup.getNotAfter();
1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((notBefore == null) && (notAfter == null)) {
1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((notBefore != null)
1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && notBefore.compareTo(privateKeyValid) > 0) {
1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((notAfter != null)
1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    && notAfter.compareTo(privateKeyValid) < 0) {
1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectPublicKeyAlgID  != null) {
1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                byte[] encoding = cert.getPublicKey().getEncoded();
1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                AlgorithmIdentifier ai = ((SubjectPublicKeyInfo)
1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        SubjectPublicKeyInfo.ASN1.decode(encoding))
1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getAlgorithmIdentifier();
1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!subjectPublicKeyAlgID.equals(ai.getAlgorithm())) {
1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                e.printStackTrace();
1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectPublicKey != null) {
1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!Arrays.equals(subjectPublicKey,
1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                               cert.getPublicKey().getEncoded())) {
1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (keyUsage != null) {
1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            boolean[] ku = cert.getKeyUsage();
1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (ku != null) {
1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int i = 0;
1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                int min_length = (ku.length < keyUsage.length) ? ku.length
1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        : keyUsage.length;
1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (; i < min_length; i++) {
1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (keyUsage[i] && !ku[i]) {
1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // the specified keyUsage allows,
1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        // but certificate does not.
1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (; i<keyUsage.length; i++) {
1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (keyUsage[i]) {
1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (extendedKeyUsage != null) {
1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                List keyUsage = cert.getExtendedKeyUsage();
1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (keyUsage != null) {
1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (!keyUsage.containsAll(extendedKeyUsage)) {
1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return false;
1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (CertificateParsingException e) {
1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathLen != -1) {
1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            int p_len = cert.getBasicConstraints();
1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((pathLen < 0) && (p_len >= 0)) {
1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // need end-entity but got CA
1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if ((pathLen > 0) && (pathLen > p_len)) {
1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // allowed _pathLen is small
1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (subjectAltNames != null) {
1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            PASSED:
1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1275fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes                byte[] bytes = getExtensionValue(cert, "2.5.29.17");
1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (bytes == null) {
1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                List sans = ((GeneralNames) GeneralNames.ASN1.decode(bytes))
1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            .getNames();
1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if ((sans == null) || (sans.size() == 0)) {
1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                boolean[][] map = new boolean[9][];
1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // initialize the check map
1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int i=0; i<9; i++) {
1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    map[i] = (subjectAltNames[i] == null)
1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                ? new boolean[0]
1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                : new boolean[subjectAltNames[i].size()];
1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Iterator it = sans.iterator();
1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (it.hasNext()) {
1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    GeneralName name = (GeneralName) it.next();
1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    int tag = name.getTag();
1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int i=0; i<map[tag].length; i++) {
1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (((GeneralName) subjectAltNames[tag].get(i))
1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                                            .equals(name)) {
1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            if (!matchAllNames) {
1299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                break PASSED;
1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            }
1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            map[tag][i] = true;
1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
1303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!matchAllNames) {
1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // there was not any match
1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // else check the map
1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                for (int tag=0; tag<9; tag++) {
1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    for (int name=0; name<map[tag].length; name++) {
1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        if (!map[tag][name]) {
1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            return false;
1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        }
1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                e.printStackTrace();
1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (nameConstraints != null) {
1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!nameConstraints.isAcceptable(cert)) {
1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (policies != null) {
1328fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            byte[] bytes = getExtensionValue(cert, "2.5.29.32");
1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bytes == null) {
1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (policies.size() == 0) {
1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // if certificate has such extension than it has at least
1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // one policy in it.
1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return true;
1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            PASSED:
1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            try {
1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                List policyInformations = ((CertificatePolicies)
1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        CertificatePolicies.ASN1.decode(bytes))
1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        .getPolicyInformations();
1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Iterator it = policyInformations.iterator();
1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                while (it.hasNext()) {
1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if (policies.contains(((PolicyInformation) it.next())
1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                                          .getPolicyIdentifier())) {
1346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        break PASSED;
1347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
1348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } catch (IOException e) {
1351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // the extension is invalid
1352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                return false;
1353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (pathToNames != null) {
1356fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes            byte[] bytes = getExtensionValue(cert, "2.5.29.30");
1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (bytes != null) {
1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                NameConstraints nameConstraints;
1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                try {
1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    nameConstraints =
1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        (NameConstraints) NameConstraints.ASN1.decode(bytes);
1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } catch (IOException e) {
1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    // the extension is invalid;
1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (!nameConstraints.isAcceptable(pathToNames)) {
1367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    return false;
1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return true;
1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Clones this {@code X509CertSelector} instance.
13762f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes     *
1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the cloned instance.
1378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Object clone() {
13802f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes        X509CertSelector result;
13812f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
1382d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes        try {
1383d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes            result = (X509CertSelector) super.clone();
1384d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes        } catch (CloneNotSupportedException e) {
1385d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes            return null;
1386d21d78fd49a2d798218e8c8aefbddb26a0e71bbbElliott Hughes        }
13872f9e468ed4985edfd5e351faf2089d91e561e41dElliott Hughes
1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectKeyIdentifier != null) {
1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.subjectKeyIdentifier =
1390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                new byte[this.subjectKeyIdentifier.length];
1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(this.subjectKeyIdentifier, 0,
1392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.subjectKeyIdentifier, 0,
1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    this.subjectKeyIdentifier.length);
1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.authorityKeyIdentifier != null) {
1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.authorityKeyIdentifier =
1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                new byte[this.authorityKeyIdentifier.length];
1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(this.authorityKeyIdentifier, 0,
1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.authorityKeyIdentifier, 0,
1400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    this.authorityKeyIdentifier.length);
1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectPublicKey != null) {
1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.subjectPublicKey = new byte[this.subjectPublicKey.length];
1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(this.subjectPublicKey, 0, result.subjectPublicKey,
1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    0, this.subjectPublicKey.length);
1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.keyUsage != null) {
1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.keyUsage = new boolean[this.keyUsage.length];
1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            System.arraycopy(this.keyUsage, 0, result.keyUsage, 0,
1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    this.keyUsage.length);
1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.extendedKeyUsage = (this.extendedKeyUsage == null)
1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? null
1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : new HashSet(this.extendedKeyUsage);
1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (this.subjectAltNames != null) {
1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            result.subjectAltNames = new ArrayList[9];
1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            for (int i=0; i<9; i++) {
1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (this.subjectAltNames[i] != null) {
1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    result.subjectAltNames[i] =
1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        new ArrayList(this.subjectAltNames[i]);
1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.policies = (this.policies == null)
1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? null
1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : new HashSet(this.policies);
1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        result.pathToNames = (this.pathToNames == null)
1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            ? null
1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            : new ArrayList(this.pathToNames);
1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return result;
1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
1433