changeset 13980:63cecc0bd71d jdk8u262-b04

8028591: NegativeArraySizeException in sun.security.util.DerInputStream.getUnalignedBitString() Reviewed-by: mbalao
author andrew
date Mon, 25 May 2020 06:27:07 +0100
parents eb13744577fb
children c0dd958bb895
files src/share/classes/sun/security/util/DerInputStream.java src/share/classes/sun/security/util/DerValue.java src/share/classes/sun/security/util/ObjectIdentifier.java test/java/security/cert/X509Certificate/X509BadCertificate.java test/java/security/cert/X509Certificate/bad-cert-2.pem
diffstat 5 files changed, 63 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/util/DerInputStream.java	Mon Mar 23 10:13:32 2015 -0400
+++ b/src/share/classes/sun/security/util/DerInputStream.java	Mon May 25 06:27:07 2020 +0100
@@ -191,7 +191,7 @@
         if (buffer.read() != DerValue.tag_Integer) {
             throw new IOException("DER input, Integer tag error");
         }
-        return buffer.getInteger(getLength(buffer));
+        return buffer.getInteger(getDefiniteLength(buffer));
     }
 
     /**
@@ -203,7 +203,7 @@
         if (buffer.read() != DerValue.tag_Integer) {
             throw new IOException("DER input, Integer tag error");
         }
-        return buffer.getBigInteger(getLength(buffer), false);
+        return buffer.getBigInteger(getDefiniteLength(buffer), false);
     }
 
     /**
@@ -217,7 +217,7 @@
         if (buffer.read() != DerValue.tag_Integer) {
             throw new IOException("DER input, Integer tag error");
         }
-        return buffer.getBigInteger(getLength(buffer), true);
+        return buffer.getBigInteger(getDefiniteLength(buffer), true);
     }
 
     /**
@@ -229,7 +229,7 @@
         if (buffer.read() != DerValue.tag_Enumerated) {
             throw new IOException("DER input, Enumerated tag error");
         }
-        return buffer.getInteger(getLength(buffer));
+        return buffer.getInteger(getDefiniteLength(buffer));
     }
 
     /**
@@ -240,7 +240,7 @@
         if (buffer.read() != DerValue.tag_BitString)
             throw new IOException("DER input not an bit string");
 
-        return buffer.getBitString(getLength(buffer));
+        return buffer.getBitString(getDefiniteLength(buffer));
     }
 
     /**
@@ -248,15 +248,21 @@
      * not be byte-aligned.
      */
     public BitArray getUnalignedBitString() throws IOException {
-        if (buffer.read() != DerValue.tag_BitString)
+        if (buffer.read() != DerValue.tag_BitString) {
             throw new IOException("DER input not a bit string");
+        }
 
-        int length = getLength(buffer) - 1;
+        int length = getDefiniteLength(buffer);
+
+        if (length == 0) {
+            return new BitArray(0);
+        }
 
         /*
          * First byte = number of excess bits in the last octet of the
          * representation.
          */
+        length--;
         int excessBits = buffer.read();
         if (excessBits < 0) {
             throw new IOException("Unused bits of bit string invalid");
@@ -282,7 +288,7 @@
         if (buffer.read() != DerValue.tag_OctetString)
             throw new IOException("DER input not an octet string");
 
-        int length = getLength(buffer);
+        int length = getDefiniteLength(buffer);
         byte[] retval = new byte[length];
         if ((length != 0) && (buffer.read(retval) != length))
             throw new IOException("Short read of DER octet string");
@@ -397,7 +403,7 @@
            if (tag != buffer.read())
                 throw new IOException("Indefinite length encoding" +
                         " not supported");
-           len = DerInputStream.getLength(buffer);
+           len = DerInputStream.getDefiniteLength(buffer);
         }
 
         if (len == 0)
@@ -514,7 +520,7 @@
             throw new IOException("DER input not a " +
                                   stringName + " string");
 
-        int length = getLength(buffer);
+        int length = getDefiniteLength(buffer);
         byte[] retval = new byte[length];
         if ((length != 0) && (buffer.read(retval) != length))
             throw new IOException("Short read of DER " +
@@ -529,7 +535,7 @@
     public Date getUTCTime() throws IOException {
         if (buffer.read() != DerValue.tag_UtcTime)
             throw new IOException("DER input, UTCtime tag invalid ");
-        return buffer.getUTCTime(getLength(buffer));
+        return buffer.getUTCTime(getDefiniteLength(buffer));
     }
 
     /**
@@ -538,7 +544,7 @@
     public Date getGeneralizedTime() throws IOException {
         if (buffer.read() != DerValue.tag_GeneralizedTime)
             throw new IOException("DER input, GeneralizedTime tag invalid ");
-        return buffer.getGeneralizedTime(getLength(buffer));
+        return buffer.getGeneralizedTime(getDefiniteLength(buffer));
     }
 
     /*
@@ -618,6 +624,24 @@
         return value;
     }
 
+    int getDefiniteLength() throws IOException {
+        return getDefiniteLength(buffer);
+    }
+
+    /*
+     * Get a length from the input stream.
+     *
+     * @return the length
+     * @exception IOException on parsing error or if indefinite length found.
+     */
+    static int getDefiniteLength(InputStream in) throws IOException {
+        int len = getLength(in);
+        if (len < 0) {
+            throw new IOException("Indefinite length encoding not supported");
+        }
+        return len;
+    }
+
     /**
      * Mark the current position in the buffer, so that
      * a later call to <code>reset</code> will return here.
--- a/src/share/classes/sun/security/util/DerValue.java	Mon Mar 23 10:13:32 2015 -0400
+++ b/src/share/classes/sun/security/util/DerValue.java	Mon May 25 06:27:07 2020 +0100
@@ -271,7 +271,7 @@
             if (tag != inbuf.read())
                 throw new IOException
                         ("Indefinite length encoding not supported");
-            length = DerInputStream.getLength(inbuf);
+            length = DerInputStream.getDefiniteLength(inbuf);
             buffer = inbuf.dup();
             buffer.truncate(length);
             data = new DerInputStream(buffer);
@@ -403,7 +403,7 @@
             if (tag != in.read())
                 throw new IOException
                         ("Indefinite length encoding not supported");
-            length = DerInputStream.getLength(in);
+            length = DerInputStream.getDefiniteLength(in);
         }
 
         if (fullyBuffered && in.available() != length)
--- a/src/share/classes/sun/security/util/ObjectIdentifier.java	Mon Mar 23 10:13:32 2015 -0400
+++ b/src/share/classes/sun/security/util/ObjectIdentifier.java	Mon May 25 06:27:07 2020 +0100
@@ -259,7 +259,7 @@
                 + " (tag = " +  type_id + ")"
                 );
 
-        int len = in.getLength();
+        int len = in.getDefiniteLength();
         if (len > in.available()) {
             throw new IOException("ObjectIdentifier() -- length exceeds" +
                     "data available.  Length: " + len + ", Available: " +
--- a/test/java/security/cert/X509Certificate/X509BadCertificate.java	Mon Mar 23 10:13:32 2015 -0400
+++ b/test/java/security/cert/X509Certificate/X509BadCertificate.java	Mon May 25 06:27:07 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8028431
+ * @bug 8028431 8028591
  * @summary Make sure that proper CertificateException is thrown
  *          when loading bad x509 certificate
  * @author Artem Smotrakov
@@ -39,6 +39,7 @@
 
     public static void main(String[] args) throws Exception {
         test("bad-cert-1.pem");
+        test("bad-cert-2.pem");
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/cert/X509Certificate/bad-cert-2.pem	Mon May 25 06:27:07 2020 +0100
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIJAJYB3qu9C2kiMA0GCSqGSIb3DQEBBQUAMEoxDTALBgNV
+BAMMBFRlc3QxDTALBgNVBAsMBEphdmExDzANBgNVBAoMBk9yYWNsZTEMMAoGA1UE
+BwwDU1BCMQswCQYDVQQGEwJSVTAeFw0xMzEyMjMwNzA4MDhaFw0yMzEyMjEwNzA4
+MDhaMEoxDTALBgNVBAMMBFRlc3QxDTALBgNVBAsMBEphdmExDzANBgNVBAoMBk9y
+YWNsZTEMMAoGA1UEBwwDU1BCMQswCQYDVQQGEwJSVTCCASIwDQYJKoZIhvcNAQEB
+BQADgGEPADCCAQoCggEBAOqiCN4gFxehl547Q7/VNGbGApr+wszLdanHPucAH6Wf
+LtcRhKNUSqtBAQxEpFrTpMNEqm2GElAjiPa6m48qIjLVSvOb/9w3G/yXB8zyZbIm
+/Nfp2sT4OEaa1JSEZSpolhS4FfqYzjGQp5cn4Xn4zKjDgiceHgfLls5x2dRydQZO
+Yf91qSIioZxVHUtlo8yztkieiSaqPWt3nJ4PIwhFbsu1HVmWaYZD+nBYCKgVHqrS
+cueO98Ca4Doz73O27X1dVbQBdLS0JI7qVAG8LD388iPL8qbsOkgWPzmEQ+kLRKO4
+g7RpuwlXuwaMSh95NWaxlu4Ob6GRJQmpconYoe13+7ECAwEAAaNQME4wHQYDVR0O
+BBYEFIG8TPobXcbNbDi+zKudd9whpxoNMB8GA1UdIwQYMBaAFIG8TPobXcbNbDi+
+zKudd9whpxoNMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAynN+e7
+h+ufT5SBKN/gBuJAnF1mKIPESiipuv5KoYUGZOY8ShgYLcwY+qnbuHYFUlvq6Zns
+K4/e+x/16h32vD7dEPkNvukbvER4YJQQiN6osDfXpTPzixYftWdmtX0u8xQfwb/g
+R8DS7bazz99jVXk+jTK4yWBY+gMwEat+LyNQ5cyq8Qhi1oBKUbGRbiOts19B97fn
+Rv8TsyXN3INLGYhdVxZoD7E5tyG1ydSFmOMadulAC2epBXDHOXZnz2UWauJc0XW5
+1L/YQVri47VkdHS3tisBzELEJdLmdMDb+5tAU+lItXmTXe2/PB53WIvsEIb4t+eQ
+wY0hCj9lVJlajTQ=
+-----END CERTIFICATE-----