src/java.base/share/classes/sun/security/provider/X509Factory.java
author coffeys
Tue, 20 Nov 2018 13:12:48 +0000
changeset 52621 f7309a1491d9
parent 51272 9d92ff04a29c
permissions -rw-r--r--
8148188: Enhance the security libraries to record events of interest Reviewed-by: egahlin, mullan, weijun, xuelei
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
51272
9d92ff04a29c 8208602: Cannot read PEM X.509 cert if there is whitespace after the header or footer
weijun
parents: 47216
diff changeset
     2
 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5164
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5164
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5164
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5164
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5164
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.*;
52621
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
    29
import java.security.PublicKey;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.cert.*;
29596
70399c7a7f5a 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness, as jdk7 did
weijun
parents: 27091
diff changeset
    32
52621
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
    33
import jdk.internal.event.EventHelper;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
    34
import jdk.internal.event.X509CertificateEvent;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
    35
import sun.security.util.KeyUtil;
29596
70399c7a7f5a 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness, as jdk7 did
weijun
parents: 27091
diff changeset
    36
import sun.security.util.Pem;
52621
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
    37
import sun.security.x509.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.security.pkcs.PKCS7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.security.provider.certpath.X509CertPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import sun.security.provider.certpath.X509CertificatePair;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import sun.security.util.DerValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.security.util.Cache;
16020
b57c48f16179 8006182: cleanup to use java.util.Base64 in java security component, providers, and regression tests
msheppar
parents: 10786
diff changeset
    43
import java.util.Base64;
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
    44
import sun.security.pkcs.ParsingException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/**
30374
2abaf49910ea 8079478: some docs cleanup for sun.security
avstepan
parents: 29596
diff changeset
    47
 * This class defines a certificate factory for X.509 v3 certificates {@literal &}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * certification paths, and X.509 v2 certificate revocation lists (CRLs).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @author Jan Luehe
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * @author Hemma Prafullchandra
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * @author Sean Mullan
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * @see java.security.cert.CertificateFactorySpi
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * @see java.security.cert.Certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * @see java.security.cert.CertPath
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * @see java.security.cert.CRL
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * @see java.security.cert.X509Certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * @see java.security.cert.X509CRL
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * @see sun.security.x509.X509CertImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * @see sun.security.x509.X509CRLImpl
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
public class X509Factory extends CertificateFactorySpi {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    public static final String END_CERT = "-----END CERTIFICATE-----";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private static final int ENC_MAX_LENGTH = 4096 * 1024; // 4 MB MAX
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
    72
    private static final Cache<Object, X509CertImpl> certCache
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
    73
        = Cache.newSoftMemoryCache(750);
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
    74
    private static final Cache<Object, X509CRLImpl> crlCache
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
    75
        = Cache.newSoftMemoryCache(750);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * Generates an X.509 certificate object and initializes it with
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * the data read from the input stream <code>is</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * @param is an input stream with the certificate data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * @return an X.509 certificate object initialized with the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * from the input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     * @exception CertificateException on parsing errors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
    88
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    public Certificate engineGenerateCertificate(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        throws CertificateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        if (is == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            // clear the caches (for debugging)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
            certCache.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
            X509CertificatePair.clearCache();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
            throw new CertificateException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
        try {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
    99
            byte[] encoding = readOneBlock(is);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
            if (encoding != null) {
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   101
                X509CertImpl cert = getFromCache(certCache, encoding);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                if (cert != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                    return cert;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
                cert = new X509CertImpl(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
                addToCache(certCache, cert.getEncodedInternal(), cert);
52621
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   107
                // record cert details if necessary
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   108
                commitEvent(cert);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
                return cert;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            } else {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   111
                throw new IOException("Empty input");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        } catch (IOException ioe) {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   114
            throw new CertificateException("Could not parse certificate: " +
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   115
                    ioe.toString(), ioe);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * Read from the stream until length bytes have been read or EOF has
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * been reached. Return the number of bytes actually read.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     */
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   123
    private static int readFully(InputStream in, ByteArrayOutputStream bout,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            int length) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        int read = 0;
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   126
        byte[] buffer = new byte[2048];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        while (length > 0) {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   128
            int n = in.read(buffer, 0, length<2048?length:2048);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            if (n <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   132
            bout.write(buffer, 0, n);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            read += n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            length -= n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        return read;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * Return an interned X509CertImpl for the given certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * If the given X509Certificate or X509CertImpl is already present
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * in the cert cache, the cached object is returned. Otherwise,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * if it is a X509Certificate, it is first converted to a X509CertImpl.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * Then the X509CertImpl is added to the cache and returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * Note that all certificates created via generateCertificate(InputStream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * are already interned and this method does not need to be called.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * It is useful for certificates that cannot be created via
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * generateCertificate() and for converting other X509Certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     * implementations to an X509CertImpl.
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   151
     *
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   152
     * @param c The source X509Certificate
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   153
     * @return An X509CertImpl object that is either a cached certificate or a
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   154
     *      newly built X509CertImpl from the provided X509Certificate
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   155
     * @throws CertificateException if failures occur while obtaining the DER
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   156
     *      encoding for certificate data.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    public static synchronized X509CertImpl intern(X509Certificate c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            throws CertificateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        if (c == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        boolean isImpl = c instanceof X509CertImpl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        byte[] encoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        if (isImpl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            encoding = ((X509CertImpl)c).getEncodedInternal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            encoding = c.getEncoded();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        }
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   170
        X509CertImpl newC = getFromCache(certCache, encoding);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        if (newC != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            return newC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        if (isImpl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            newC = (X509CertImpl)c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            newC = new X509CertImpl(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            encoding = newC.getEncodedInternal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        addToCache(certCache, encoding, newC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        return newC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * Return an interned X509CRLImpl for the given certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * For more information, see intern(X509Certificate).
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   187
     *
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   188
     * @param c The source X509CRL
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   189
     * @return An X509CRLImpl object that is either a cached CRL or a
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   190
     *      newly built X509CRLImpl from the provided X509CRL
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   191
     * @throws CRLException if failures occur while obtaining the DER
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   192
     *      encoding for CRL data.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
    public static synchronized X509CRLImpl intern(X509CRL c)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            throws CRLException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        if (c == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        boolean isImpl = c instanceof X509CRLImpl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        byte[] encoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (isImpl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            encoding = ((X509CRLImpl)c).getEncodedInternal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            encoding = c.getEncoded();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        }
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   206
        X509CRLImpl newC = getFromCache(crlCache, encoding);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        if (newC != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            return newC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        if (isImpl) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            newC = (X509CRLImpl)c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            newC = new X509CRLImpl(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            encoding = newC.getEncodedInternal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        addToCache(crlCache, encoding, newC);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        return newC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * Get the X509CertImpl or X509CRLImpl from the cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
     */
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   223
    private static synchronized <K,V> V getFromCache(Cache<K,V> cache,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            byte[] encoding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        Object key = new Cache.EqualByteArray(encoding);
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   226
        return cache.get(key);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * Add the X509CertImpl or X509CRLImpl to the cache.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   232
    private static synchronized <V> void addToCache(Cache<Object, V> cache,
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   233
            byte[] encoding, V value) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        if (encoding.length > ENC_MAX_LENGTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        Object key = new Cache.EqualByteArray(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        cache.put(key, value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     * Generates a <code>CertPath</code> object and initializes it with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * the data read from the <code>InputStream</code> inStream. The data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * is assumed to be in the default encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
     * @param inStream an <code>InputStream</code> containing the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * @return a <code>CertPath</code> initialized with the data from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     *   <code>InputStream</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * @exception CertificateException if an exception occurs while decoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   252
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    public CertPath engineGenerateCertPath(InputStream inStream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        throws CertificateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        if (inStream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            throw new CertificateException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        try {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   260
            byte[] encoding = readOneBlock(inStream);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   261
            if (encoding != null) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   262
                return new X509CertPath(new ByteArrayInputStream(encoding));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            } else {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   264
                throw new IOException("Empty input");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            throw new CertificateException(ioe.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * Generates a <code>CertPath</code> object and initializes it with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     * the data read from the <code>InputStream</code> inStream. The data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * is assumed to be in the specified encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * @param inStream an <code>InputStream</code> containing the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * @param encoding the encoding used for the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     * @return a <code>CertPath</code> initialized with the data from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
     *   <code>InputStream</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * @exception CertificateException if an exception occurs while decoding or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     *   the encoding requested is not supported
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   284
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    public CertPath engineGenerateCertPath(InputStream inStream,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        String encoding) throws CertificateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        if (inStream == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            throw new CertificateException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        try {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   292
            byte[] data = readOneBlock(inStream);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   293
            if (data != null) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                return new X509CertPath(new ByteArrayInputStream(data), encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            } else {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   296
                throw new IOException("Empty input");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
        } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            throw new CertificateException(ioe.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
     * Generates a <code>CertPath</code> object and initializes it with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * a <code>List</code> of <code>Certificate</code>s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * The certificates supplied must be of a type supported by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * <code>CertificateFactory</code>. They will be copied out of the supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * <code>List</code> object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * @param certificates a <code>List</code> of <code>Certificate</code>s
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * @return a <code>CertPath</code> initialized with the supplied list of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     *   certificates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * @exception CertificateException if an exception occurs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   317
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    public CertPath
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        engineGenerateCertPath(List<? extends Certificate> certificates)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        throws CertificateException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        return(new X509CertPath(certificates));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * Returns an iteration of the <code>CertPath</code> encodings supported
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * by this certificate factory, with the default encoding first.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * Attempts to modify the returned <code>Iterator</code> via its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     * <code>remove</code> method result in an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
     * <code>UnsupportedOperationException</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
     * @return an <code>Iterator</code> over the names of the supported
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
     *         <code>CertPath</code> encodings (as <code>String</code>s)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
     * @since 1.4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   337
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    public Iterator<String> engineGetCertPathEncodings() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        return(X509CertPath.getEncodingsStatic());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     * Returns a (possibly empty) collection view of X.509 certificates read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
     * from the given input stream <code>is</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
     * @param is the input stream with the certificates.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
     * @return a (possibly empty) collection view of X.509 certificate objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
     * initialized with the data from the input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
     * @exception CertificateException on parsing errors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   353
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    public Collection<? extends java.security.cert.Certificate>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            engineGenerateCertificates(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            throws CertificateException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        if (is == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            throw new CertificateException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            return parseX509orPKCS7Cert(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            throw new CertificateException(ioe);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * Generates an X.509 certificate revocation list (CRL) object and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     * initializes it with the data read from the given input stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * <code>is</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     * @param is an input stream with the CRL data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * @return an X.509 CRL object initialized with the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * from the input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * @exception CRLException on parsing errors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   379
    @Override
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    public CRL engineGenerateCRL(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
        throws CRLException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        if (is == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            // clear the cache (for debugging)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            crlCache.clear();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            throw new CRLException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
        try {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   389
            byte[] encoding = readOneBlock(is);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
            if (encoding != null) {
10785
1d42311b6355 7092897: sun.security.util.Cache should be generified
mullan
parents: 9035
diff changeset
   391
                X509CRLImpl crl = getFromCache(crlCache, encoding);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                if (crl != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
                    return crl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                crl = new X509CRLImpl(encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                addToCache(crlCache, crl.getEncodedInternal(), crl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                return crl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            } else {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   399
                throw new IOException("Empty input");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            throw new CRLException(ioe.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * Returns a (possibly empty) collection view of X.509 CRLs read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * from the given input stream <code>is</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * @param is the input stream with the CRLs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     * @return a (possibly empty) collection view of X.509 CRL objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * initialized with the data from the input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     * @exception CRLException on parsing errors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     */
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   417
    @Override
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   418
    public Collection<? extends java.security.cert.CRL> engineGenerateCRLs(
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   419
            InputStream is) throws CRLException
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        if (is == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            throw new CRLException("Missing input stream");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            return parseX509orPKCS7CRL(is);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        } catch (IOException ioe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            throw new CRLException(ioe.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * Parses the data in the given input stream as a sequence of DER
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * encoded X.509 certificates (in binary or base 64 encoded format) OR
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * as a single PKCS#7 encoded blob (in binary or base64 encoded format).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    private Collection<? extends java.security.cert.Certificate>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        parseX509orPKCS7Cert(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        throws CertificateException, IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   440
        int peekByte;
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   441
        byte[] data;
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   442
        PushbackInputStream pbis = new PushbackInputStream(is);
7973
dffe8439eb20 7005608: diamond conversion of JCA and crypto providers
smarks
parents: 5627
diff changeset
   443
        Collection<X509CertImpl> coll = new ArrayList<>();
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   444
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   445
        // Test the InputStream for end-of-stream.  If the stream's
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   446
        // initial state is already at end-of-stream then return
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   447
        // an empty collection.  Otherwise, push the byte back into the
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   448
        // stream and let readOneBlock look for the first certificate.
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   449
        peekByte = pbis.read();
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   450
        if (peekByte == -1) {
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   451
            return new ArrayList<>(0);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   452
        } else {
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   453
            pbis.unread(peekByte);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   454
            data = readOneBlock(pbis);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   455
        }
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   456
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   457
        // If we end up with a null value after reading the first block
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   458
        // then we know the end-of-stream has been reached and no certificate
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   459
        // data has been found.
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   460
        if (data == null) {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   461
            throw new CertificateException("No certificate data found");
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   462
        }
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   463
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   464
        try {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   465
            PKCS7 pkcs7 = new PKCS7(data);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   466
            X509Certificate[] certs = pkcs7.getCertificates();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   467
            // certs are optional in PKCS #7
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   468
            if (certs != null) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   469
                return Arrays.asList(certs);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   470
            } else {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   471
                // no certificates provided
7973
dffe8439eb20 7005608: diamond conversion of JCA and crypto providers
smarks
parents: 5627
diff changeset
   472
                return new ArrayList<>(0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
            }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   474
        } catch (ParsingException e) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   475
            while (data != null) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   476
                coll.add(new X509CertImpl(data));
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   477
                data = readOneBlock(pbis);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        return coll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * Parses the data in the given input stream as a sequence of DER encoded
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     * X.509 CRLs (in binary or base 64 encoded format) OR as a single PKCS#7
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * encoded blob (in binary or base 64 encoded format).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    private Collection<? extends java.security.cert.CRL>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        parseX509orPKCS7CRL(InputStream is)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        throws CRLException, IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   492
        int peekByte;
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   493
        byte[] data;
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   494
        PushbackInputStream pbis = new PushbackInputStream(is);
7973
dffe8439eb20 7005608: diamond conversion of JCA and crypto providers
smarks
parents: 5627
diff changeset
   495
        Collection<X509CRLImpl> coll = new ArrayList<>();
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   496
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   497
        // Test the InputStream for end-of-stream.  If the stream's
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   498
        // initial state is already at end-of-stream then return
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   499
        // an empty collection.  Otherwise, push the byte back into the
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   500
        // stream and let readOneBlock look for the first CRL.
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   501
        peekByte = pbis.read();
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   502
        if (peekByte == -1) {
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   503
            return new ArrayList<>(0);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   504
        } else {
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   505
            pbis.unread(peekByte);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   506
            data = readOneBlock(pbis);
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   507
        }
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   508
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   509
        // If we end up with a null value after reading the first block
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   510
        // then we know the end-of-stream has been reached and no CRL
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   511
        // data has been found.
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   512
        if (data == null) {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   513
            throw new CRLException("No CRL data found");
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   514
        }
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   515
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   516
        try {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   517
            PKCS7 pkcs7 = new PKCS7(data);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   518
            X509CRL[] crls = pkcs7.getCRLs();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   519
            // CRLs are optional in PKCS #7
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   520
            if (crls != null) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   521
                return Arrays.asList(crls);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   522
            } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   523
                // no crls provided
7973
dffe8439eb20 7005608: diamond conversion of JCA and crypto providers
smarks
parents: 5627
diff changeset
   524
                return new ArrayList<>(0);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   526
        } catch (ParsingException e) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   527
            while (data != null) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   528
                coll.add(new X509CRLImpl(data));
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   529
                data = readOneBlock(pbis);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        return coll;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   535
    /**
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   536
     * Returns an ASN.1 SEQUENCE from a stream, which might be a BER-encoded
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   537
     * binary block or a PEM-style BASE64-encoded ASCII data. In the latter
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   538
     * case, it's de-BASE64'ed before return.
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   539
     *
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   540
     * After the reading, the input stream pointer is after the BER block, or
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   541
     * after the newline character after the -----END SOMETHING----- line.
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   542
     *
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   543
     * @param is the InputStream
30374
2abaf49910ea 8079478: some docs cleanup for sun.security
avstepan
parents: 29596
diff changeset
   544
     * @return byte block or null if end of stream
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   545
     * @throws IOException If any parsing error
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     */
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   547
    private static byte[] readOneBlock(InputStream is) throws IOException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   549
        // The first character of a BLOCK.
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   550
        int c = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   551
        if (c == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   552
            return null;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   553
        }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   554
        if (c == DerValue.tag_Sequence) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   555
            ByteArrayOutputStream bout = new ByteArrayOutputStream(2048);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   556
            bout.write(c);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   557
            readBERInternal(is, bout, c);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   558
            return bout.toByteArray();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   559
        } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   560
            // Read BASE64 encoded data, might skip info at the beginning
45063
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   561
            ByteArrayOutputStream data = new ByteArrayOutputStream();
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   562
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   563
            // Step 1: Read until header is found
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   564
            int hyphen = (c=='-') ? 1: 0;   // count of consequent hyphens
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   565
            int last = (c=='-') ? -1: c;    // the char before hyphen
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   566
            while (true) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   567
                int next = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   568
                if (next == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   569
                    // We accept useless data after the last block,
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   570
                    // say, empty lines.
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   571
                    return null;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   572
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   573
                if (next == '-') {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   574
                    hyphen++;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   575
                } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   576
                    hyphen = 0;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   577
                    last = next;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   578
                }
16020
b57c48f16179 8006182: cleanup to use java.util.Base64 in java security component, providers, and regression tests
msheppar
parents: 10786
diff changeset
   579
                if (hyphen == 5 && (last == -1 || last == '\r' || last == '\n')) {
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   580
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   581
                }
2063
8ad79de28190 6535697: keytool can be more flexible on format of PEM-encoded X.509 certificates
weijun
parents: 2
diff changeset
   582
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   584
            // Step 2: Read the rest of header, determine the line end
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   585
            int end;
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 23010
diff changeset
   586
            StringBuilder header = new StringBuilder("-----");
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   587
            while (true) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   588
                int next = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   589
                if (next == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   590
                    throw new IOException("Incomplete data");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   591
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   592
                if (next == '\n') {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   593
                    end = '\n';
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   594
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   595
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   596
                if (next == '\r') {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   597
                    next = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   598
                    if (next == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   599
                        throw new IOException("Incomplete data");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   600
                    }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   601
                    if (next == '\n') {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   602
                        end = '\n';
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   603
                    } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   604
                        end = '\r';
45063
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   605
                        // Skip all white space chars
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   606
                        if (next != 9 && next != 10 && next != 13 && next != 32) {
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   607
                            data.write(next);
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   608
                        }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   609
                    }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   610
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   611
                }
5616
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   612
                header.append((char)next);
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   613
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   615
            // Step 3: Read the data
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   616
            while (true) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   617
                int next = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   618
                if (next == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   619
                    throw new IOException("Incomplete data");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   620
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   621
                if (next != '-') {
45063
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   622
                    // Skip all white space chars
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   623
                    if (next != 9 && next != 10 && next != 13 && next != 32) {
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   624
                        data.write(next);
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   625
                    }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   626
                } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   627
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   628
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   629
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   631
            // Step 4: Consume the footer
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 23010
diff changeset
   632
            StringBuilder footer = new StringBuilder("-");
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   633
            while (true) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   634
                int next = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   635
                // Add next == '\n' for maximum safety, in case endline
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   636
                // is not consistent.
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   637
                if (next == -1 || next == end || next == '\n') {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   638
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   639
                }
5616
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   640
                if (next != '\r') footer.append((char)next);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   642
51272
9d92ff04a29c 8208602: Cannot read PEM X.509 cert if there is whitespace after the header or footer
weijun
parents: 47216
diff changeset
   643
            checkHeaderFooter(header.toString().stripTrailing(),
9d92ff04a29c 8208602: Cannot read PEM X.509 cert if there is whitespace after the header or footer
weijun
parents: 47216
diff changeset
   644
                    footer.toString().stripTrailing());
5616
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   645
45063
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   646
            try {
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   647
                return Base64.getDecoder().decode(data.toByteArray());
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   648
            } catch (IllegalArgumentException e) {
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   649
                throw new IOException(e);
0909d3bcbacb 8179389: X509Certificate generateCRLs is extremely slow using a PEM crl list
weijun
parents: 30374
diff changeset
   650
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
5616
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   654
    private static void checkHeaderFooter(String header,
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   655
            String footer) throws IOException {
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   656
        if (header.length() < 16 || !header.startsWith("-----BEGIN ") ||
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   657
                !header.endsWith("-----")) {
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   658
            throw new IOException("Illegal header: " + header);
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   659
        }
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   660
        if (footer.length() < 14 || !footer.startsWith("-----END ") ||
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   661
                !footer.endsWith("-----")) {
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   662
            throw new IOException("Illegal footer: " + footer);
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   663
        }
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   664
        String headerType = header.substring(11, header.length()-5);
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   665
        String footerType = footer.substring(9, footer.length()-5);
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   666
        if (!headerType.equals(footerType)) {
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   667
            throw new IOException("Header and footer do not match: " +
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   668
                    header + " " + footer);
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   669
        }
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   670
    }
6f3f39ddc2c2 6948781: CertificateFactory.generateCertificate doesn't throw CertificateException for malformed certificate
weijun
parents: 5164
diff changeset
   671
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   672
    /**
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   673
     * Read one BER data block. This method is aware of indefinite-length BER
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   674
     * encoding and will read all of the sub-sections in a recursive way
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
     *
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   676
     * @param is    Read from this InputStream
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   677
     * @param bout  Write into this OutputStream
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   678
     * @param tag   Tag already read (-1 mean not read)
30374
2abaf49910ea 8079478: some docs cleanup for sun.security
avstepan
parents: 29596
diff changeset
   679
     * @return     The current tag, used to check EOC in indefinite-length BER
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   680
     * @throws IOException Any parsing error
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     */
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   682
    private static int readBERInternal(InputStream is,
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   683
            ByteArrayOutputStream bout, int tag) throws IOException {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   684
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   685
        if (tag == -1) {        // Not read before the call, read now
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   686
            tag = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   687
            if (tag == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   688
                throw new IOException("BER/DER tag info absent");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   689
            }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   690
            if ((tag & 0x1f) == 0x1f) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   691
                throw new IOException("Multi octets tag not supported");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   692
            }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   693
            bout.write(tag);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   694
        }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   695
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   696
        int n = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   697
        if (n == -1) {
27091
c068bd1064e0 8032573: CertificateFactory.getInstance("X.509").generateCertificates(InputStream) does not throw CertificateException for invalid input
ascarpino
parents: 25859
diff changeset
   698
            throw new IOException("BER/DER length info absent");
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   699
        }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   700
        bout.write(n);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   701
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   702
        int length;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   703
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   704
        if (n == 0x80) {        // Indefinite-length encoding
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   705
            if ((tag & 0x20) != 0x20) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   706
                throw new IOException(
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   707
                        "Non constructed encoding must have definite length");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   708
            }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   709
            while (true) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   710
                int subTag = readBERInternal(is, bout, -1);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   711
                if (subTag == 0) {   // EOC, end of indefinite-length section
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   712
                    break;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   713
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   715
        } else {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   716
            if (n < 0x80) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   717
                length = n;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   718
            } else if (n == 0x81) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   719
                length = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   720
                if (length == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   721
                    throw new IOException("Incomplete BER/DER length info");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   722
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   723
                bout.write(length);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   724
            } else if (n == 0x82) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   725
                int highByte = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   726
                int lowByte = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   727
                if (lowByte == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   728
                    throw new IOException("Incomplete BER/DER length info");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   729
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   730
                bout.write(highByte);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   731
                bout.write(lowByte);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   732
                length = (highByte << 8) | lowByte;
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   733
            } else if (n == 0x83) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   734
                int highByte = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   735
                int midByte = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   736
                int lowByte = is.read();
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   737
                if (lowByte == -1) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   738
                    throw new IOException("Incomplete BER/DER length info");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   739
                }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   740
                bout.write(highByte);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   741
                bout.write(midByte);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   742
                bout.write(lowByte);
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   743
                length = (highByte << 16) | (midByte << 8) | lowByte;
10784
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   744
            } else if (n == 0x84) {
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   745
                int highByte = is.read();
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   746
                int nextByte = is.read();
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   747
                int midByte = is.read();
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   748
                int lowByte = is.read();
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   749
                if (lowByte == -1) {
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   750
                    throw new IOException("Incomplete BER/DER length info");
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   751
                }
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   752
                if (highByte > 127) {
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   753
                    throw new IOException("Invalid BER/DER data (a little huge?)");
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   754
                }
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   755
                bout.write(highByte);
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   756
                bout.write(nextByte);
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   757
                bout.write(midByte);
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   758
                bout.write(lowByte);
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   759
                length = (highByte << 24 ) | (nextByte << 16) |
f800232d1474 7099399: cannot deal with CRL file larger than 16MB
weijun
parents: 9035
diff changeset
   760
                        (midByte << 8) | lowByte;
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   761
            } else { // ignore longer length forms
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   762
                throw new IOException("Invalid BER/DER data (too huge?)");
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   763
            }
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   764
            if (readFully(is, bout, length) != length) {
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   765
                throw new IOException("Incomplete BER/DER data");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        }
5164
337ae296b6d6 6813340: X509Factory should not depend on is.available()==0
weijun
parents: 2063
diff changeset
   768
        return tag;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    }
52621
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   770
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   771
    private void commitEvent(X509CertImpl info) {
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   772
        X509CertificateEvent xce = new X509CertificateEvent();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   773
        if (xce.shouldCommit() || EventHelper.isLoggingSecurity()) {
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   774
            PublicKey pKey = info.getPublicKey();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   775
            String algId = info.getSigAlgName();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   776
            String serNum = info.getSerialNumber().toString(16);
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   777
            String subject = info.getSubjectDN().getName();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   778
            String issuer = info.getIssuerDN().getName();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   779
            String keyType = pKey.getAlgorithm();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   780
            int length = KeyUtil.getKeySize(pKey);
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   781
            int hashCode = info.hashCode();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   782
            long beginDate = info.getNotBefore().getTime();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   783
            long endDate = info.getNotAfter().getTime();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   784
            if (xce.shouldCommit()) {
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   785
                xce.algorithm = algId;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   786
                xce.serialNumber = serNum;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   787
                xce.subject = subject;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   788
                xce.issuer = issuer;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   789
                xce.keyType = keyType;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   790
                xce.keyLength = length;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   791
                xce.certificateId = hashCode;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   792
                xce.validFrom = beginDate;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   793
                xce.validUntil = endDate;
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   794
                xce.commit();
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   795
            }
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   796
            if (EventHelper.isLoggingSecurity()) {
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   797
                EventHelper.logX509CertificateEvent(algId,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   798
                        serNum,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   799
                        subject,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   800
                        issuer,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   801
                        keyType,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   802
                        length,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   803
                        hashCode,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   804
                        beginDate,
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   805
                        endDate);
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   806
            }
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   807
        }
f7309a1491d9 8148188: Enhance the security libraries to record events of interest
coffeys
parents: 51272
diff changeset
   808
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
}